mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-07-14 02:01:56 +00:00
fix challenge list
This commit is contained in:
parent
68e3ca7b65
commit
cd3bfbcd67
28 changed files with 444 additions and 730 deletions
|
|
@ -18,41 +18,9 @@
|
||||||
android:layout_marginLeft="@dimen/dialog_marginLeftRight"
|
android:layout_marginLeft="@dimen/dialog_marginLeftRight"
|
||||||
android:layout_marginRight="@dimen/dialog_marginLeftRight"
|
android:layout_marginRight="@dimen/dialog_marginLeftRight"
|
||||||
android:layout_marginStart="@dimen/dialog_marginLeftRight"
|
android:layout_marginStart="@dimen/dialog_marginLeftRight"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="65dp"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/Title1_WideLetterSpacing"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_weight="2"
|
|
||||||
android:text="@string/filters"
|
|
||||||
android:textColor="#000" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="right">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/challenge_filter_button_done"
|
|
||||||
style="@style/Body1_Button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="right"
|
|
||||||
android:text="@string/done"
|
|
||||||
android:textColor="#6133b4"
|
|
||||||
android:textSize="16sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
|
|
@ -60,16 +28,14 @@
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/Caption3"
|
style="@style/Caption3"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="14dp"
|
|
||||||
android:layout_weight="2"
|
android:layout_weight="2"
|
||||||
android:height="20dp"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:text="@string/groups"
|
android:text="@string/groups"
|
||||||
android:textAllCaps="true" />
|
android:textAllCaps="true" />
|
||||||
|
|
||||||
|
|
@ -78,22 +44,23 @@
|
||||||
style="@style/Body1_Button"
|
style="@style/Body1_Button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="right"
|
android:gravity="right|center_vertical"
|
||||||
android:text="@string/all"
|
android:text="@string/all"
|
||||||
android:textColor="#6133b4"
|
android:textColor="#6133b4"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp"
|
||||||
|
android:padding="0dp" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/challenge_filter_button_none"
|
android:id="@+id/challenge_filter_button_none"
|
||||||
style="@style/Body1_Button"
|
style="@style/Body1_Button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="right"
|
android:gravity="right|center_vertical"
|
||||||
android:text="@string/none"
|
android:text="@string/none"
|
||||||
android:textColor="#6133b4"
|
android:textColor="#6133b4"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp"
|
||||||
|
android:padding="0dp"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/challenge_filter_recycler_view"
|
android:id="@+id/challenge_filter_recycler_view"
|
||||||
|
|
@ -101,63 +68,32 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
tools:listitem="@layout/dialog_challenge_filter_group_item"
|
tools:listitem="@layout/dialog_challenge_filter_group_item"
|
||||||
tools:visibility="gone" />
|
tools:visibility="gone" />
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/Caption3"
|
style="@style/Caption3"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="14dp"
|
android:layout_marginTop="14dp"
|
||||||
android:layout_weight="2"
|
|
||||||
android:height="20dp"
|
android:height="20dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:text="Ownerchip"
|
android:text="@string/ownership"
|
||||||
android:textAllCaps="true" />
|
android:textAllCaps="true" />
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
|
style="@style/Subheader2"
|
||||||
android:id="@+id/challenge_filter_owned"
|
android:id="@+id/challenge_filter_owned"
|
||||||
android:layout_width="50dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:checked="true"
|
android:checked="true"
|
||||||
android:text="" />
|
android:text="@string/owned"
|
||||||
|
android:textColor="@color/textColorLight"/>
|
||||||
<TextView
|
|
||||||
style="@style/Subheader2"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/owned" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
|
style="@style/Subheader2"
|
||||||
android:id="@+id/challenge_filter_not_owned"
|
android:id="@+id/challenge_filter_not_owned"
|
||||||
android:layout_width="50dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:checked="true"
|
android:checked="true"
|
||||||
android:text="" />
|
android:text="@string/not_owned"
|
||||||
|
android:textColor="@color/textColorLight"/>
|
||||||
<TextView
|
|
||||||
style="@style/Subheader2"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/not_owned" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</com.habitrpg.android.habitica.ui.MaxHeightLinearLayout>
|
</com.habitrpg.android.habitica.ui.MaxHeightLinearLayout>
|
||||||
|
|
@ -1,82 +1,29 @@
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
|
||||||
|
android:id="@+id/refresh_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#fff"
|
android:background="#fff"
|
||||||
android:orientation="vertical">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
<FrameLayout
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/challenge_filter_layout"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent">
|
||||||
android:background="#f9f9f9"
|
<com.habitrpg.android.habitica.ui.helpers.RecyclerViewEmptySupport
|
||||||
android:orientation="horizontal"
|
android:id="@+id/recyclerView"
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/action_filter_icon"
|
|
||||||
android:layout_width="18dp"
|
|
||||||
android:layout_height="18dp"
|
|
||||||
android:layout_marginRight="13dp"
|
|
||||||
android:src="@drawable/ic_action_filter_list"
|
|
||||||
android:tint="#80000000"
|
|
||||||
android:contentDescription="filter icon" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/Caption2"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/filter"
|
|
||||||
android:textAllCaps="true" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="18dp"
|
|
||||||
android:layout_height="18dp"
|
|
||||||
android:src="@drawable/ic_arrow_drop_down_80000000_24dp"
|
|
||||||
android:contentDescription="filter icon" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<android.support.v4.widget.SwipeRefreshLayout
|
|
||||||
android:id="@+id/challenges.refresh.layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
|
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
|
||||||
android:id="@+id/challenges.list"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:divider="@null"
|
android:divider="@null"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
android:paddingBottom="?attr/actionBarSize" />
|
android:paddingBottom="?attr/actionBarSize" />
|
||||||
|
|
||||||
</android.support.v4.widget.SwipeRefreshLayout>
|
|
||||||
|
|
||||||
<android.support.v4.widget.SwipeRefreshLayout
|
|
||||||
android:id="@+id/challenges_refresh_empty"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
|
|
||||||
<android.support.v4.widget.NestedScrollView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:clipToPadding="false">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/challenges.list.empty"
|
android:id="@+id/empty_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="48dp"
|
android:layout_marginLeft="48dp"
|
||||||
android:layout_marginRight="48dp"
|
android:layout_marginRight="48dp"
|
||||||
android:layout_marginTop="65dp"
|
android:layout_marginTop="32dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
@ -100,7 +47,6 @@
|
||||||
android:textColor="#66000000" />
|
android:textColor="#66000000" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textView5"
|
|
||||||
style="@style/Body2"
|
style="@style/Body2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|
@ -111,9 +57,5 @@
|
||||||
android:textColor="#66000000" />
|
android:textColor="#66000000" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
</android.support.v4.widget.NestedScrollView>
|
</android.support.v4.widget.SwipeRefreshLayout>
|
||||||
</android.support.v4.widget.SwipeRefreshLayout>
|
|
||||||
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/refresh.layout"
|
android:id="@+id/refresh_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,16 @@
|
||||||
android:id="@+id/action_create_challenge"
|
android:id="@+id/action_create_challenge"
|
||||||
android:title="@string/create_challenge"/>
|
android:title="@string/create_challenge"/>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_reload"
|
||||||
|
android:icon="@drawable/ic_refresh_white"
|
||||||
|
android:title="@string/action_refresh"
|
||||||
|
app:showAsAction="never"
|
||||||
|
android:actionViewClass="android.widget.ImageButton"/>
|
||||||
|
|
||||||
|
<item android:id="@+id/action_search"
|
||||||
|
android:icon="@drawable/ic_action_filter_list"
|
||||||
|
app:actionLayout="@layout/filter_menu_item"
|
||||||
|
android:title="@string/filter"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
||||||
|
|
@ -488,101 +488,102 @@
|
||||||
<string name="subscribe_prompt_thanks">For Subscribing you are receiving these useful benefits:</string>
|
<string name="subscribe_prompt_thanks">For Subscribing you are receiving these useful benefits:</string>
|
||||||
<string name="subscription_status">Subscription Status</string>
|
<string name="subscription_status">Subscription Status</string>
|
||||||
|
|
||||||
<string name="byLeader" >by %s</string>
|
<string name="byLeader" >by %s</string>
|
||||||
<string name="challenge_details">Challenge Details</string>
|
<string name="challenge_details">Challenge Details</string>
|
||||||
<string name="challenge_leave_title">Leave Challenge</string>
|
<string name="challenge_leave_title">Leave Challenge</string>
|
||||||
<string name="challenge_leave_text">Are you sure you want to leave the Challenge “%s”?</string>
|
<string name="challenge_leave_text">Are you sure you want to leave the Challenge “%s”?</string>
|
||||||
<string name="challenge_remove_tasks_title">Remove tasks</string>
|
<string name="challenge_remove_tasks_title">Remove tasks</string>
|
||||||
<string name="challenge_remove_tasks_text">Do you want to remove the tasks?</string>
|
<string name="challenge_remove_tasks_text">Do you want to remove the tasks?</string>
|
||||||
<string name="remove_tasks">Remove</string>
|
<string name="remove_tasks">Remove</string>
|
||||||
<string name="keep_tasks">Keep</string>
|
<string name="keep_tasks">Keep</string>
|
||||||
<string name="my_challenges">My Challenges</string>
|
<string name="my_challenges">My Challenges</string>
|
||||||
<string name="public_challenges">Public</string>
|
<string name="public_challenges">Public</string>
|
||||||
<string name="challenges">Challenges</string>
|
<string name="challenges">Challenges</string>
|
||||||
<string name="daily">Daily</string>
|
<string name="daily">Daily</string>
|
||||||
<string name="habit">Habit</string>
|
<string name="habit">Habit</string>
|
||||||
<string name="reward">Reward</string>
|
<string name="reward">Reward</string>
|
||||||
<string name="todo">To-Do</string>
|
<string name="todo">To-Do</string>
|
||||||
<string name="official">Official</string>
|
<string name="official">Official</string>
|
||||||
<string name="participating">Participating</string>
|
<string name="participating">Participating</string>
|
||||||
<string name="challenge">Challenge</string>
|
<string name="challenge">Challenge</string>
|
||||||
<string name="go_to_challenge">Go to Challenge</string>
|
<string name="go_to_challenge">Go to Challenge</string>
|
||||||
<string name="not_part_of_a_challenge">You’re not part of any Challenges right now!</string>
|
<string name="not_part_of_a_challenge">You’re not part of any Challenges right now!</string>
|
||||||
<string name="join_a_challenge">Join a Challenge to add a curated set of tasks to your list, then compete against other Habiticans to win achievements and even gems!</string>
|
<string name="join_a_challenge">Join a Challenge to add a curated set of tasks to your list, then compete against other Habiticans to win achievements and even gems!</string>
|
||||||
<string name="check_the_public_challenge_tab">Tap the “Public” tab to find the user-created Challenges that are the best fit for you!</string>
|
<string name="check_the_public_challenge_tab">Tap the “Public” tab to find the user-created Challenges that are the best fit for you!</string>
|
||||||
<string name="add_reminder">Add Reminder</string>
|
<string name="add_reminder">Add Reminder</string>
|
||||||
<string name="warning">Warning</string>
|
<string name="warning">Warning</string>
|
||||||
<string name="open_settings">Open Settings</string>
|
<string name="open_settings">Open Settings</string>
|
||||||
<string name="dont_keep_activities_warning">It seems like you have the Developer option \“Don\'t keep Activities\” active. Currently this option causes issues with the habitica app, so we suggest disabling it.</string>
|
<string name="dont_keep_activities_warning">It seems like you have the Developer option \“Don\'t keep Activities\” active. Currently this option causes issues with the habitica app, so we suggest disabling it.</string>
|
||||||
<string name="inbox">Inbox</string>
|
<string name="inbox">Inbox</string>
|
||||||
<string name="FAQ">Frequently Asked Questions</string>
|
<string name="FAQ">Frequently Asked Questions</string>
|
||||||
<string name="special">Special</string>
|
<string name="special">Special</string>
|
||||||
<string name="gem_for_gold_description">Because you subscribe to Habitica, you can purchase a number of Gems each month using Gold.</string>
|
<string name="gem_for_gold_description">Because you subscribe to Habitica, you can purchase a number of Gems each month using Gold.</string>
|
||||||
<string name="limited_count" >%d left</string>
|
<string name="limited_count" >%d left</string>
|
||||||
<string name="gem_shop">Gem</string>
|
<string name="gem_shop">Gem</string>
|
||||||
<string name="mystery_item">Mystery Item</string>
|
<string name="mystery_item">Mystery Item</string>
|
||||||
<string name="myster_item_notes">Each month, subscribers will receive a mystery item. This is usually released about one week before the end of the month.</string>
|
<string name="myster_item_notes">Each month, subscribers will receive a mystery item. This is usually released about one week before the end of the month.</string>
|
||||||
<string name="open">Open</string>
|
<string name="open">Open</string>
|
||||||
<string name="notification_mystery_item">You open the box and find %s!</string>
|
<string name="notification_mystery_item">You open the box and find %s!</string>
|
||||||
<string name="checkInRewardEarned">You earned a %1$s as a reward for your devotion to improving your life.</string>
|
<string name="checkInRewardEarned">You earned a %1$s as a reward for your devotion to improving your life.</string>
|
||||||
<string name="nextPrizeUnlocks" tools:ignore="PluralsCandidate">Your next prize unlocks at %1$d Check-Ins</string>
|
<string name="nextPrizeUnlocks" tools:ignore="PluralsCandidate">Your next prize unlocks at %1$d Check-Ins</string>
|
||||||
<string name="pending_approval">pending approval</string>
|
<string name="pending_approval">pending approval</string>
|
||||||
<string name="filters">Filters</string>
|
<string name="filters">Filters</string>
|
||||||
<string name="done">Done</string>
|
<string name="done">Done</string>
|
||||||
<string name="group_tasks_edit_description">Group tasks can not be edited.</string>
|
<string name="group_tasks_edit_description">Group tasks can not be edited.</string>
|
||||||
<string name="group_tasks_edit_title">Can\'t edit this task</string>
|
<string name="group_tasks_edit_title">Can\'t edit this task</string>
|
||||||
<string name="groups">Groups</string>
|
<string name="groups">Groups</string>
|
||||||
<string name="all">All</string>
|
<string name="all">All</string>
|
||||||
<string name="none">None</string>
|
<string name="none">None</string>
|
||||||
<string name="owned">Owned</string>
|
<string name="owned">Owned</string>
|
||||||
<string name="not_owned">Not owned</string>
|
<string name="not_owned">Not owned</string>
|
||||||
<string name="new_game">New\nGame</string>
|
<string name="new_game">New\nGame</string>
|
||||||
<string name="login_btn_fb">Login with Facebook</string>
|
<string name="login_btn_fb">Login with Facebook</string>
|
||||||
<string name="login_btn_google">Login with Google</string>
|
<string name="login_btn_google">Login with Google</string>
|
||||||
<string name="action_back">Back</string>
|
<string name="action_back">Back</string>
|
||||||
<string name="welcome_text">Oh, you must be new here. I’m Justin, I’ll be your guide in Habitica.\n\nTo start, you’ll need to create an avatar.</string>
|
<string name="welcome_text">Oh, you must be new here. I’m Justin, I’ll be your guide in Habitica.\n\nTo start, you’ll need to create an avatar.</string>
|
||||||
<string name="randomize">Randomize</string>
|
<string name="randomize">Randomize</string>
|
||||||
<string name="avatar_extras">Extras</string>
|
<string name="avatar_extras">Extras</string>
|
||||||
<string name="avatar_skin_color">Skin Color</string>
|
<string name="avatar_skin_color">Skin Color</string>
|
||||||
<string name="avatar_hair_color">Hair Color</string>
|
<string name="avatar_hair_color">Hair Color</string>
|
||||||
<string name="avatar_hair_bangs">Bangs</string>
|
<string name="avatar_hair_bangs">Bangs</string>
|
||||||
<string name="avatar_hair_ponytail">Ponytail</string>
|
<string name="avatar_hair_ponytail">Ponytail</string>
|
||||||
<string name="avatar_glasses">Glasses</string>
|
<string name="avatar_glasses">Glasses</string>
|
||||||
<string name="avatar_wheelchair">Wheelchair</string>
|
<string name="avatar_wheelchair">Wheelchair</string>
|
||||||
<string name="weak">Weak</string>
|
<string name="weak">Weak</string>
|
||||||
<string name="strong">Strong</string>
|
<string name="strong">Strong</string>
|
||||||
<string name="gray">Grey</string>
|
<string name="gray">Grey</string>
|
||||||
<string name="dated">Dated</string>
|
<string name="dated">Dated</string>
|
||||||
<string name="completed">Completed</string>
|
<string name="completed">Completed</string>
|
||||||
<string name="setuP_group_other">Other</string>
|
<string name="setuP_group_other">Other</string>
|
||||||
<string name="clear">Clear</string>
|
<string name="clear">Clear</string>
|
||||||
<string name="empty_title_habits">You don\'t have any Habits</string>
|
<string name="empty_title_habits">You don\'t have any Habits</string>
|
||||||
<string name="empty_description_habits">Habits are tasks that don\'t have a rigid schedule. You can check them off many times a day, or not at all.</string>
|
<string name="empty_description_habits">Habits are tasks that don\'t have a rigid schedule. You can check them off many times a day, or not at all.</string>
|
||||||
<string name="empty_title_dailies">You don\'t have any Dailies</string>
|
<string name="empty_title_dailies">You don\'t have any Dailies</string>
|
||||||
<string name="empty_description_dailies">Dailies are tasks that repeat on a regular basis. Choose the schedule that works for you!</string>
|
<string name="empty_description_dailies">Dailies are tasks that repeat on a regular basis. Choose the schedule that works for you!</string>
|
||||||
<string name="empty_title_todos">You don\'t have any To-Dos</string>
|
<string name="empty_title_todos">You don\'t have any To-Dos</string>
|
||||||
<string name="empty_description_todos">To-Dos are tasks that only need to be completed once. Add checklists to your To-Dos to increase their value.</string>
|
<string name="empty_description_todos">To-Dos are tasks that only need to be completed once. Add checklists to your To-Dos to increase their value.</string>
|
||||||
<string name="empty_title_rewards">You don\'t have any Rewards</string>
|
<string name="empty_title_rewards">You don\'t have any Rewards</string>
|
||||||
<string name="reset_walkthrough">Reset Justins Walkthrough</string>
|
<string name="reset_walkthrough">Reset Justins Walkthrough</string>
|
||||||
<string name="read_community_guidelines">Please read our Community Guidelines before posting</string>
|
<string name="read_community_guidelines">Please read our Community Guidelines before posting</string>
|
||||||
<string name="maintenance">Maintenance</string>
|
<string name="maintenance">Maintenance</string>
|
||||||
<string name="reload_content">Reload Content</string>
|
<string name="reload_content">Reload Content</string>
|
||||||
<string name="dailyDueDefaultView">Set Dailies default to ‘due’ tab</string>
|
<string name="dailyDueDefaultView">Set Dailies default to ‘due’ tab</string>
|
||||||
<string name="dailyDueDefaultViewDescription">With this option set, the Dailies tasks will default to ‘due’ instead of ‘all’</string>
|
<string name="dailyDueDefaultViewDescription">With this option set, the Dailies tasks will default to ‘due’ instead of ‘all’</string>
|
||||||
<string name="no_billing_gems">Your device does not have any of the supported payment methods. Please use the habitica website if you want to purchase gems.</string>
|
<string name="no_billing_gems">Your device does not have any of the supported payment methods. Please use the habitica website if you want to purchase gems.</string>
|
||||||
<string name="no_billing_subscriptions">Your device does not have any of the supported payment methods. Please use the habitica website if you want to purchase a subscription.</string>
|
<string name="no_billing_subscriptions">Your device does not have any of the supported payment methods. Please use the habitica website if you want to purchase a subscription.</string>
|
||||||
<string name="save">Save</string>
|
<string name="save">Save</string>
|
||||||
<string name="location">Location</string>
|
<string name="location">Location</string>
|
||||||
<string name="gem_reward">Gem reward</string>
|
<string name="gem_reward">Gem reward</string>
|
||||||
<string name="tasks">Tasks</string>
|
<string name="tasks">Tasks</string>
|
||||||
<string name="create_challenge">Create challenge</string>
|
<string name="create_challenge">Create challenge</string>
|
||||||
<string name="edit_challenge">Edit Challenge</string>
|
<string name="edit_challenge">Edit Challenge</string>
|
||||||
<string name="challenge_create_error_tavern_one_gem">You need at least 1 gem to create a challenge in Tavern.</string>
|
<string name="challenge_create_error_tavern_one_gem">You need at least 1 gem to create a challenge in Tavern.</string>
|
||||||
<string name="challenge_create_error_enough_gems">You don\'t have enough gems to create a challenge.</string>
|
<string name="challenge_create_error_enough_gems">You don\'t have enough gems to create a challenge.</string>
|
||||||
<string name="identify_your_challenge_with_a_tag">Identify your challenge with a tag ..</string>
|
<string name="identify_your_challenge_with_a_tag">Identify your challenge with a tag ..</string>
|
||||||
<string name="challenge_create_error_tag">You need a tag to create this Challenge.</string>
|
<string name="challenge_create_error_tag">You need a tag to create this Challenge.</string>
|
||||||
<string name="challenge_create_error_no_tasks">You need to add at least one task to create this Challenge.</string>
|
<string name="challenge_create_error_no_tasks">You need to add at least one task to create this Challenge.</string>
|
||||||
<string name="challenge_create_error_title">You need a title to create this Challenge.</string>
|
<string name="challenge_create_error_title">You need a title to create this Challenge.</string>
|
||||||
<string name="description_optional">Description (optional)</string>
|
<string name="description_optional">Description (optional)</string>
|
||||||
<string name="new_challenge_title">New challenge title</string>
|
<string name="new_challenge_title">New challenge title</string>
|
||||||
|
<string name="ownership">Ownership</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ import com.habitrpg.android.habitica.models.tasks.TaskList;
|
||||||
import com.habitrpg.android.habitica.models.user.Items;
|
import com.habitrpg.android.habitica.models.user.Items;
|
||||||
import com.habitrpg.android.habitica.models.user.User;
|
import com.habitrpg.android.habitica.models.user.User;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
@ -109,7 +108,7 @@ public interface ApiService {
|
||||||
Observable<HabitResponse<TaskDirectionData>> postTaskDirection(@Path("id") String id, @Path("direction") String direction);
|
Observable<HabitResponse<TaskDirectionData>> postTaskDirection(@Path("id") String id, @Path("direction") String direction);
|
||||||
|
|
||||||
@POST("tasks/{id}/move/to/{position}")
|
@POST("tasks/{id}/move/to/{position}")
|
||||||
Observable<HabitResponse<ArrayList<String>>> postTaskNewPosition(@Path("id") String id, @Path("position") String position);
|
Observable<HabitResponse<List<String>>> postTaskNewPosition(@Path("id") String id, @Path("position") String position);
|
||||||
|
|
||||||
@POST("tasks/{taskId}/checklist/{itemId}/score")
|
@POST("tasks/{taskId}/checklist/{itemId}/score")
|
||||||
Observable<HabitResponse<Task>> scoreChecklistItem(@Path("taskId") String taskId, @Path("itemId") String itemId);
|
Observable<HabitResponse<Task>> scoreChecklistItem(@Path("taskId") String taskId, @Path("itemId") String itemId);
|
||||||
|
|
@ -273,7 +272,7 @@ public interface ApiService {
|
||||||
/* challenges api */
|
/* challenges api */
|
||||||
|
|
||||||
@GET("challenges/user")
|
@GET("challenges/user")
|
||||||
Observable<HabitResponse<ArrayList<Challenge>>> getUserChallenges();
|
Observable<HabitResponse<List<Challenge>>> getUserChallenges();
|
||||||
|
|
||||||
@GET("tasks/challenge/{challengeId}")
|
@GET("tasks/challenge/{challengeId}")
|
||||||
Observable<HabitResponse<TaskList>> getChallengeTasks(@Path("challengeId") String challengeId);
|
Observable<HabitResponse<TaskList>> getChallengeTasks(@Path("challengeId") String challengeId);
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ import com.habitrpg.android.habitica.ui.fragments.social.InboxFragment;
|
||||||
import com.habitrpg.android.habitica.ui.fragments.social.InboxMessageListFragment;
|
import com.habitrpg.android.habitica.ui.fragments.social.InboxMessageListFragment;
|
||||||
import com.habitrpg.android.habitica.ui.fragments.social.PublicGuildsFragment;
|
import com.habitrpg.android.habitica.ui.fragments.social.PublicGuildsFragment;
|
||||||
import com.habitrpg.android.habitica.ui.fragments.social.TavernFragment;
|
import com.habitrpg.android.habitica.ui.fragments.social.TavernFragment;
|
||||||
|
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeDetailDialogHolder;
|
||||||
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeListFragment;
|
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeListFragment;
|
||||||
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeTasksRecyclerViewFragment;
|
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeTasksRecyclerViewFragment;
|
||||||
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengesOverviewFragment;
|
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengesOverviewFragment;
|
||||||
|
|
@ -262,4 +263,6 @@ public interface AppComponent {
|
||||||
void inject(NotificationPublisher notificationPublisher);
|
void inject(NotificationPublisher notificationPublisher);
|
||||||
|
|
||||||
void inject(CreateChallengeActivity createChallengeActivity);
|
void inject(CreateChallengeActivity createChallengeActivity);
|
||||||
|
|
||||||
|
void inject(ChallengeDetailDialogHolder challengeDetailDialogHolder);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
package com.habitrpg.android.habitica.data;
|
package com.habitrpg.android.habitica.data;
|
||||||
|
|
||||||
|
import com.habitrpg.android.habitica.models.LeaveChallengeBody;
|
||||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||||
import com.habitrpg.android.habitica.models.social.Group;
|
import com.habitrpg.android.habitica.models.social.Group;
|
||||||
import com.habitrpg.android.habitica.models.tasks.Task;
|
import com.habitrpg.android.habitica.models.tasks.Task;
|
||||||
import com.habitrpg.android.habitica.models.tasks.TaskList;
|
import com.habitrpg.android.habitica.models.tasks.TaskList;
|
||||||
|
import com.habitrpg.android.habitica.models.user.User;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.realm.RealmResults;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
|
||||||
public interface ChallengeRepository extends BaseRepository {
|
public interface ChallengeRepository extends BaseRepository {
|
||||||
|
|
@ -17,18 +20,23 @@ public interface ChallengeRepository extends BaseRepository {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param challenge
|
* @param challenge the challenge that will be updated
|
||||||
* @param fullTaskList lists all tasks of the current challenge, to create the taskOrders
|
* @param fullTaskList lists all tasks of the current challenge, to create the taskOrders
|
||||||
* @param addedTaskList only the tasks to be added online
|
* @param addedTaskList only the tasks to be added online
|
||||||
* @param updatedTaskList only the updated ones
|
* @param updatedTaskList only the updated ones
|
||||||
* @param removedTaskList tasks that has be to be removed
|
* @param removedTaskList tasks that has be to be removed
|
||||||
* @return
|
* @return Observable with the updated challenge
|
||||||
*/
|
*/
|
||||||
Observable<Challenge> updateChallenge(Challenge challenge, List<Task> fullTaskList,
|
Observable<Challenge> updateChallenge(Challenge challenge, List<Task> fullTaskList,
|
||||||
List<Task> addedTaskList, List<Task> updatedTaskList, List<String> removedTaskList);
|
List<Task> addedTaskList, List<Task> updatedTaskList, List<String> removedTaskList);
|
||||||
Observable<Void> deleteChallenge(String challengeId);
|
Observable<Void> deleteChallenge(String challengeId);
|
||||||
|
|
||||||
void setUsersGroups(List<Group> groups);
|
Observable<RealmResults<Challenge>> getChallenges();
|
||||||
|
Observable<RealmResults<Challenge>> getUserChallenges(String userId);
|
||||||
|
|
||||||
Observable<List<Group>> getLocalGroups();
|
Observable<List<Challenge>> retrieveChallenges(User user);
|
||||||
|
|
||||||
|
Observable<Void> leaveChallenge(Challenge challenge, LeaveChallengeBody leaveChallengeBody);
|
||||||
|
|
||||||
|
Observable<Challenge> joinChallenge(Challenge challenge);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ public interface SocialRepository extends BaseRepository {
|
||||||
Observable<Void> updateGroup(Group group);
|
Observable<Void> updateGroup(Group group);
|
||||||
|
|
||||||
Observable<List<Group>> retrieveGroups(String type);
|
Observable<List<Group>> retrieveGroups(String type);
|
||||||
Observable<List<Group>> getGroups(String type);
|
Observable<RealmResults<Group>> getGroups(String type);
|
||||||
|
|
||||||
Observable<PostChatMessageResult> postPrivateMessage(HashMap<String, String> messageObject);
|
Observable<PostChatMessageResult> postPrivateMessage(HashMap<String, String> messageObject);
|
||||||
Observable<PostChatMessageResult> postPrivateMessage(String recipientId, String message);
|
Observable<PostChatMessageResult> postPrivateMessage(String recipientId, String message);
|
||||||
|
|
@ -52,10 +52,5 @@ public interface SocialRepository extends BaseRepository {
|
||||||
|
|
||||||
Observable<User> getMember(String userId);
|
Observable<User> getMember(String userId);
|
||||||
|
|
||||||
Observable<Challenge> getChallenge(String challengeId);
|
|
||||||
|
|
||||||
Observable<RealmResults<Challenge>> getChallenges();
|
|
||||||
Observable<RealmResults<Challenge>> getUserChallenges(String id);
|
|
||||||
|
|
||||||
Observable<Void> markPrivateMessagesRead(User user);
|
Observable<Void> markPrivateMessagesRead(User user);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ import com.habitrpg.android.habitica.models.tasks.Task;
|
||||||
import com.habitrpg.android.habitica.models.tasks.TaskList;
|
import com.habitrpg.android.habitica.models.tasks.TaskList;
|
||||||
import com.habitrpg.android.habitica.utils.BooleanAsIntAdapter;
|
import com.habitrpg.android.habitica.utils.BooleanAsIntAdapter;
|
||||||
import com.habitrpg.android.habitica.utils.ChallengeDeserializer;
|
import com.habitrpg.android.habitica.utils.ChallengeDeserializer;
|
||||||
|
import com.habitrpg.android.habitica.utils.ChallengeListDeserializer;
|
||||||
import com.habitrpg.android.habitica.utils.ChatMessageDeserializer;
|
import com.habitrpg.android.habitica.utils.ChatMessageDeserializer;
|
||||||
import com.habitrpg.android.habitica.utils.ChatMessageListDeserializer;
|
import com.habitrpg.android.habitica.utils.ChatMessageListDeserializer;
|
||||||
import com.habitrpg.android.habitica.utils.ChecklistItemSerializer;
|
import com.habitrpg.android.habitica.utils.ChecklistItemSerializer;
|
||||||
|
|
@ -208,38 +209,23 @@ public class ApiClientImpl implements Action1<Throwable>, ApiClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GsonConverterFactory createGsonFactory() {
|
public static GsonConverterFactory createGsonFactory() {
|
||||||
Type taskTagClassListType = new TypeToken<RealmList<Tag>>() {
|
Type taskTagClassListType = new TypeToken<RealmList<Tag>>() {}.getType();
|
||||||
}.getType();
|
Type skillListType = new TypeToken<List<Skill>>() {}.getType();
|
||||||
Type skillListType = new TypeToken<List<Skill>>() {
|
Type customizationListType = new TypeToken<RealmList<Customization>>() {}.getType();
|
||||||
}.getType();
|
Type tutorialStepListType = new TypeToken<RealmList<TutorialStep>>() {}.getType();
|
||||||
Type customizationListType = new TypeToken<RealmList<Customization>>() {
|
Type faqArticleListType = new TypeToken<RealmList<FAQArticle>>() {}.getType();
|
||||||
}.getType();
|
Type itemDataListType = new TypeToken<RealmList<Equipment>>() {}.getType();
|
||||||
Type tutorialStepListType = new TypeToken<RealmList<TutorialStep>>() {
|
Type eggListType = new TypeToken<RealmList<Egg>>() {}.getType();
|
||||||
}.getType();
|
Type foodListType = new TypeToken<RealmList<Food>>() {}.getType();
|
||||||
Type faqArticleListType = new TypeToken<RealmList<FAQArticle>>() {
|
Type hatchingPotionListType = new TypeToken<RealmList<HatchingPotion>>() {}.getType();
|
||||||
}.getType();
|
Type questContentListType = new TypeToken<RealmList<QuestContent>>() {}.getType();
|
||||||
Type itemDataListType = new TypeToken<RealmList<Equipment>>() {
|
Type petMapType = new TypeToken<Map<String, Pet>>() {}.getType();
|
||||||
}.getType();
|
Type mountMapType = new TypeToken<Map<String, Mount>>() {}.getType();
|
||||||
Type eggListType = new TypeToken<RealmList<Egg>>() {
|
Type petListType = new TypeToken<RealmList<Pet>>() {}.getType();
|
||||||
}.getType();
|
Type mountListType = new TypeToken<RealmList<Mount>>() {}.getType();
|
||||||
Type foodListType = new TypeToken<RealmList<Food>>() {
|
Type questCollectListType = new TypeToken<RealmList<QuestCollect>>() {}.getType();
|
||||||
}.getType();
|
Type chatMessageListType = new TypeToken<RealmList<ChatMessage>>() {}.getType();
|
||||||
Type hatchingPotionListType = new TypeToken<RealmList<HatchingPotion>>() {
|
Type challengeListType = new TypeToken<List<Challenge>>() {}.getType();
|
||||||
}.getType();
|
|
||||||
Type questContentListType = new TypeToken<RealmList<QuestContent>>() {
|
|
||||||
}.getType();
|
|
||||||
Type petMapType = new TypeToken<Map<String, Pet>>() {
|
|
||||||
}.getType();
|
|
||||||
Type mountMapType = new TypeToken<Map<String, Mount>>() {
|
|
||||||
}.getType();
|
|
||||||
Type petListType = new TypeToken<RealmList<Pet>>() {
|
|
||||||
}.getType();
|
|
||||||
Type mountListType = new TypeToken<RealmList<Mount>>() {
|
|
||||||
}.getType();
|
|
||||||
Type questCollectListType = new TypeToken<RealmList<QuestCollect>>() {
|
|
||||||
}.getType();
|
|
||||||
Type chatMessageListType = new TypeToken<RealmList<ChatMessage>>() {
|
|
||||||
}.getType();
|
|
||||||
|
|
||||||
//Exclusion strategy needed for DBFlow https://github.com/Raizlabs/DBFlow/issues/121
|
//Exclusion strategy needed for DBFlow https://github.com/Raizlabs/DBFlow/issues/121
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
|
|
@ -274,6 +260,7 @@ public class ApiClientImpl implements Action1<Throwable>, ApiClient {
|
||||||
.registerTypeAdapter(User.class, new UserDeserializer())
|
.registerTypeAdapter(User.class, new UserDeserializer())
|
||||||
.registerTypeAdapter(questCollectListType, new QuestCollectDeserializer())
|
.registerTypeAdapter(questCollectListType, new QuestCollectDeserializer())
|
||||||
.registerTypeAdapter(chatMessageListType, new ChatMessageListDeserializer())
|
.registerTypeAdapter(chatMessageListType, new ChatMessageListDeserializer())
|
||||||
|
.registerTypeAdapter(challengeListType, new ChallengeListDeserializer())
|
||||||
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||||
.create();
|
.create();
|
||||||
return GsonConverterFactory.create(gson);
|
return GsonConverterFactory.create(gson);
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,18 @@ import com.github.underscore.$;
|
||||||
import com.habitrpg.android.habitica.data.ApiClient;
|
import com.habitrpg.android.habitica.data.ApiClient;
|
||||||
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||||
import com.habitrpg.android.habitica.data.local.ChallengeLocalRepository;
|
import com.habitrpg.android.habitica.data.local.ChallengeLocalRepository;
|
||||||
|
import com.habitrpg.android.habitica.models.LeaveChallengeBody;
|
||||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||||
import com.habitrpg.android.habitica.models.social.Group;
|
|
||||||
import com.habitrpg.android.habitica.models.tasks.Task;
|
import com.habitrpg.android.habitica.models.tasks.Task;
|
||||||
import com.habitrpg.android.habitica.models.tasks.TaskList;
|
import com.habitrpg.android.habitica.models.tasks.TaskList;
|
||||||
import com.habitrpg.android.habitica.models.tasks.TasksOrder;
|
import com.habitrpg.android.habitica.models.tasks.TasksOrder;
|
||||||
|
import com.habitrpg.android.habitica.models.user.User;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import io.realm.RealmResults;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
import rx.schedulers.Schedulers;
|
import rx.schedulers.Schedulers;
|
||||||
|
|
||||||
|
|
@ -110,12 +112,30 @@ public class ChallengeRepositoryImpl extends BaseRepositoryImpl<ChallengeLocalRe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUsersGroups(List<Group> groups) {
|
public Observable<RealmResults<Challenge>> getChallenges() {
|
||||||
localRepository.setUsersGroups(groups);
|
return localRepository.getChallenges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Observable<List<Group>> getLocalGroups() {
|
public Observable<RealmResults<Challenge>> getUserChallenges(String userId) {
|
||||||
return localRepository.getGroups();
|
return localRepository.getUserChallenges(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Observable<List<Challenge>> retrieveChallenges(User user) {
|
||||||
|
return apiClient.getUserChallenges()
|
||||||
|
.doOnNext(challenges -> localRepository.saveChallenges(user, challenges));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Observable<Void> leaveChallenge(Challenge challenge, LeaveChallengeBody leaveChallengeBody) {
|
||||||
|
return apiClient.leaveChallenge(challenge.id, leaveChallengeBody)
|
||||||
|
.doOnNext(aVoid -> localRepository.setParticipating(challenge, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Observable<Challenge> joinChallenge(Challenge challenge) {
|
||||||
|
return apiClient.joinChallenge(challenge.id)
|
||||||
|
.doOnNext(aVoid -> localRepository.setParticipating(challenge, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,8 +106,8 @@ public class SocialRepositoryImpl extends BaseRepositoryImpl<SocialLocalReposito
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Observable<List<Group>> getGroups(String type) {
|
public Observable<RealmResults<Group>> getGroups(String type) {
|
||||||
return retrieveGroups(type);
|
return localRepository.getGroups(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -143,21 +143,6 @@ public class SocialRepositoryImpl extends BaseRepositoryImpl<SocialLocalReposito
|
||||||
return apiClient.getMember(userId);
|
return apiClient.getMember(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<Challenge> getChallenge(String challengeId) {
|
|
||||||
return localRepository.getChallenge(challengeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<RealmResults<Challenge>> getChallenges() {
|
|
||||||
return localRepository.getChallenges();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<RealmResults<Challenge>> getUserChallenges(String userId) {
|
|
||||||
return localRepository.getUserChallenges(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Observable<Void> markPrivateMessagesRead(User user) {
|
public Observable<Void> markPrivateMessagesRead(User user) {
|
||||||
return apiClient.markPrivateMessagesRead()
|
return apiClient.markPrivateMessagesRead()
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,22 @@ package com.habitrpg.android.habitica.data.local;
|
||||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||||
import com.habitrpg.android.habitica.models.social.Group;
|
import com.habitrpg.android.habitica.models.social.Group;
|
||||||
import com.habitrpg.android.habitica.models.tasks.Task;
|
import com.habitrpg.android.habitica.models.tasks.Task;
|
||||||
|
import com.habitrpg.android.habitica.models.user.User;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.realm.RealmResults;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
|
||||||
public interface ChallengeLocalRepository extends BaseLocalRepository {
|
public interface ChallengeLocalRepository extends BaseLocalRepository {
|
||||||
Observable<Challenge> getChallenge(String id);
|
Observable<Challenge> getChallenge(String id);
|
||||||
Observable<List<Task>> getTasks(Challenge challenge);
|
Observable<List<Task>> getTasks(Challenge challenge);
|
||||||
|
|
||||||
void setUsersGroups(List<Group> group);
|
Observable<RealmResults<Challenge>> getChallenges();
|
||||||
|
|
||||||
Observable<List<Group>> getGroups();
|
Observable<RealmResults<Challenge>> getUserChallenges(String userId);
|
||||||
|
|
||||||
|
void saveChallenges(User user, List<Challenge> challenges);
|
||||||
|
|
||||||
|
void setParticipating(Challenge challenge, boolean isParticipating);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.habitrpg.android.habitica.data.local;
|
||||||
|
|
||||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||||
import com.habitrpg.android.habitica.models.social.ChatMessage;
|
import com.habitrpg.android.habitica.models.social.ChatMessage;
|
||||||
|
import com.habitrpg.android.habitica.models.social.Group;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -9,9 +10,5 @@ import io.realm.RealmResults;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
|
||||||
public interface SocialLocalRepository extends BaseLocalRepository {
|
public interface SocialLocalRepository extends BaseLocalRepository {
|
||||||
Observable<Challenge> getChallenge(String challengeId);
|
Observable<RealmResults<Group>> getGroups(String type);
|
||||||
|
|
||||||
Observable<RealmResults<Challenge>> getChallenges();
|
|
||||||
|
|
||||||
Observable<RealmResults<Challenge>> getUserChallenges(String userId);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,13 @@ import com.habitrpg.android.habitica.data.local.ChallengeLocalRepository;
|
||||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||||
import com.habitrpg.android.habitica.models.social.Group;
|
import com.habitrpg.android.habitica.models.social.Group;
|
||||||
import com.habitrpg.android.habitica.models.tasks.Task;
|
import com.habitrpg.android.habitica.models.tasks.Task;
|
||||||
|
import com.habitrpg.android.habitica.models.user.User;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import io.realm.Realm;
|
import io.realm.Realm;
|
||||||
|
import io.realm.RealmResults;
|
||||||
|
import io.realm.Sort;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
|
||||||
public class RealmChallengeLocalRepository extends RealmBaseLocalRepository implements ChallengeLocalRepository {
|
public class RealmChallengeLocalRepository extends RealmBaseLocalRepository implements ChallengeLocalRepository {
|
||||||
|
|
@ -32,12 +35,31 @@ public class RealmChallengeLocalRepository extends RealmBaseLocalRepository impl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUsersGroups(List<Group> groups) {
|
public Observable<RealmResults<Challenge>> getChallenges() {
|
||||||
|
return realm.where(Challenge.class)
|
||||||
|
.isNotNull("name")
|
||||||
|
.findAllSortedAsync("memberCount", Sort.DESCENDING)
|
||||||
|
.asObservable()
|
||||||
|
.filter(RealmResults::isLoaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Observable<List<Group>> getGroups() {
|
public Observable<RealmResults<Challenge>> getUserChallenges(String userId) {
|
||||||
return null;
|
return realm.where(Challenge.class)
|
||||||
|
.isNotNull("name")
|
||||||
|
.equalTo("isParticipating", true)
|
||||||
|
.findAllSortedAsync("memberCount", Sort.DESCENDING)
|
||||||
|
.asObservable()
|
||||||
|
.filter(RealmResults::isLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveChallenges(User user, List<Challenge> challenges) {
|
||||||
|
realm.executeTransactionAsync(realm1 -> realm1.copyToRealmOrUpdate(challenges));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setParticipating(Challenge challenge, boolean isParticipating) {
|
||||||
|
realm.executeTransaction(realm1 -> challenge.isParticipating = isParticipating);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
package com.habitrpg.android.habitica.data.local.implementation;
|
package com.habitrpg.android.habitica.data.local.implementation;
|
||||||
|
|
||||||
import com.habitrpg.android.habitica.data.local.SocialLocalRepository;
|
import com.habitrpg.android.habitica.data.local.SocialLocalRepository;
|
||||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
import com.habitrpg.android.habitica.models.social.Group;
|
||||||
import com.habitrpg.android.habitica.models.social.ChatMessage;
|
|
||||||
|
|
||||||
import io.realm.Realm;
|
import io.realm.Realm;
|
||||||
import io.realm.RealmResults;
|
import io.realm.RealmResults;
|
||||||
|
|
@ -16,30 +15,10 @@ public class RealmSocialLocalRepository extends RealmBaseLocalRepository impleme
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Observable<Challenge> getChallenge(String challengeId) {
|
public Observable<RealmResults<Group>> getGroups(String type) {
|
||||||
return realm.where(Challenge.class)
|
return realm.where(Group.class)
|
||||||
.equalTo("id", challengeId)
|
.equalTo("type", type)
|
||||||
.findFirstAsync()
|
.findAllAsync()
|
||||||
.asObservable()
|
|
||||||
.filter(realmObject -> realmObject.isLoaded())
|
|
||||||
.cast(Challenge.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<RealmResults<Challenge>> getChallenges() {
|
|
||||||
return realm.where(Challenge.class)
|
|
||||||
.isNotNull("name")
|
|
||||||
.findAll()
|
|
||||||
.asObservable()
|
|
||||||
.filter(RealmResults::isLoaded);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Observable<RealmResults<Challenge>> getUserChallenges(String userId) {
|
|
||||||
return realm.where(Challenge.class)
|
|
||||||
.isNotNull("name")
|
|
||||||
.equalTo("userId", userId)
|
|
||||||
.findAll()
|
|
||||||
.asObservable()
|
.asObservable()
|
||||||
.filter(RealmResults::isLoaded);
|
.filter(RealmResults::isLoaded);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,6 @@ public class Challenge extends RealmObject {
|
||||||
public int prize;
|
public int prize;
|
||||||
public boolean official;
|
public boolean official;
|
||||||
public int memberCount;
|
public int memberCount;
|
||||||
@SerializedName("user_id")
|
|
||||||
public String userId;
|
|
||||||
public String todoList;
|
public String todoList;
|
||||||
public String habitList;
|
public String habitList;
|
||||||
public String dailyList;
|
public String dailyList;
|
||||||
|
|
@ -41,6 +39,7 @@ public class Challenge extends RealmObject {
|
||||||
public User leader;
|
public User leader;
|
||||||
@Ignore
|
@Ignore
|
||||||
public TasksOrder tasksOrder;
|
public TasksOrder tasksOrder;
|
||||||
|
public boolean isParticipating;
|
||||||
|
|
||||||
public HashMap<String, String[]> getTasksOrder() {
|
public HashMap<String, String[]> getTasksOrder() {
|
||||||
HashMap<String, String[]> map = new HashMap();
|
HashMap<String, String[]> map = new HashMap();
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@ import io.realm.annotations.PrimaryKey;
|
||||||
|
|
||||||
public class User extends RealmObject {
|
public class User extends RealmObject {
|
||||||
|
|
||||||
@Ignore
|
|
||||||
List<Challenge> challengeList;
|
|
||||||
@Ignore
|
@Ignore
|
||||||
public TaskList tasks;
|
public TaskList tasks;
|
||||||
|
|
||||||
|
|
@ -54,21 +52,7 @@ public class User extends RealmObject {
|
||||||
@Ignore
|
@Ignore
|
||||||
private TasksOrder tasksOrder;
|
private TasksOrder tasksOrder;
|
||||||
|
|
||||||
@Ignore
|
private RealmList<Challenge> challenges;
|
||||||
private List<String> challenges;
|
|
||||||
|
|
||||||
|
|
||||||
public List<Challenge> getChallengeList() {
|
|
||||||
return challengeList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChallengeList(List<Challenge> challenges) {
|
|
||||||
this.challengeList = challenges;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetChallengeList() {
|
|
||||||
challengeList = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Preferences getPreferences() {
|
public Preferences getPreferences() {
|
||||||
return preferences;
|
return preferences;
|
||||||
|
|
@ -248,14 +232,6 @@ public class User extends RealmObject {
|
||||||
this.pushDevices = pushDevices;
|
this.pushDevices = pushDevices;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getChallenges() {
|
|
||||||
return challenges;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChallenges(List<String> challenges) {
|
|
||||||
this.challenges = challenges;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getAvatarLayerNames() {
|
public List<String> getAvatarLayerNames() {
|
||||||
List<String> layerNames = new ArrayList<String>();
|
List<String> layerNames = new ArrayList<String>();
|
||||||
|
|
||||||
|
|
@ -467,4 +443,12 @@ public class User extends RealmObject {
|
||||||
public void setTags(RealmList<Tag> tags) {
|
public void setTags(RealmList<Tag> tags) {
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RealmList<Challenge> getChallenges() {
|
||||||
|
return challenges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChallenges(RealmList<Challenge> challenges) {
|
||||||
|
this.challenges = challenges;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,7 @@ import android.widget.TextView;
|
||||||
|
|
||||||
import com.habitrpg.android.habitica.R;
|
import com.habitrpg.android.habitica.R;
|
||||||
import com.habitrpg.android.habitica.components.AppComponent;
|
import com.habitrpg.android.habitica.components.AppComponent;
|
||||||
import com.habitrpg.android.habitica.data.ApiClient;
|
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||||
import com.habitrpg.android.habitica.data.SocialRepository;
|
|
||||||
import com.habitrpg.android.habitica.data.UserRepository;
|
import com.habitrpg.android.habitica.data.UserRepository;
|
||||||
import com.habitrpg.android.habitica.events.HabitScoreEvent;
|
import com.habitrpg.android.habitica.events.HabitScoreEvent;
|
||||||
import com.habitrpg.android.habitica.events.TaskUpdatedEvent;
|
import com.habitrpg.android.habitica.events.TaskUpdatedEvent;
|
||||||
|
|
@ -76,9 +75,7 @@ public class ChallengeDetailActivity extends BaseActivity {
|
||||||
Toolbar toolbar;
|
Toolbar toolbar;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ApiClient apiClient;
|
ChallengeRepository challengeRepository;
|
||||||
@Inject
|
|
||||||
SocialRepository socialRepository;
|
|
||||||
@Inject
|
@Inject
|
||||||
@Named(AppModule.NAMED_USER_ID)
|
@Named(AppModule.NAMED_USER_ID)
|
||||||
String userId;
|
String userId;
|
||||||
|
|
@ -154,8 +151,7 @@ public class ChallengeDetailActivity extends BaseActivity {
|
||||||
userRepository.getUser(userId).first().subscribe(user -> ChallengeDetailActivity.this.user = user, ReactiveErrorHandler.handleEmptyError());
|
userRepository.getUser(userId).first().subscribe(user -> ChallengeDetailActivity.this.user = user, ReactiveErrorHandler.handleEmptyError());
|
||||||
|
|
||||||
if (challengeId != null) {
|
if (challengeId != null) {
|
||||||
|
challengeRepository.getChallengeTasks(challengeId)
|
||||||
apiClient.getChallengeTasks(challengeId)
|
|
||||||
.subscribe(taskList -> {
|
.subscribe(taskList -> {
|
||||||
ArrayList<Task> resultList = new ArrayList<>();
|
ArrayList<Task> resultList = new ArrayList<>();
|
||||||
|
|
||||||
|
|
@ -243,7 +239,7 @@ public class ChallengeDetailActivity extends BaseActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (challengeId != null) {
|
if (challengeId != null) {
|
||||||
socialRepository.getChallenge(challengeId).subscribe(challenge -> {
|
challengeRepository.getChallenge(challengeId).subscribe(challenge -> {
|
||||||
ChallengeDetailActivity.this.challenge = challenge;
|
ChallengeDetailActivity.this.challenge = challenge;
|
||||||
ChallengeViewHolder challengeViewHolder = new ChallengeViewHolder(findViewById(R.id.challenge_header));
|
ChallengeViewHolder challengeViewHolder = new ChallengeViewHolder(findViewById(R.id.challenge_header));
|
||||||
challengeViewHolder.bind(challenge);
|
challengeViewHolder.bind(challenge);
|
||||||
|
|
@ -253,13 +249,13 @@ public class ChallengeDetailActivity extends BaseActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
socialRepository.close();
|
challengeRepository.close();
|
||||||
userRepository.close();
|
userRepository.close();
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void injectActivity(AppComponent component) {
|
protected void injectActivity(AppComponent component) {
|
||||||
openChallengeEditActivity();
|
component.inject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -292,15 +288,8 @@ public class ChallengeDetailActivity extends BaseActivity {
|
||||||
.setPositiveButton(this.getString(R.string.yes), (dialog, which) -> {
|
.setPositiveButton(this.getString(R.string.yes), (dialog, which) -> {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
|
|
||||||
showRemoveTasksDialog(keepTasks -> this.apiClient.leaveChallenge(challenge.id, new LeaveChallengeBody(keepTasks))
|
showRemoveTasksDialog(keepTasks -> this.challengeRepository.leaveChallenge(challenge, new LeaveChallengeBody(keepTasks))
|
||||||
.subscribe(aVoid -> {
|
.subscribe(aVoid -> finish(), throwable -> {}));
|
||||||
challenge.userId = null;
|
|
||||||
|
|
||||||
user.resetChallengeList();
|
|
||||||
finish();
|
|
||||||
|
|
||||||
}, throwable -> {
|
|
||||||
}));
|
|
||||||
})
|
})
|
||||||
.setNegativeButton(this.getString(R.string.no), (dialog, which) -> dialog.dismiss()).show();
|
.setNegativeButton(this.getString(R.string.no), (dialog, which) -> dialog.dismiss()).show();
|
||||||
}
|
}
|
||||||
|
|
@ -375,12 +364,9 @@ public class ChallengeDetailActivity extends BaseActivity {
|
||||||
|
|
||||||
@OnClick(R.id.btn_show_more)
|
@OnClick(R.id.btn_show_more)
|
||||||
void onShowMore() {
|
void onShowMore() {
|
||||||
|
ChallengeDetailDialogHolder.showDialog(ChallengeDetailActivity.this,
|
||||||
ChallengeDetailDialogHolder.showDialog(ChallengeDetailActivity.this, ChallengeDetailActivity.this.apiClient,
|
ChallengeDetailActivity.this.challengeRepository,
|
||||||
user, challenge,
|
challenge,
|
||||||
challenge1 -> {
|
|
||||||
|
|
||||||
},
|
|
||||||
challenge1 -> ChallengeDetailActivity.this.onBackPressed());
|
challenge1 -> ChallengeDetailActivity.this.onBackPressed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import android.content.Intent;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.design.widget.TextInputLayout;
|
import android.support.design.widget.TextInputLayout;
|
||||||
|
|
@ -33,12 +34,16 @@ import com.habitrpg.android.habitica.HabiticaApplication;
|
||||||
import com.habitrpg.android.habitica.R;
|
import com.habitrpg.android.habitica.R;
|
||||||
import com.habitrpg.android.habitica.components.AppComponent;
|
import com.habitrpg.android.habitica.components.AppComponent;
|
||||||
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||||
|
import com.habitrpg.android.habitica.data.SocialRepository;
|
||||||
|
import com.habitrpg.android.habitica.data.UserRepository;
|
||||||
import com.habitrpg.android.habitica.events.TaskSaveEvent;
|
import com.habitrpg.android.habitica.events.TaskSaveEvent;
|
||||||
import com.habitrpg.android.habitica.events.TaskTappedEvent;
|
import com.habitrpg.android.habitica.events.TaskTappedEvent;
|
||||||
|
import com.habitrpg.android.habitica.helpers.ReactiveErrorHandler;
|
||||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||||
import com.habitrpg.android.habitica.models.social.Group;
|
import com.habitrpg.android.habitica.models.social.Group;
|
||||||
import com.habitrpg.android.habitica.models.tasks.Task;
|
import com.habitrpg.android.habitica.models.tasks.Task;
|
||||||
import com.habitrpg.android.habitica.models.user.User;
|
import com.habitrpg.android.habitica.models.user.User;
|
||||||
|
import com.habitrpg.android.habitica.modules.AppModule;
|
||||||
import com.habitrpg.android.habitica.ui.adapter.social.challenges.ChallengeTasksRecyclerViewAdapter;
|
import com.habitrpg.android.habitica.ui.adapter.social.challenges.ChallengeTasksRecyclerViewAdapter;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
@ -47,9 +52,11 @@ import org.greenrobot.eventbus.Subscribe;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
|
|
@ -100,6 +107,13 @@ public class CreateChallengeActivity extends BaseActivity {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ChallengeRepository challengeRepository;
|
ChallengeRepository challengeRepository;
|
||||||
|
@Inject
|
||||||
|
SocialRepository socialRepository;
|
||||||
|
@Inject
|
||||||
|
UserRepository userRepository;
|
||||||
|
@Inject
|
||||||
|
@Named(AppModule.NAMED_USER_ID)
|
||||||
|
String userId;
|
||||||
|
|
||||||
private ChallengeTasksRecyclerViewAdapter challengeTasks;
|
private ChallengeTasksRecyclerViewAdapter challengeTasks;
|
||||||
|
|
||||||
|
|
@ -116,8 +130,15 @@ public class CreateChallengeActivity extends BaseActivity {
|
||||||
Task addDaily;
|
Task addDaily;
|
||||||
Task addTodo;
|
Task addTodo;
|
||||||
Task addReward;
|
Task addReward;
|
||||||
|
@Nullable
|
||||||
private User user;
|
private User user;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
|
||||||
|
super.onCreate(savedInstanceState, persistentState);
|
||||||
|
userRepository.getUser(userId).subscribe(user1 -> this.user = user1, ReactiveErrorHandler.handleEmptyError());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getLayoutResId() {
|
protected int getLayoutResId() {
|
||||||
return R.layout.activity_create_challenge;
|
return R.layout.activity_create_challenge;
|
||||||
|
|
@ -234,6 +255,8 @@ public class CreateChallengeActivity extends BaseActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
|
socialRepository.close();
|
||||||
|
challengeRepository.close();
|
||||||
EventBus.getDefault().unregister(this);
|
EventBus.getDefault().unregister(this);
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
@ -288,7 +311,10 @@ public class CreateChallengeActivity extends BaseActivity {
|
||||||
// 0 is Tavern
|
// 0 is Tavern
|
||||||
int selectedLocation = challengeLocationSpinner.getSelectedItemPosition();
|
int selectedLocation = challengeLocationSpinner.getSelectedItemPosition();
|
||||||
|
|
||||||
double gemCount = user.getGemCount();
|
double gemCount = 0;
|
||||||
|
if (user != null) {
|
||||||
|
gemCount = user.getGemCount();
|
||||||
|
}
|
||||||
|
|
||||||
if (selectedLocation == 0 && currentVal == 0) {
|
if (selectedLocation == 0 && currentVal == 0) {
|
||||||
createChallengeGemError.setVisibility(View.VISIBLE);
|
createChallengeGemError.setVisibility(View.VISIBLE);
|
||||||
|
|
@ -324,7 +350,7 @@ public class CreateChallengeActivity extends BaseActivity {
|
||||||
|
|
||||||
locationAdapter = new GroupArrayAdapter(this);
|
locationAdapter = new GroupArrayAdapter(this);
|
||||||
locationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
locationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
challengeRepository.getLocalGroups().subscribe(groups -> {
|
socialRepository.getGroups("guild").subscribe(groups -> {
|
||||||
Group tavern = new Group();
|
Group tavern = new Group();
|
||||||
tavern.id = "00000000-0000-4000-A000-000000000000";
|
tavern.id = "00000000-0000-4000-A000-000000000000";
|
||||||
tavern.name = getString(R.string.sidebar_tavern);
|
tavern.name = getString(R.string.sidebar_tavern);
|
||||||
|
|
@ -332,7 +358,7 @@ public class CreateChallengeActivity extends BaseActivity {
|
||||||
locationAdapter.add(tavern);
|
locationAdapter.add(tavern);
|
||||||
|
|
||||||
groups.forEach(group -> locationAdapter.add(group));
|
groups.forEach(group -> locationAdapter.add(group));
|
||||||
}, Throwable::printStackTrace);
|
}, ReactiveErrorHandler.handleEmptyError());
|
||||||
|
|
||||||
challengeLocationSpinner.setAdapter(locationAdapter);
|
challengeLocationSpinner.setAdapter(locationAdapter);
|
||||||
challengeLocationSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
challengeLocationSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
|
|
@ -410,12 +436,12 @@ public class CreateChallengeActivity extends BaseActivity {
|
||||||
createChallengeTitle.setText(challenge.name);
|
createChallengeTitle.setText(challenge.name);
|
||||||
createChallengeDescription.setText(challenge.description);
|
createChallengeDescription.setText(challenge.description);
|
||||||
createChallengeTag.setText(challenge.shortName);
|
createChallengeTag.setText(challenge.shortName);
|
||||||
createChallengePrize.setText(challenge.prize + "");
|
createChallengePrize.setText(String.valueOf(challenge.prize));
|
||||||
|
|
||||||
for (int i = 0; i < locationAdapter.getCount(); i++) {
|
for (int i = 0; i < locationAdapter.getCount(); i++) {
|
||||||
Group group = locationAdapter.getItem(i);
|
Group group = locationAdapter.getItem(i);
|
||||||
|
|
||||||
if (group.id == challenge.groupId) {
|
if (group != null && challenge.groupId.equals(group.id)) {
|
||||||
challengeLocationSpinner.setSelection(i);
|
challengeLocationSpinner.setSelection(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -542,7 +568,7 @@ public class CreateChallengeActivity extends BaseActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class GroupArrayAdapter extends ArrayAdapter<Group> {
|
private class GroupArrayAdapter extends ArrayAdapter<Group> {
|
||||||
public GroupArrayAdapter(@NonNull Context context) {
|
GroupArrayAdapter(@NonNull Context context) {
|
||||||
super(context, android.R.layout.simple_spinner_item);
|
super(context, android.R.layout.simple_spinner_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,60 +10,28 @@ import android.view.ViewGroup;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.github.underscore.$;
|
|
||||||
import com.habitrpg.android.habitica.R;
|
import com.habitrpg.android.habitica.R;
|
||||||
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailActivityCommand;
|
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailActivityCommand;
|
||||||
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailDialogCommand;
|
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailDialogCommand;
|
||||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||||
import com.habitrpg.android.habitica.models.user.User;
|
|
||||||
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeFilterOptions;
|
|
||||||
|
|
||||||
import net.pherth.android.emoji_library.EmojiParser;
|
import net.pherth.android.emoji_library.EmojiParser;
|
||||||
import net.pherth.android.emoji_library.EmojiTextView;
|
import net.pherth.android.emoji_library.EmojiTextView;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import io.realm.OrderedRealmCollection;
|
||||||
|
import io.realm.RealmRecyclerViewAdapter;
|
||||||
|
|
||||||
public class ChallengesListViewAdapter extends RecyclerView.Adapter<ChallengesListViewAdapter.ChallengeViewHolder> {
|
public class ChallengesListViewAdapter extends RealmRecyclerViewAdapter<Challenge, ChallengesListViewAdapter.ChallengeViewHolder> {
|
||||||
private List<Challenge> challenges = new ArrayList<>();
|
|
||||||
private List<Challenge> challengesSource = new ArrayList<>();
|
|
||||||
|
|
||||||
private boolean viewUserChallengesOnly;
|
private boolean viewUserChallengesOnly;
|
||||||
@Nullable
|
|
||||||
private User user;
|
|
||||||
|
|
||||||
public ChallengesListViewAdapter(boolean viewUserChallengesOnly, @Nullable User user) {
|
public ChallengesListViewAdapter(@Nullable OrderedRealmCollection<Challenge> data, boolean autoUpdate, boolean viewUserChallengesOnly) {
|
||||||
|
super(data, autoUpdate);
|
||||||
this.viewUserChallengesOnly = viewUserChallengesOnly;
|
this.viewUserChallengesOnly = viewUserChallengesOnly;
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChallenges(List<Challenge> challenges) {
|
|
||||||
this.challengesSource = challenges;
|
|
||||||
this.challenges = new ArrayList<>(challengesSource);
|
|
||||||
this.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFilterByGroups(ChallengeFilterOptions filterOptions){
|
|
||||||
this.challenges = $.filter(challengesSource, arg -> {
|
|
||||||
boolean showChallenge = $.find(filterOptions.showByGroups, g -> g.id.contains(arg.groupId)).isPresent();
|
|
||||||
|
|
||||||
boolean showByOwnership = true;
|
|
||||||
if(filterOptions.showOwned == filterOptions.notOwned && this.user != null){
|
|
||||||
if (filterOptions.showOwned) {
|
|
||||||
showByOwnership = arg.leaderId.equals(this.user.getId());
|
|
||||||
} else {
|
|
||||||
showByOwnership = !arg.leaderId.equals(this.user.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return showChallenge && showByOwnership;
|
|
||||||
});
|
|
||||||
this.notifyDataSetChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -76,36 +44,7 @@ public class ChallengesListViewAdapter extends RecyclerView.Adapter<ChallengesLi
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(ChallengeViewHolder holder, int position) {
|
public void onBindViewHolder(ChallengeViewHolder holder, int position) {
|
||||||
holder.bind(challenges.get(position));
|
holder.bind(getData().get(position));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return challenges.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addChallenge(Challenge challenge) {
|
|
||||||
challenges.add(challenge);
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void replaceChallenge(Challenge challenge) {
|
|
||||||
int index = challenges.indexOf(challenge);
|
|
||||||
|
|
||||||
if (index == -1) {
|
|
||||||
for (int i = 0; i < challenges.size(); i++) {
|
|
||||||
if (challenges.get(i).id.equals(challenge.id)) {
|
|
||||||
index = i;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index != -1) {
|
|
||||||
challenges.set(index, challenge);
|
|
||||||
notifyItemChanged(index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ChallengeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
public static class ChallengeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||||
|
|
@ -175,14 +114,13 @@ public class ChallengesListViewAdapter extends RecyclerView.Adapter<ChallengesLi
|
||||||
challengeDescription.setText(challenge.groupName);
|
challengeDescription.setText(challenge.groupName);
|
||||||
|
|
||||||
officialChallengeLayout.setVisibility(challenge.official ? View.VISIBLE : View.GONE);
|
officialChallengeLayout.setVisibility(challenge.official ? View.VISIBLE : View.GONE);
|
||||||
boolean userIdExists = challenge.userId != null && !challenge.userId.isEmpty();
|
|
||||||
|
|
||||||
if (viewUserChallengesOnly) {
|
if (viewUserChallengesOnly) {
|
||||||
leaderParticipantLayout.setVisibility(View.GONE);
|
leaderParticipantLayout.setVisibility(View.GONE);
|
||||||
challengeParticipatingTextView.setVisibility(View.GONE);
|
challengeParticipatingTextView.setVisibility(View.GONE);
|
||||||
arrowImage.setVisibility(View.VISIBLE);
|
arrowImage.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
challengeParticipatingTextView.setVisibility(userIdExists ? View.VISIBLE : View.GONE);
|
challengeParticipatingTextView.setVisibility(challenge.isParticipating ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
leaderName.setText(itemView.getContext().getString(R.string.byLeader, challenge.leaderName));
|
leaderName.setText(itemView.getContext().getString(R.string.byLeader, challenge.leaderName));
|
||||||
participantCount.setText(String.valueOf(challenge.memberCount));
|
participantCount.setText(String.valueOf(challenge.memberCount));
|
||||||
|
|
|
||||||
|
|
@ -93,10 +93,7 @@ public class GuildsOverviewFragment extends BaseMainFragment implements View.OnC
|
||||||
if (swipeRefreshLayout != null) {
|
if (swipeRefreshLayout != null) {
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
}
|
}
|
||||||
|
}, throwable -> {});
|
||||||
challengeRepository.setUsersGroups(groups);
|
|
||||||
}, throwable -> {
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,10 @@ import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.habitrpg.android.habitica.HabiticaApplication;
|
||||||
import com.habitrpg.android.habitica.R;
|
import com.habitrpg.android.habitica.R;
|
||||||
import com.habitrpg.android.habitica.data.ApiClient;
|
import com.habitrpg.android.habitica.data.ApiClient;
|
||||||
|
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||||
import com.habitrpg.android.habitica.events.commands.OpenFullProfileCommand;
|
import com.habitrpg.android.habitica.events.commands.OpenFullProfileCommand;
|
||||||
import com.habitrpg.android.habitica.models.LeaveChallengeBody;
|
import com.habitrpg.android.habitica.models.LeaveChallengeBody;
|
||||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||||
|
|
@ -30,6 +32,8 @@ import org.greenrobot.eventbus.EventBus;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
|
|
@ -37,6 +41,7 @@ import rx.functions.Action1;
|
||||||
|
|
||||||
public class ChallengeDetailDialogHolder {
|
public class ChallengeDetailDialogHolder {
|
||||||
|
|
||||||
|
|
||||||
@BindView(R.id.challenge_not_joined_header)
|
@BindView(R.id.challenge_not_joined_header)
|
||||||
LinearLayout notJoinedHeader;
|
LinearLayout notJoinedHeader;
|
||||||
|
|
||||||
|
|
@ -68,11 +73,9 @@ public class ChallengeDetailDialogHolder {
|
||||||
LinearLayout task_group_layout;
|
LinearLayout task_group_layout;
|
||||||
|
|
||||||
private AlertDialog dialog;
|
private AlertDialog dialog;
|
||||||
private ApiClient apiClient;
|
private ChallengeRepository challengeRepository;
|
||||||
@Nullable
|
@Nullable
|
||||||
private User user;
|
|
||||||
private Challenge challenge;
|
private Challenge challenge;
|
||||||
private Action1<Challenge> challengeJoinedAction;
|
|
||||||
private Action1<Challenge> challengeLeftAction;
|
private Action1<Challenge> challengeLeftAction;
|
||||||
private Activity context;
|
private Activity context;
|
||||||
|
|
||||||
|
|
@ -82,8 +85,7 @@ public class ChallengeDetailDialogHolder {
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showDialog(Activity activity, ApiClient apiClient, @Nullable User user, Challenge challenge,
|
public static void showDialog(Activity activity, ChallengeRepository challengeRepository, Challenge challenge, Action1<Challenge> challengeLeftAction) {
|
||||||
Action1<Challenge> challengeJoinedAction, Action1<Challenge> challengeLeftAction) {
|
|
||||||
View dialogLayout = activity.getLayoutInflater().inflate(R.layout.dialog_challenge_detail, null);
|
View dialogLayout = activity.getLayoutInflater().inflate(R.layout.dialog_challenge_detail, null);
|
||||||
|
|
||||||
ChallengeDetailDialogHolder challengeDetailDialogHolder = new ChallengeDetailDialogHolder(dialogLayout, activity);
|
ChallengeDetailDialogHolder challengeDetailDialogHolder = new ChallengeDetailDialogHolder(dialogLayout, activity);
|
||||||
|
|
@ -91,23 +93,21 @@ public class ChallengeDetailDialogHolder {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity)
|
AlertDialog.Builder builder = new AlertDialog.Builder(activity)
|
||||||
.setView(dialogLayout);
|
.setView(dialogLayout);
|
||||||
|
|
||||||
challengeDetailDialogHolder.bind(builder.show(), apiClient, user, challenge, challengeJoinedAction, challengeLeftAction);
|
challengeDetailDialogHolder.bind(builder.show(), challengeRepository, challenge, challengeLeftAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(AlertDialog dialog, ApiClient apiClient, @Nullable User user, Challenge challenge,
|
public void bind(AlertDialog dialog, ChallengeRepository challengeRepository, Challenge challenge,
|
||||||
Action1<Challenge> challengeJoinedAction, Action1<Challenge> challengeLeftAction) {
|
Action1<Challenge> challengeLeftAction) {
|
||||||
this.dialog = dialog;
|
this.dialog = dialog;
|
||||||
this.apiClient = apiClient;
|
this.challengeRepository = challengeRepository;
|
||||||
this.user = user;
|
|
||||||
this.challenge = challenge;
|
this.challenge = challenge;
|
||||||
this.challengeJoinedAction = challengeJoinedAction;
|
|
||||||
this.challengeLeftAction = challengeLeftAction;
|
this.challengeLeftAction = challengeLeftAction;
|
||||||
|
|
||||||
changeViewsByChallenge(challenge);
|
changeViewsByChallenge(challenge);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeViewsByChallenge(Challenge challenge) {
|
private void changeViewsByChallenge(Challenge challenge) {
|
||||||
setJoined(challenge.userId != null && !challenge.userId.isEmpty());
|
setJoined(challenge.isParticipating);
|
||||||
|
|
||||||
challengeName.setText(EmojiParser.parseEmojis(challenge.name));
|
challengeName.setText(EmojiParser.parseEmojis(challenge.name));
|
||||||
challengeDescription.setText(MarkdownParser.parseMarkdown(challenge.description));
|
challengeDescription.setText(MarkdownParser.parseMarkdown(challenge.description));
|
||||||
|
|
@ -116,7 +116,7 @@ public class ChallengeDetailDialogHolder {
|
||||||
gem_amount.setText(String.valueOf(challenge.prize));
|
gem_amount.setText(String.valueOf(challenge.prize));
|
||||||
member_count.setText(String.valueOf(challenge.memberCount));
|
member_count.setText(String.valueOf(challenge.memberCount));
|
||||||
|
|
||||||
apiClient.getChallengeTasks(challenge.id)
|
challengeRepository.getChallengeTasks(challenge.id)
|
||||||
.subscribe(taskList -> {
|
.subscribe(taskList -> {
|
||||||
ArrayList<Task> todos = new ArrayList<>();
|
ArrayList<Task> todos = new ArrayList<>();
|
||||||
ArrayList<Task> habits = new ArrayList<>();
|
ArrayList<Task> habits = new ArrayList<>();
|
||||||
|
|
@ -287,19 +287,7 @@ public class ChallengeDetailDialogHolder {
|
||||||
|
|
||||||
@OnClick(R.id.challenge_join_btn)
|
@OnClick(R.id.challenge_join_btn)
|
||||||
void joinChallenge() {
|
void joinChallenge() {
|
||||||
this.apiClient.joinChallenge(challenge.id)
|
this.challengeRepository.joinChallenge(challenge).subscribe(this::changeViewsByChallenge, throwable -> {});
|
||||||
.subscribe(challenge -> {
|
|
||||||
if (this.user != null) {
|
|
||||||
challenge.userId = this.user.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (challengeJoinedAction != null) {
|
|
||||||
challengeJoinedAction.call(challenge);
|
|
||||||
}
|
|
||||||
|
|
||||||
changeViewsByChallenge(challenge);
|
|
||||||
}, throwable -> {
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.challenge_leave_btn)
|
@OnClick(R.id.challenge_leave_btn)
|
||||||
|
|
@ -308,19 +296,11 @@ public class ChallengeDetailDialogHolder {
|
||||||
.setTitle(context.getString(R.string.challenge_leave_title))
|
.setTitle(context.getString(R.string.challenge_leave_title))
|
||||||
.setMessage(context.getString(R.string.challenge_leave_text, challenge.name))
|
.setMessage(context.getString(R.string.challenge_leave_text, challenge.name))
|
||||||
.setPositiveButton(context.getString(R.string.yes), (dialog, which) ->
|
.setPositiveButton(context.getString(R.string.yes), (dialog, which) ->
|
||||||
|
showRemoveTasksDialog(keepTasks -> this.challengeRepository.leaveChallenge(challenge, new LeaveChallengeBody(keepTasks))
|
||||||
showRemoveTasksDialog(keepTasks -> this.apiClient.leaveChallenge(challenge.id, new LeaveChallengeBody(keepTasks))
|
|
||||||
.subscribe(aVoid -> {
|
.subscribe(aVoid -> {
|
||||||
challenge.userId = null;
|
|
||||||
|
|
||||||
if (this.user != null) {
|
|
||||||
this.user.resetChallengeList();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (challengeLeftAction != null) {
|
if (challengeLeftAction != null) {
|
||||||
challengeLeftAction.call(challenge);
|
challengeLeftAction.call(challenge);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dialog.dismiss();
|
this.dialog.dismiss();
|
||||||
}, throwable -> {
|
}, throwable -> {
|
||||||
}))).setNegativeButton(context.getString(R.string.no), (dialog, which) -> dialog.dismiss()).show();
|
}))).setNegativeButton(context.getString(R.string.no), (dialog, which) -> dialog.dismiss()).show();
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.habitrpg.android.habitica.ui.fragments.social.challenges;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
|
@ -29,9 +30,6 @@ class ChallengeFilterDialogHolder {
|
||||||
@BindView(R.id.challenge_filter_recycler_view)
|
@BindView(R.id.challenge_filter_recycler_view)
|
||||||
RecyclerView groupRecyclerView;
|
RecyclerView groupRecyclerView;
|
||||||
|
|
||||||
@BindView(R.id.challenge_filter_button_done)
|
|
||||||
Button doneButton;
|
|
||||||
|
|
||||||
@BindView(R.id.challenge_filter_button_all)
|
@BindView(R.id.challenge_filter_button_all)
|
||||||
Button allButton;
|
Button allButton;
|
||||||
|
|
||||||
|
|
@ -74,6 +72,7 @@ class ChallengeFilterDialogHolder {
|
||||||
ChallengeFilterOptions currentFilter,
|
ChallengeFilterOptions currentFilter,
|
||||||
Action1<ChallengeFilterOptions> selectedGroupsCallback) {
|
Action1<ChallengeFilterOptions> selectedGroupsCallback) {
|
||||||
this.dialog = dialog;
|
this.dialog = dialog;
|
||||||
|
this.dialog.setButton(Dialog.BUTTON_POSITIVE, context.getString(R.string.done), (dialog1, which) -> doneClicked());
|
||||||
this.challengesViewed = challengesViewed;
|
this.challengesViewed = challengesViewed;
|
||||||
this.currentFilter = currentFilter;
|
this.currentFilter = currentFilter;
|
||||||
this.selectedGroupsCallback = selectedGroupsCallback;
|
this.selectedGroupsCallback = selectedGroupsCallback;
|
||||||
|
|
@ -116,8 +115,7 @@ class ChallengeFilterDialogHolder {
|
||||||
return groupMap.values();
|
return groupMap.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.challenge_filter_button_done)
|
private void doneClicked() {
|
||||||
void doneClicked() {
|
|
||||||
ChallengeFilterOptions options = new ChallengeFilterOptions();
|
ChallengeFilterOptions options = new ChallengeFilterOptions();
|
||||||
options.showByGroups = this.adapter.getCheckedEntries();
|
options.showByGroups = this.adapter.getCheckedEntries();
|
||||||
options.showOwned = checkboxOwned.isChecked();
|
options.showOwned = checkboxOwned.isChecked();
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,9 @@ package com.habitrpg.android.habitica.ui.fragments.social.challenges;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.view.MenuItemCompat;
|
||||||
import android.support.v4.widget.SwipeRefreshLayout;
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
|
|
@ -13,19 +12,18 @@ import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.habitrpg.android.habitica.R;
|
import com.habitrpg.android.habitica.R;
|
||||||
import com.habitrpg.android.habitica.components.AppComponent;
|
import com.habitrpg.android.habitica.components.AppComponent;
|
||||||
import com.habitrpg.android.habitica.data.SocialRepository;
|
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||||
import com.habitrpg.android.habitica.helpers.ReactiveErrorHandler;
|
import com.habitrpg.android.habitica.helpers.ReactiveErrorHandler;
|
||||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||||
import com.habitrpg.android.habitica.ui.activities.CreateChallengeActivity;
|
import com.habitrpg.android.habitica.ui.activities.CreateChallengeActivity;
|
||||||
import com.habitrpg.android.habitica.ui.adapter.social.ChallengesListViewAdapter;
|
import com.habitrpg.android.habitica.ui.adapter.social.ChallengesListViewAdapter;
|
||||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
||||||
|
import com.habitrpg.android.habitica.ui.helpers.RecyclerViewEmptySupport;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
|
@ -33,31 +31,21 @@ import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import io.realm.RealmResults;
|
import io.realm.RealmResults;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
import rx.functions.Action0;
|
|
||||||
|
|
||||||
public class ChallengeListFragment extends BaseMainFragment implements SwipeRefreshLayout.OnRefreshListener {
|
public class ChallengeListFragment extends BaseMainFragment implements SwipeRefreshLayout.OnRefreshListener {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SocialRepository socialRepository;
|
ChallengeRepository challengeRepository;
|
||||||
|
|
||||||
@BindView(R.id.challenge_filter_layout)
|
@BindView(R.id.refresh_layout)
|
||||||
LinearLayout challengeFilterLayout;
|
|
||||||
|
|
||||||
@BindView(R.id.action_filter_icon)
|
|
||||||
View actionFilterIcon;
|
|
||||||
|
|
||||||
@BindView(R.id.challenges_refresh_layout)
|
|
||||||
SwipeRefreshLayout swipeRefreshLayout;
|
SwipeRefreshLayout swipeRefreshLayout;
|
||||||
|
@BindView(R.id.recyclerView)
|
||||||
@BindView(R.id.challenges_refresh_empty)
|
RecyclerViewEmptySupport recyclerView;
|
||||||
SwipeRefreshLayout swipeRefreshEmptyLayout;
|
@BindView(R.id.empty_view)
|
||||||
|
public View emptyView;
|
||||||
@BindView(R.id.challenges_list)
|
|
||||||
RecyclerView recyclerView;
|
|
||||||
|
|
||||||
private ChallengesListViewAdapter challengeAdapter;
|
private ChallengesListViewAdapter challengeAdapter;
|
||||||
private boolean viewUserChallengesOnly;
|
private boolean viewUserChallengesOnly;
|
||||||
private Action0 refreshCallback;
|
|
||||||
private boolean withFilter;
|
private boolean withFilter;
|
||||||
|
|
||||||
public void setWithFilter(boolean withFilter){
|
public void setWithFilter(boolean withFilter){
|
||||||
|
|
@ -68,58 +56,14 @@ public class ChallengeListFragment extends BaseMainFragment implements SwipeRefr
|
||||||
this.viewUserChallengesOnly = only;
|
this.viewUserChallengesOnly = only;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRefreshingCallback(Action0 refreshCallback) {
|
|
||||||
this.refreshCallback = refreshCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Challenge> currentChallengesInView;
|
private RealmResults<Challenge> challenges;
|
||||||
|
|
||||||
private ChallengeFilterOptions lastFilterOptions;
|
private ChallengeFilterOptions lastFilterOptions;
|
||||||
|
|
||||||
public void setObservable(Observable<List<Challenge>> listObservable) {
|
|
||||||
listObservable
|
|
||||||
.subscribe(challenges -> {
|
|
||||||
|
|
||||||
List<Challenge> userChallenges = this.user != null ? this.user.getChallengeList() : new ArrayList<>();
|
|
||||||
|
|
||||||
HashSet<String> userChallengesHash = new HashSet<>();
|
|
||||||
|
|
||||||
for (Challenge userChallenge : userChallenges) {
|
|
||||||
userChallengesHash.add(userChallenge.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
userChallenges.clear();
|
|
||||||
|
|
||||||
for (Challenge challenge : challenges) {
|
|
||||||
if (userChallengesHash.contains(challenge.id) && challenge.name != null && !challenge.name.isEmpty()) {
|
|
||||||
challenge.userId = this.user.getId();
|
|
||||||
userChallenges.add(challenge);
|
|
||||||
} else {
|
|
||||||
challenge.userId = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setRefreshingIfVisible(swipeRefreshLayout, false);
|
|
||||||
setRefreshingIfVisible(swipeRefreshEmptyLayout, false);
|
|
||||||
|
|
||||||
if (viewUserChallengesOnly) {
|
|
||||||
setChallengeEntries(userChallenges);
|
|
||||||
} else {
|
|
||||||
setChallengeEntries(challenges);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}, throwable -> {
|
|
||||||
Log.e("ChallengeListFragment", "", throwable);
|
|
||||||
|
|
||||||
setRefreshingIfVisible(swipeRefreshLayout, false);
|
|
||||||
setRefreshingIfVisible(swipeRefreshEmptyLayout, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
socialRepository.close();
|
challengeRepository.close();
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,17 +74,9 @@ public class ChallengeListFragment extends BaseMainFragment implements SwipeRefr
|
||||||
View v = inflater.inflate(R.layout.fragment_challengeslist, container, false);
|
View v = inflater.inflate(R.layout.fragment_challengeslist, container, false);
|
||||||
unbinder = ButterKnife.bind(this, v);
|
unbinder = ButterKnife.bind(this, v);
|
||||||
|
|
||||||
challengeAdapter = new ChallengesListViewAdapter(viewUserChallengesOnly, user);
|
challengeAdapter = new ChallengesListViewAdapter(null, true, viewUserChallengesOnly);
|
||||||
|
|
||||||
swipeRefreshLayout.setOnRefreshListener(this);
|
swipeRefreshLayout.setOnRefreshListener(this);
|
||||||
swipeRefreshEmptyLayout.setOnRefreshListener(this);
|
|
||||||
|
|
||||||
challengeFilterLayout.setVisibility(withFilter?View.VISIBLE:View.GONE);
|
|
||||||
challengeFilterLayout.setClickable(true);
|
|
||||||
challengeFilterLayout.setOnClickListener(view -> ChallengeFilterDialogHolder.showDialog(getActivity(), currentChallengesInView, lastFilterOptions, filterOptions -> {
|
|
||||||
challengeAdapter.setFilterByGroups(filterOptions);
|
|
||||||
this.lastFilterOptions = filterOptions;
|
|
||||||
}));
|
|
||||||
|
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(this.activity));
|
recyclerView.setLayoutManager(new LinearLayoutManager(this.activity));
|
||||||
recyclerView.setAdapter(challengeAdapter);
|
recyclerView.setAdapter(challengeAdapter);
|
||||||
|
|
@ -148,7 +84,9 @@ public class ChallengeListFragment extends BaseMainFragment implements SwipeRefr
|
||||||
this.recyclerView.setBackgroundResource(R.color.white);
|
this.recyclerView.setBackgroundResource(R.color.white);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchLocalChallenges();
|
recyclerView.setEmptyView(emptyView);
|
||||||
|
|
||||||
|
loadLocalChallenges();
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,72 +97,36 @@ public class ChallengeListFragment extends BaseMainFragment implements SwipeRefr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRefresh() {
|
public void onRefresh() {
|
||||||
setRefreshingIfVisible(swipeRefreshEmptyLayout, true);
|
|
||||||
setRefreshingIfVisible(swipeRefreshLayout, true);
|
|
||||||
|
|
||||||
fetchOnlineChallenges();
|
fetchOnlineChallenges();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRefreshingIfVisible(SwipeRefreshLayout refreshLayout, boolean state) {
|
private void setRefreshing(boolean state) {
|
||||||
if (refreshLayout != null && refreshLayout.getVisibility() == View.VISIBLE) {
|
if (swipeRefreshLayout != null && swipeRefreshLayout.getVisibility() == View.VISIBLE) {
|
||||||
refreshLayout.setRefreshing(state);
|
swipeRefreshLayout.setRefreshing(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchLocalChallenges() {
|
private void loadLocalChallenges() {
|
||||||
setRefreshingIfVisible(swipeRefreshLayout, true);
|
|
||||||
|
|
||||||
Observable<RealmResults<Challenge>> observable;
|
Observable<RealmResults<Challenge>> observable;
|
||||||
|
|
||||||
if (viewUserChallengesOnly && user != null) {
|
if (viewUserChallengesOnly && user != null) {
|
||||||
observable = socialRepository.getUserChallenges(user.getId());
|
observable = challengeRepository.getUserChallenges(user.getId());
|
||||||
} else {
|
} else {
|
||||||
observable = socialRepository.getChallenges();
|
observable = challengeRepository.getChallenges();
|
||||||
}
|
}
|
||||||
|
|
||||||
observable.subscribe(challenges -> {
|
observable.first().subscribe(challenges -> {
|
||||||
if (challenges.size() != 0) {
|
if (challenges.size() == 0) {
|
||||||
setChallengeEntries(challenges);
|
fetchOnlineChallenges();
|
||||||
}
|
}
|
||||||
|
this.challenges = challenges;
|
||||||
setRefreshingIfVisible(swipeRefreshLayout, false);
|
challengeAdapter.updateData(challenges);
|
||||||
|
|
||||||
// load online challenges & save to database
|
|
||||||
onRefresh();
|
|
||||||
}, ReactiveErrorHandler.handleEmptyError());
|
}, ReactiveErrorHandler.handleEmptyError());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setChallengeEntries(List<Challenge> challenges) {
|
|
||||||
if (swipeRefreshEmptyLayout == null || swipeRefreshLayout == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
currentChallengesInView = challenges;
|
|
||||||
|
|
||||||
if (viewUserChallengesOnly && challenges.size() == 0) {
|
|
||||||
swipeRefreshEmptyLayout.setVisibility(View.VISIBLE);
|
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
|
||||||
swipeRefreshLayout.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
swipeRefreshEmptyLayout.setRefreshing(false);
|
|
||||||
swipeRefreshEmptyLayout.setVisibility(View.GONE);
|
|
||||||
swipeRefreshLayout.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
challengeAdapter.setChallenges(challenges);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fetchOnlineChallenges() {
|
private void fetchOnlineChallenges() {
|
||||||
if (refreshCallback != null) {
|
setRefreshing(true);
|
||||||
refreshCallback.call();
|
challengeRepository.retrieveChallenges(user).subscribe(challenges -> setRefreshing(false), throwable -> setRefreshing(false));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addItem(Challenge challenge) {
|
|
||||||
challengeAdapter.addChallenge(challenge);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateItem(Challenge challenge) {
|
|
||||||
challengeAdapter.replaceChallenge(challenge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -235,7 +137,21 @@ public class ChallengeListFragment extends BaseMainFragment implements SwipeRefr
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
inflater.inflate(R.menu.menu_list_challenges, menu);
|
inflater.inflate(R.menu.menu_list_challenges, menu);
|
||||||
}
|
|
||||||
|
|
||||||
|
RelativeLayout badgeLayout = (RelativeLayout) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
|
||||||
|
TextView filterCountTextView = (TextView) badgeLayout.findViewById(R.id.badge_textview);
|
||||||
|
filterCountTextView.setText(null);
|
||||||
|
filterCountTextView.setVisibility(View.GONE);
|
||||||
|
badgeLayout.setOnClickListener(view -> showFilterDialog());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showFilterDialog() {
|
||||||
|
ChallengeFilterDialogHolder.showDialog(getActivity(),
|
||||||
|
challenges,
|
||||||
|
lastFilterOptions,
|
||||||
|
filterOptions -> this.lastFilterOptions = filterOptions);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
|
@ -248,7 +164,12 @@ public class ChallengeListFragment extends BaseMainFragment implements SwipeRefr
|
||||||
case R.id.action_create_challenge:
|
case R.id.action_create_challenge:
|
||||||
Intent intent = new Intent(getActivity(), CreateChallengeActivity.class);
|
Intent intent = new Intent(getActivity(), CreateChallengeActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
return true;
|
||||||
|
case R.id.action_reload:
|
||||||
|
fetchOnlineChallenges();
|
||||||
|
return true;
|
||||||
|
case R.id.action_search:
|
||||||
|
showFilterDialog();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,34 +11,24 @@ import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.habitrpg.android.habitica.R;
|
import com.habitrpg.android.habitica.R;
|
||||||
import com.habitrpg.android.habitica.components.AppComponent;
|
import com.habitrpg.android.habitica.components.AppComponent;
|
||||||
import com.habitrpg.android.habitica.data.SocialRepository;
|
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||||
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailActivityCommand;
|
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailActivityCommand;
|
||||||
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailDialogCommand;
|
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailDialogCommand;
|
||||||
import com.habitrpg.android.habitica.helpers.ReactiveErrorHandler;
|
import com.habitrpg.android.habitica.helpers.ReactiveErrorHandler;
|
||||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
|
||||||
import com.habitrpg.android.habitica.ui.activities.ChallengeDetailActivity;
|
import com.habitrpg.android.habitica.ui.activities.ChallengeDetailActivity;
|
||||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import rx.subjects.PublishSubject;
|
|
||||||
|
|
||||||
public class ChallengesOverviewFragment extends BaseMainFragment {
|
public class ChallengesOverviewFragment extends BaseMainFragment {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SocialRepository socialRepository;
|
ChallengeRepository challengeRepository;
|
||||||
|
|
||||||
public ViewPager viewPager;
|
public ViewPager viewPager;
|
||||||
public FragmentStatePagerAdapter statePagerAdapter;
|
public FragmentStatePagerAdapter statePagerAdapter;
|
||||||
int currentPage;
|
|
||||||
private Stack<Integer> pageHistory;
|
|
||||||
private boolean saveToHistory;
|
|
||||||
private PublishSubject<List<Challenge>> getUserChallengesObservable;
|
|
||||||
private ChallengeListFragment userChallengesFragment;
|
private ChallengeListFragment userChallengesFragment;
|
||||||
private ChallengeListFragment availableChallengesFragment;
|
private ChallengeListFragment availableChallengesFragment;
|
||||||
|
|
||||||
|
|
@ -53,40 +43,23 @@ public class ChallengesOverviewFragment extends BaseMainFragment {
|
||||||
|
|
||||||
setViewPagerAdapter();
|
setViewPagerAdapter();
|
||||||
|
|
||||||
getUserChallengesObservable = PublishSubject.create();
|
|
||||||
|
|
||||||
subscribeGetChallenges();
|
|
||||||
|
|
||||||
userChallengesFragment = new ChallengeListFragment();
|
userChallengesFragment = new ChallengeListFragment();
|
||||||
userChallengesFragment.setUser(this.user);
|
userChallengesFragment.setUser(this.user);
|
||||||
userChallengesFragment.setRefreshingCallback(this::subscribeGetChallenges);
|
|
||||||
userChallengesFragment.setObservable(getUserChallengesObservable);
|
|
||||||
userChallengesFragment.setViewUserChallengesOnly(true);
|
userChallengesFragment.setViewUserChallengesOnly(true);
|
||||||
userChallengesFragment.setWithFilter(true);
|
userChallengesFragment.setWithFilter(true);
|
||||||
|
|
||||||
availableChallengesFragment = new ChallengeListFragment();
|
availableChallengesFragment = new ChallengeListFragment();
|
||||||
availableChallengesFragment.setUser(this.user);
|
availableChallengesFragment.setUser(this.user);
|
||||||
availableChallengesFragment.setRefreshingCallback(this::subscribeGetChallenges);
|
|
||||||
availableChallengesFragment.setObservable(getUserChallengesObservable);
|
|
||||||
availableChallengesFragment.setViewUserChallengesOnly(false);
|
availableChallengesFragment.setViewUserChallengesOnly(false);
|
||||||
|
|
||||||
pageHistory = new Stack<>();
|
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
socialRepository.close();
|
challengeRepository.close();
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void subscribeGetChallenges() {
|
|
||||||
this.socialRepository.getUserChallenges()
|
|
||||||
.subscribe(challenges -> getUserChallengesObservable.onNext(challenges),
|
|
||||||
e -> getUserChallengesObservable.onError(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectFragment(AppComponent component) {
|
public void injectFragment(AppComponent component) {
|
||||||
component.inject(this);
|
component.inject(this);
|
||||||
|
|
@ -128,25 +101,6 @@ public class ChallengesOverviewFragment extends BaseMainFragment {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
viewPager.setAdapter(statePagerAdapter);
|
viewPager.setAdapter(statePagerAdapter);
|
||||||
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageSelected(int newPageId) {
|
|
||||||
if (saveToHistory)
|
|
||||||
pageHistory.push(currentPage);
|
|
||||||
|
|
||||||
currentPage = newPageId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageScrolled(int arg0, float arg1, int arg2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageScrollStateChanged(int arg0) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
saveToHistory = true;
|
|
||||||
|
|
||||||
if (tabLayout != null && viewPager != null) {
|
if (tabLayout != null && viewPager != null) {
|
||||||
tabLayout.setupWithViewPager(viewPager);
|
tabLayout.setupWithViewPager(viewPager);
|
||||||
|
|
@ -155,17 +109,10 @@ public class ChallengesOverviewFragment extends BaseMainFragment {
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onEvent(ShowChallengeDetailDialogCommand cmd) {
|
public void onEvent(ShowChallengeDetailDialogCommand cmd) {
|
||||||
socialRepository.getChallenge(cmd.challengeId).subscribe(challenge -> {
|
challengeRepository.getChallenge(cmd.challengeId).first().subscribe(challenge -> ChallengeDetailDialogHolder.showDialog(getActivity(), challengeRepository, challenge,
|
||||||
ChallengeDetailDialogHolder.showDialog(getActivity(), apiClient, user, challenge, challenge1 -> {
|
challenge1 -> {
|
||||||
// challenge joined
|
// challenge left
|
||||||
userChallengesFragment.addItem(challenge1);
|
}), ReactiveErrorHandler.handleEmptyError());
|
||||||
availableChallengesFragment.updateItem(challenge1);
|
|
||||||
}, challenge1 -> {
|
|
||||||
// challenge left
|
|
||||||
userChallengesFragment.onRefresh();
|
|
||||||
availableChallengesFragment.onRefresh();
|
|
||||||
});
|
|
||||||
}, ReactiveErrorHandler.handleEmptyError());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|
@ -179,18 +126,6 @@ public class ChallengesOverviewFragment extends BaseMainFragment {
|
||||||
getActivity().startActivity(intent);
|
getActivity().startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onHandleBackPressed() {
|
|
||||||
if (!pageHistory.empty()) {
|
|
||||||
saveToHistory = false;
|
|
||||||
viewPager.setCurrentItem(pageHistory.pop());
|
|
||||||
saveToHistory = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String customTitle() {
|
public String customTitle() {
|
||||||
return getString(R.string.challenges);
|
return getString(R.string.challenges);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.habitrpg.android.habitica.utils;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.realm.Realm;
|
||||||
|
import io.realm.RealmList;
|
||||||
|
|
||||||
|
public class ChallengeListDeserializer implements JsonDeserializer<List<Challenge>> {
|
||||||
|
@Override
|
||||||
|
public List<Challenge> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
RealmList<Challenge> challenges = new RealmList<>();
|
||||||
|
|
||||||
|
Realm realm = Realm.getDefaultInstance();
|
||||||
|
List<Challenge> existingChallenges = realm.copyFromRealm(realm.where(Challenge.class).findAll());
|
||||||
|
realm.close();
|
||||||
|
|
||||||
|
for (JsonElement element : json.getAsJsonArray()) {
|
||||||
|
Challenge challenge;
|
||||||
|
if (element.isJsonObject()) {
|
||||||
|
challenge = context.deserialize(element, Challenge.class);
|
||||||
|
Challenge existingChallenge = findExistingChallenge(existingChallenges, challenge.id);
|
||||||
|
if (existingChallenge != null) {
|
||||||
|
challenge.isParticipating = existingChallenge.isParticipating;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
challenge = findExistingChallenge(existingChallenges, element.getAsString());
|
||||||
|
if (challenge == null) {
|
||||||
|
challenge = new Challenge();
|
||||||
|
challenge.id = element.getAsString();
|
||||||
|
}
|
||||||
|
challenge.isParticipating = true;
|
||||||
|
}
|
||||||
|
challenges.add(challenge);
|
||||||
|
}
|
||||||
|
|
||||||
|
return challenges;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Challenge findExistingChallenge(List<Challenge> existingChallenges, String id) {
|
||||||
|
for (Challenge challenge : existingChallenges) {
|
||||||
|
if (id.equals(challenge.id)) {
|
||||||
|
return challenge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ import com.google.gson.JsonParseException;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.habitrpg.android.habitica.models.Tag;
|
import com.habitrpg.android.habitica.models.Tag;
|
||||||
import com.habitrpg.android.habitica.models.invitations.Invitations;
|
import com.habitrpg.android.habitica.models.invitations.Invitations;
|
||||||
|
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||||
import com.habitrpg.android.habitica.models.social.UserParty;
|
import com.habitrpg.android.habitica.models.social.UserParty;
|
||||||
import com.habitrpg.android.habitica.models.tasks.TasksOrder;
|
import com.habitrpg.android.habitica.models.tasks.TasksOrder;
|
||||||
import com.habitrpg.android.habitica.models.user.Authentication;
|
import com.habitrpg.android.habitica.models.user.Authentication;
|
||||||
|
|
@ -72,7 +73,7 @@ public class UserDeserializer implements JsonDeserializer<User> {
|
||||||
user.setTasksOrder(context.deserialize(obj.get("tasksOrder"), TasksOrder.class));
|
user.setTasksOrder(context.deserialize(obj.get("tasksOrder"), TasksOrder.class));
|
||||||
}
|
}
|
||||||
if (obj.has("challenges")) {
|
if (obj.has("challenges")) {
|
||||||
user.setChallenges(context.deserialize(obj.get("challenges"), new TypeToken<List<String>>() {
|
user.setChallenges(context.deserialize(obj.get("challenges"), new TypeToken<List<Challenge>>() {
|
||||||
}.getType()));
|
}.getType()));
|
||||||
}
|
}
|
||||||
if (obj.has("purchased")) {
|
if (obj.has("purchased")) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue