mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-20 04:39:04 +00:00
Merge branch 'develop' into add-repeatables
This commit is contained in:
commit
1ca55f4ea9
68 changed files with 1989 additions and 262 deletions
|
|
@ -2,7 +2,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.habitrpg.android.habitica"
|
||||
android:versionCode="179"
|
||||
android:versionCode="181"
|
||||
android:versionName="1.0.1"
|
||||
android:screenOrientation="portrait"
|
||||
android:installLocation="auto" >
|
||||
|
|
@ -141,6 +141,17 @@
|
|||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".ui.activities.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activities.CreateChallengeActivity"
|
||||
android:theme="@style/AppTheme.ActionBar"
|
||||
android:parentActivityName=".ui.activities.MainActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:launchMode="singleTask"
|
||||
tools:ignore="UnusedAttribute">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".ui.activities.MainActivity" />
|
||||
</activity>
|
||||
<activity android:name="com.facebook.FacebookActivity"
|
||||
android:configChanges=
|
||||
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
|
||||
|
|
|
|||
|
|
@ -117,13 +117,13 @@ dependencies {
|
|||
compile 'io.reactivex:rxjava:1.2.0'
|
||||
|
||||
//Analytics
|
||||
compile 'com.amplitude:android-sdk:2.13.1'
|
||||
compile 'com.amplitude:android-sdk:2.13.3'
|
||||
|
||||
// Fresco Image Management Library
|
||||
compile('com.facebook.fresco:fresco:1.0.1') {
|
||||
compile('com.facebook.fresco:fresco:1.3.0') {
|
||||
exclude module: 'bolts-android'
|
||||
}
|
||||
compile('com.facebook.fresco:animated-gif:1.0.1') {
|
||||
compile('com.facebook.fresco:animated-gif:1.3.0') {
|
||||
exclude module: 'bolts-android'
|
||||
}
|
||||
//Tests
|
||||
|
|
@ -162,6 +162,7 @@ android {
|
|||
defaultConfig {
|
||||
applicationId "com.habitrpg.android.habitica"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
buildConfigField "String", "STORE", "\"google\""
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
|
|
@ -198,6 +199,10 @@ android {
|
|||
|
||||
prod {
|
||||
}
|
||||
|
||||
amazon {
|
||||
buildConfigField "String", "STORE", "\"amazon\""
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
|
@ -294,7 +299,7 @@ if (HRPG_RES_FILE.canRead()) {
|
|||
}
|
||||
|
||||
tasks.whenTaskAdded { task ->
|
||||
if (task.name.equals("lint")) {
|
||||
if (task.name == "lint") {
|
||||
task.enabled = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate android:fromYDelta="100%" android:toYDelta="0%"/>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:duration="200">
|
||||
<translate
|
||||
android:fromYDelta="100%"
|
||||
android:toYDelta="0%"/>
|
||||
</set>
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate android:fromYDelta="0%" android:toYDelta="100%"/>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:duration="200">
|
||||
<translate android:fromYDelta="0%"
|
||||
android:toYDelta="100%"
|
||||
/>
|
||||
</set>
|
||||
4
Habitica/res/drawable-v21/ic_close_white_24dp.xml
Normal file
4
Habitica/res/drawable-v21/ic_close_white_24dp.xml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="24dp">
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
||||
5
Habitica/res/drawable/challenge_gem_add_button.xml
Normal file
5
Habitica/res/drawable/challenge_gem_add_button.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/challenge_gem_add_button_disabled" android:state_enabled="false"></item>
|
||||
<item android:drawable="@drawable/challenge_gem_add_button_enabled" android:state_enabled="true"></item>
|
||||
</selector>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item >
|
||||
<bitmap
|
||||
android:src="@drawable/plus"
|
||||
android:tint="#e1e0e3" />
|
||||
</item>
|
||||
</layer-list>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item >
|
||||
<bitmap
|
||||
android:src="@drawable/plus"
|
||||
android:tint="@color/brand_400" />
|
||||
</item>
|
||||
</layer-list>
|
||||
5
Habitica/res/drawable/challenge_gem_remove_button.xml
Normal file
5
Habitica/res/drawable/challenge_gem_remove_button.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/challenge_gem_remove_button_disabled" android:state_enabled="false"></item>
|
||||
<item android:drawable="@drawable/challenge_gem_remove_button_enabled" android:state_enabled="true"></item>
|
||||
</selector>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item >
|
||||
<bitmap
|
||||
android:src="@drawable/minus"
|
||||
android:tint="#e1e0e3" />
|
||||
</item>
|
||||
</layer-list>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item >
|
||||
<bitmap
|
||||
android:src="@drawable/minus"
|
||||
android:tint="@color/brand_400" />
|
||||
</item>
|
||||
</layer-list>
|
||||
4
Habitica/res/drawable/ic_close_white_24dp.xml
Normal file
4
Habitica/res/drawable/ic_close_white_24dp.xml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="24dp">
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
||||
4
Habitica/res/drawable/ic_info_outline_black_24dp.xml
Normal file
4
Habitica/res/drawable/ic_info_outline_black_24dp.xml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="24dp">
|
||||
<path android:fillColor="#000000" android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
|
||||
</vector>
|
||||
220
Habitica/res/layout/activity_create_challenge.xml
Normal file
220
Habitica/res/layout/activity_create_challenge.xml
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/activity_create_challenge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
|
||||
tools:context="com.habitrpg.android.habitica.ui.activities.CreateChallengeActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/brand_200"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="22dp">
|
||||
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColorHint="@color/brand_500"
|
||||
app:hintTextAppearance="@style/TextAppearance.AppCompat"
|
||||
android:id="@+id/create_challenge_title_input_layout">
|
||||
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
android:hint="@string/new_challenge_title"
|
||||
android:id="@+id/create_challenge_title"
|
||||
android:textColor="@color/white"
|
||||
android:textColorHighlight="@color/brand_500"
|
||||
android:textColorHint="@color/brand_500"
|
||||
|
||||
tools:text="Get in shape" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColorHint="@color/brand_500"
|
||||
|
||||
android:id="@+id/create_challenge_description_input_layout"
|
||||
app:hintTextAppearance="@style/TextAppearance.AppCompat">
|
||||
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/description_optional"
|
||||
android:inputType="textMultiLine"
|
||||
|
||||
android:id="@+id/create_challenge_description"
|
||||
android:maxLines="5"
|
||||
android:minLines="3"
|
||||
android:textColor="@color/white"
|
||||
android:textColorHighlight="@color/brand_500"
|
||||
android:textColorHint="@color/brand_500" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:background="@color/brand_700" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin">
|
||||
|
||||
<TextView
|
||||
style="@style/Subheader2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="23dp"
|
||||
android:text="@string/gem_reward"
|
||||
android:textColor="#cc000000" />
|
||||
|
||||
<TextView
|
||||
style="@style/Caption3"
|
||||
android:id="@+id/create_challenge_gem_error"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="23dp"
|
||||
android:text="@string/gem_reward"
|
||||
android:textColor="#f74e52"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="28dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/challenge_add_gem_btn"
|
||||
style="@style/Body1_Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:drawableLeft="@drawable/challenge_gem_add_button"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_header_gem" />
|
||||
|
||||
<EditText
|
||||
style="@style/Subheader2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:inputType="number"
|
||||
android:textColor="#8a000000"
|
||||
android:text="0"
|
||||
android:id="@+id/create_challenge_prize"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/challenge_remove_gem_btn"
|
||||
style="@style/Body1_Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:drawableRight="@drawable/challenge_gem_remove_button"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
style="@style/Subheader2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="26dp"
|
||||
android:text="@string/location"
|
||||
android:textColor="#cc000000" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/challenge_location_spinner"
|
||||
style="@android:style/Widget.Material.Spinner.Underlined"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#8a000000"
|
||||
android:layout_marginTop="17dp" />
|
||||
|
||||
<TextView
|
||||
style="@style/Subheader2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginTop="39dp"
|
||||
android:drawablePadding="12dp"
|
||||
android:drawableEnd="@drawable/ic_info_outline_black_24dp"
|
||||
android:drawableTint="@color/brand_300"
|
||||
android:gravity="center"
|
||||
android:text="Tag"
|
||||
android:textColor="#cc000000" />
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:id="@+id/create_challenge_tag_input_layout"
|
||||
app:hintTextAppearance="@style/TextAppearance.AppCompat">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/create_challenge_tag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:hint="@string/identify_your_challenge_with_a_tag"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/white"
|
||||
android:textColorHint="#61000000" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<TextView
|
||||
style="@style/Subheader2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/tasks" />
|
||||
|
||||
<TextView
|
||||
style="@style/Caption3"
|
||||
android:id="@+id/create_challenge_task_error"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="23dp"
|
||||
android:textColor="#f74e52"
|
||||
android:text="@string/challenge_create_error_no_tasks"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:nestedScrollingEnabled="false"
|
||||
android:id="@+id/create_challenge_task_list">
|
||||
|
||||
</android.support.v7.widget.RecyclerView>
|
||||
</LinearLayout>
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
28
Habitica/res/layout/challenge_add_task_item.xml
Normal file
28
Habitica/res/layout/challenge_add_task_item.xml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#FFF"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
|
||||
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="22dp"
|
||||
android:layout_marginBottom="18dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:textAllCaps="false"
|
||||
style="@style/Subheader2"
|
||||
android:textColor="@color/brand_400"
|
||||
android:background="#f9f9f9"
|
||||
android:id="@+id/btn_add_task"
|
||||
tools:text="Add habit">
|
||||
|
||||
</Button>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -1,24 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
>
|
||||
android:gravity="center_horizontal">
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:id="@+id/imageView" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:text=""
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/imageView"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="50dp"
|
||||
android:layout_marginLeft="25dp"
|
||||
android:layout_marginRight="25dp"
|
||||
|
|
@ -28,8 +23,6 @@
|
|||
android:text=""
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/you_earned_message"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="50dp"
|
||||
android:id="@+id/next_unlock_message" />
|
||||
|
||||
|
|
@ -37,10 +30,8 @@
|
|||
android:text="@string/see_you_tomorrow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/next_unlock_message"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="50dp"
|
||||
android:id="@+id/confirm_button"
|
||||
style="@style/Widget.AppCompat.Button.Borderless.Colored" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
|
@ -18,7 +18,9 @@
|
|||
fab:menu_animationDelayPerItem="50"
|
||||
fab:menu_icon="@drawable/fab_add"
|
||||
fab:menu_buttonSpacing="2dp"
|
||||
fab:menu_labels_margin="4dp">
|
||||
fab:menu_labels_margin="4dp"
|
||||
fab:menu_fab_show_animation="@anim/fab_slide_in"
|
||||
fab:menu_fab_hide_animation="@anim/fab_slide_out">
|
||||
|
||||
<com.github.clans.fab.FloatingActionButton
|
||||
android:id="@+id/fab.new.habit"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -42,6 +42,7 @@
|
|||
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">
|
||||
|
||||
|
|
@ -54,62 +55,65 @@
|
|||
android:scrollbars="vertical"
|
||||
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.support.v4.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/challenges.list.empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false">
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="48dp"
|
||||
android:layout_marginRight="48dp"
|
||||
android:layout_marginTop="65dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/challenges.list.empty"
|
||||
<TextView
|
||||
style="@style/Headline"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="48dp"
|
||||
android:layout_marginRight="48dp"
|
||||
android:layout_marginTop="65dp"
|
||||
android:orientation="vertical">
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:text="@string/not_part_of_a_challenge"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#8a000000" />
|
||||
|
||||
<TextView
|
||||
style="@style/Headline"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:text="@string/not_part_of_a_challenge"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#8a000000" />
|
||||
<TextView
|
||||
style="@style/Body2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="22dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/join_a_challenge"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#66000000" />
|
||||
|
||||
<TextView
|
||||
style="@style/Body2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="22dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/join_a_challenge"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#66000000" />
|
||||
<TextView
|
||||
android:id="@+id/textView5"
|
||||
style="@style/Body2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="22dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/check_the_public_challenge_tab"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#66000000" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView5"
|
||||
style="@style/Body2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="22dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/check_the_public_challenge_tab"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#66000000" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -24,7 +24,25 @@
|
|||
android:drawableTop="@drawable/ic_heart_large"
|
||||
android:textSize="14sp"
|
||||
android:lineSpacingExtra="4dp" />
|
||||
<TextView
|
||||
android:id="@+id/notAvailableTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/no_billing_gems"
|
||||
android:paddingTop="50dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:visibility="gone" />
|
||||
<Button
|
||||
android:id="@+id/notAvailableButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/visit_habitica_website"
|
||||
android:layout_marginBottom="50dp"
|
||||
style="@style/Button.Purple"
|
||||
android:visibility="gone" />
|
||||
<LinearLayout
|
||||
android:id="@+id/gemPurchaseOptions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
|
|
|||
|
|
@ -150,6 +150,25 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:id="@+id/loadingIndicator"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notAvailableTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/no_billing_subscriptions"
|
||||
android:paddingTop="50dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:visibility="gone" />
|
||||
<Button
|
||||
android:id="@+id/notAvailableButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/visit_habitica_website"
|
||||
android:layout_marginBottom="50dp"
|
||||
style="@style/Button.Purple"
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/subscriptionOptions"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -5,9 +5,15 @@
|
|||
|
||||
<item
|
||||
android:id="@+id/action_leave"
|
||||
android:actionViewClass="android.widget.ImageButton"
|
||||
android:icon="@drawable/leave_light"
|
||||
android:title="@string/leave"
|
||||
app:showAsAction="always"
|
||||
android:actionViewClass="android.widget.ImageButton"/>
|
||||
app:showAsAction="always" />
|
||||
|
||||
<group
|
||||
android:id="@+id/challenge_edit_action_group">
|
||||
<item
|
||||
android:id="@+id/action_edit"
|
||||
android:title="@string/edit_challenge" />
|
||||
</group>
|
||||
</menu>
|
||||
|
|
|
|||
11
Habitica/res/menu/menu_create_challenge.xml
Normal file
11
Habitica/res/menu/menu_create_challenge.xml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="com.habitrpg.android.habitica.TaskActivity">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_save"
|
||||
android:title="@string/save"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
</menu>
|
||||
10
Habitica/res/menu/menu_list_challenges.xml
Normal file
10
Habitica/res/menu/menu_list_challenges.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="com.habitrpg.android.habitica.TaskActivity">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_create_challenge"
|
||||
android:title="@string/create_challenge"/>
|
||||
|
||||
</menu>
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
<string name="tutorial_dailies_1">Создайте ежедневные задачи, которые необходимо выполнять по расписанию.</string>
|
||||
<string name="tutorial_dailies_2">Будьте осторожны - если вы пропустите раз, ваш аватар в одночасье получит урон . Регулярно выполняя их, вы получите отличные награды!</string>
|
||||
<string name="tutorial_todos_1">Используйте список дел, чтобы отслеживать задачи, которые нужно выполнять только один раз.</string>
|
||||
<string name="tutorial_todos_2">Если ваше задание должно быть выполнено к определенному времени, установите срок. Похоже, вы можете выполнить одно - идти впереди!</string>
|
||||
<string name="tutorial_rewards_1">Покупайте снаряжение для вашего аватара за золото которое вы получаете!</string>
|
||||
<string name="tutorial_rewards_2">Вы также можете создавать свои вознаграждения в зависимости от того, что вас мотивирует.</string>
|
||||
<string name="tutorial_tasks_complete">На этом все. Если вы что-то забыли, проверьте раздел часто задаваемых вопросов.</string>
|
||||
|
|
|
|||
|
|
@ -186,6 +186,8 @@
|
|||
<string name="intro_1_description">Пришло время веселиться, пока вы делаете свою работу. Присоединитесь к %s участникам, уже улучшающих свою жизнь.</string>
|
||||
<string name="intro_2_subtitle">Прогресс в игре</string>
|
||||
<string name="intro_2_title">Прогресс в жизни</string>
|
||||
<string name="intro_3_subtitle">Битва с монстрами</string>
|
||||
<string name="intro_3_title">Общайтесь</string>
|
||||
<string name="intro_3_description">Добивайтесь поставленнх целей с помощью друзей. Поддерживайте друг друга в реальной жизни и в сражении, делая свою жизнь лучше!</string>
|
||||
<string name="intro_finish_button">Давайте начнем!</string>
|
||||
<string name="previous_button">Назад</string>
|
||||
|
|
@ -237,6 +239,7 @@
|
|||
<string name="delete">Удалить</string>
|
||||
<string name="name">Имя</string>
|
||||
<string name="description">Описание</string>
|
||||
<string name="add_tag">Добавить новый Тег</string>
|
||||
<string name="privacy">Приватность</string>
|
||||
<string name="write_message">Написать сообщение</string>
|
||||
<string name="post">Отправить</string>
|
||||
|
|
@ -393,6 +396,7 @@
|
|||
<string name="all_dailies_completed">Вы справились со всеми ежедневными заданиями. Так держать!</string>
|
||||
<string name="widget_habit_button">Привычки Habitica</string>
|
||||
<string name="widget_dailies">Ежедневные задания Habitica</string>
|
||||
<string name="widget_todo_list">Список задач Habitica</string>
|
||||
<string name="widget_add_task">Добавить задачу Habitica</string>
|
||||
<string name="google_services_missing">Сервис Google play не найден.</string>
|
||||
<string name="gem.purchase.toolbartitle">Купить</string>
|
||||
|
|
@ -497,6 +501,7 @@
|
|||
<string name="login_btn_fb">Зарегистрироваться с Facebook</string>
|
||||
<string name="login_btn_google">Зарегистрироваться с Google</string>
|
||||
<string name="action_back">Назад</string>
|
||||
<string name="welcome_text">О, должно быть ,вы новичок. Я Джастин, я буду твоим проводником в Habitica. \ N \ nЧтобы начать, вам нужно создать аватар.</string>
|
||||
<string name="avatar_extras">Дополнительно</string>
|
||||
<string name="avatar_skin_color">Цвет кожи</string>
|
||||
<string name="avatar_hair_color">Цвет волос</string>
|
||||
|
|
@ -506,11 +511,13 @@
|
|||
<string name="avatar_wheelchair">Кресло-каталка</string>
|
||||
<string name="weak">Стройное</string>
|
||||
<string name="strong">Тучное</string>
|
||||
<string name="gray">Серый</string>
|
||||
<string name="completed">Завершить</string>
|
||||
<string name="setuP_group_other">Другое</string>
|
||||
<string name="clear">Очистить</string>
|
||||
<string name="empty_title_habits">У вас нет привычек</string>
|
||||
<string name="empty_title_todos">У вас нет задач</string>
|
||||
<string name="empty_title_rewards">У вас нет вознаграждений</string>
|
||||
<string name="maintenance">Cодержание</string>
|
||||
<string name="reload_content">Обновить содержимое</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -582,4 +582,21 @@
|
|||
<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="repeat_summary">"Repeats %1$s every %2$s %3$s %4$s"</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="save">Save</string>
|
||||
<string name="location">Location</string>
|
||||
<string name="gem_reward">Gem reward</string>
|
||||
<string name="tasks">Tasks</string>
|
||||
<string name="create_challenge">Create 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_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="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_title">You need a title to create this Challenge.</string>
|
||||
<string name="description_optional">Description (optional)</string>
|
||||
<string name="new_challenge_title">New challenge title</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import android.support.multidex.MultiDexApplication;
|
|||
import android.util.Log;
|
||||
|
||||
import com.amplitude.api.Amplitude;
|
||||
import com.amplitude.api.Identify;
|
||||
import com.facebook.FacebookSdk;
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
|
|
@ -140,6 +141,8 @@ public abstract class HabiticaBaseApplication extends MultiDexApplication {
|
|||
if (!BuildConfig.DEBUG) {
|
||||
try {
|
||||
Amplitude.getInstance().initialize(this, getString(R.string.amplitude_app_id)).enableForegroundTracking(this);
|
||||
Identify identify = new Identify().setOnce("androidStore", BuildConfig.STORE);
|
||||
Amplitude.getInstance().identify(identify);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
//pass
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,6 +287,22 @@ public interface ApiService {
|
|||
@POST("challenges/{challengeId}/leave")
|
||||
Observable<HabitResponse<Void>> leaveChallenge(@Path("challengeId") String challengeId, @Body LeaveChallengeBody body);
|
||||
|
||||
@POST("challenges")
|
||||
Observable<HabitResponse<Challenge>> createChallenge(@Body Challenge challenge);
|
||||
|
||||
@POST("tasks/challenge/{challengeId}")
|
||||
Observable<HabitResponse<Task>> createChallengeTask(@Path("challengeId") String challengeId, @Body Task task);
|
||||
|
||||
@POST("tasks/challenge/{challengeId}")
|
||||
Observable<HabitResponse<List<Task>>> createChallengeTasks(@Path("challengeId") String challengeId, @Body List<Task> tasks);
|
||||
|
||||
@PUT("challenges/{challengeId}")
|
||||
Observable<HabitResponse<Challenge>> updateChallenge(@Path("challengeId") String challengeId, @Body Challenge challenge);
|
||||
|
||||
@DELETE("challenges/{challengeId}")
|
||||
Observable<HabitResponse<Void>> deleteChallenge(@Path("challengeId") String challengeId);
|
||||
|
||||
|
||||
//DEBUG: These calls only work on a local development server
|
||||
|
||||
@POST("debug/add-ten-gems")
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver;
|
|||
import com.habitrpg.android.habitica.ui.activities.AboutActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.ChallengeDetailActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.ClassSelectionActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.CreateChallengeActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.FullProfileActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.GemPurchaseActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.GroupFormActivity;
|
||||
|
|
@ -33,6 +34,7 @@ import com.habitrpg.android.habitica.ui.activities.SetupActivity;
|
|||
import com.habitrpg.android.habitica.ui.activities.SkillMemberActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.SkillTasksActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.TaskFormActivity;
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.challenges.ChallengeTasksRecyclerViewAdapter;
|
||||
import com.habitrpg.android.habitica.ui.adapter.tasks.DailiesRecyclerViewHolder;
|
||||
import com.habitrpg.android.habitica.ui.adapter.tasks.HabitsRecyclerViewAdapter;
|
||||
import com.habitrpg.android.habitica.ui.adapter.tasks.RewardsRecyclerViewAdapter;
|
||||
|
|
@ -231,7 +233,7 @@ public interface AppComponent {
|
|||
|
||||
void inject(SubscriptionFragment subscriptionFragment);
|
||||
|
||||
void inject(ChallengeTasksRecyclerViewFragment.ChallengeTasksRecyclerViewAdapter challengeTasksRecyclerViewAdapter);
|
||||
void inject(ChallengeTasksRecyclerViewAdapter challengeTasksRecyclerViewAdapter);
|
||||
|
||||
void inject(ChallengeTasksRecyclerViewFragment challengeTasksRecyclerViewFragment);
|
||||
|
||||
|
|
@ -248,4 +250,6 @@ public interface AppComponent {
|
|||
void inject(HabiticaFirebaseInstanceIDService habiticaFirebaseInstanceIDService);
|
||||
|
||||
void inject(HabiticaFirebaseMessagingService habiticaFirebaseMessagingService);
|
||||
|
||||
void inject(CreateChallengeActivity createChallengeActivity);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,6 +200,13 @@ public interface ApiClient {
|
|||
|
||||
Observable<Void> leaveChallenge(String challengeId, LeaveChallengeBody body);
|
||||
|
||||
Observable<Challenge> createChallenge(Challenge challenge);
|
||||
|
||||
Observable<Task> createChallengeTask(String challengeId, Task task);
|
||||
Observable<List<Task>> createChallengeTasks(String challengeId, List<Task> tasks);
|
||||
Observable<Challenge> updateChallenge(Challenge challenge);
|
||||
Observable<Void> deleteChallenge(String challengeId);
|
||||
|
||||
//DEBUG: These calls only work on a local development server
|
||||
|
||||
Observable<Void> debugAddTenGems();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
package com.habitrpg.android.habitica.data;
|
||||
|
||||
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.TaskList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import rx.Observable;
|
||||
|
||||
public interface ChallengeRepository extends BaseRepository {
|
||||
Observable<Challenge> getChallenge(String challengeId);
|
||||
Observable<TaskList> getChallengeTasks(String challengeId);
|
||||
|
||||
Observable<Challenge> createChallenge(Challenge challenge, List<Task> taskList);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param challenge
|
||||
* @param fullTaskList lists all tasks of the current challenge, to create the taskOrders
|
||||
* @param addedTaskList only the tasks to be added online
|
||||
* @param updatedTaskList only the updated ones
|
||||
* @param removedTaskList tasks that has be to be removed
|
||||
* @return
|
||||
*/
|
||||
Observable<Challenge> updateChallenge(Challenge challenge, List<Task> fullTaskList,
|
||||
List<Task> addedTaskList, List<Task> updatedTaskList, List<String> removedTaskList);
|
||||
Observable<Void> deleteChallenge(String challengeId);
|
||||
|
||||
void setUsersGroups(List<Group> groups);
|
||||
|
||||
Observable<List<Group>> getLocalGroups();
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ import com.habitrpg.android.habitica.models.tasks.Task;
|
|||
import com.habitrpg.android.habitica.models.tasks.TaskList;
|
||||
import com.habitrpg.android.habitica.models.tasks.TaskTag;
|
||||
import com.habitrpg.android.habitica.utils.BooleanAsIntAdapter;
|
||||
import com.habitrpg.android.habitica.utils.ChallengeDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.ChallengeSerializer;
|
||||
import com.habitrpg.android.habitica.utils.ChatMessageDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.ChecklistItemSerializer;
|
||||
import com.habitrpg.android.habitica.utils.ContentDeserializer;
|
||||
|
|
@ -267,7 +267,7 @@ public class ApiClientImpl implements Action1<Throwable>, ApiClient {
|
|||
.registerTypeAdapter(Task.class, new TaskSerializer())
|
||||
.registerTypeAdapter(ContentResult.class, new ContentDeserializer())
|
||||
.registerTypeAdapter(FeedResponse.class, new FeedResponseDeserializer())
|
||||
.registerTypeAdapter(Challenge.class, new ChallengeDeserializer())
|
||||
.registerTypeAdapter(Challenge.class, new ChallengeSerializer())
|
||||
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||
.create();
|
||||
return GsonConverterFactory.create(gson);
|
||||
|
|
@ -826,6 +826,32 @@ public class ApiClientImpl implements Action1<Throwable>, ApiClient {
|
|||
return apiService.leaveChallenge(challengeId, body).compose(configureApiCallObserver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Challenge> createChallenge(Challenge challenge) {
|
||||
return apiService.createChallenge(challenge).compose(configureApiCallObserver());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Observable<Task> createChallengeTask(String challengeId, Task task) {
|
||||
return apiService.createChallengeTask(challengeId, task).compose(configureApiCallObserver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<List<Task>> createChallengeTasks(String challengeId, List<Task> tasks) {
|
||||
return apiService.createChallengeTasks(challengeId, tasks).compose(configureApiCallObserver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Challenge> updateChallenge(Challenge challenge) {
|
||||
return apiService.updateChallenge(challenge.id, challenge).compose(configureApiCallObserver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Void> deleteChallenge(String challengeId) {
|
||||
return apiService.deleteChallenge(challengeId).compose(configureApiCallObserver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Void> debugAddTenGems() {
|
||||
return apiService.debugAddTenGems().compose(configureApiCallObserver());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,121 @@
|
|||
package com.habitrpg.android.habitica.data.implementation;
|
||||
|
||||
import com.github.underscore.$;
|
||||
import com.habitrpg.android.habitica.data.ApiClient;
|
||||
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||
import com.habitrpg.android.habitica.data.local.ChallengeLocalRepository;
|
||||
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.TaskList;
|
||||
import com.habitrpg.android.habitica.models.tasks.TasksOrder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import rx.Observable;
|
||||
import rx.schedulers.Schedulers;
|
||||
|
||||
|
||||
public class ChallengeRepositoryImpl extends BaseRepositoryImpl<ChallengeLocalRepository> implements ChallengeRepository {
|
||||
|
||||
public ChallengeRepositoryImpl(ChallengeLocalRepository localRepository, ApiClient apiClient) {
|
||||
super(localRepository, apiClient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Challenge> getChallenge(String challengeId) {
|
||||
return apiClient.getChallenge(challengeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<TaskList> getChallengeTasks(String challengeId) {
|
||||
return apiClient.getChallengeTasks(challengeId);
|
||||
}
|
||||
|
||||
|
||||
private TasksOrder getTaskOrders(List<Task> taskList) {
|
||||
Map<String, List<Task>> stringListMap = $.groupBy(taskList, t -> t.getType());
|
||||
|
||||
TasksOrder tasksOrder = new TasksOrder();
|
||||
|
||||
for (Map.Entry<String, List<Task>> entry : stringListMap.entrySet()) {
|
||||
List<String> taskIdList = $.map(entry.getValue(), t -> t.getId());
|
||||
|
||||
switch (entry.getKey()) {
|
||||
case Task.TYPE_HABIT:
|
||||
tasksOrder.setHabits(taskIdList);
|
||||
break;
|
||||
case Task.TYPE_DAILY:
|
||||
tasksOrder.setDailys(taskIdList);
|
||||
break;
|
||||
case Task.TYPE_TODO:
|
||||
tasksOrder.setTodos(taskIdList);
|
||||
break;
|
||||
case Task.TYPE_REWARD:
|
||||
tasksOrder.setRewards(taskIdList);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return tasksOrder;
|
||||
}
|
||||
|
||||
private Observable addChallengeTasks(String challengeId, List<Task> addedTaskList) {
|
||||
if (addedTaskList.size() == 1) {
|
||||
return apiClient.createChallengeTask(challengeId, addedTaskList.get(0));
|
||||
} else {
|
||||
return apiClient.createChallengeTasks(challengeId, addedTaskList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Challenge> createChallenge(Challenge challenge, List<Task> taskList) {
|
||||
challenge.tasksOrder = getTaskOrders(taskList);
|
||||
|
||||
return Observable.create(subscriber -> {
|
||||
apiClient.createChallenge(challenge).subscribe(challenge1 -> {
|
||||
addChallengeTasks(challenge1.id, taskList).subscribe(task -> {
|
||||
subscriber.onNext(challenge1);
|
||||
subscriber.onCompleted();
|
||||
}, throwable -> subscriber.onError((Throwable) throwable));
|
||||
|
||||
}, throwable -> subscriber.onError(throwable));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Challenge> updateChallenge(Challenge challenge, List<Task> fullTaskList,
|
||||
List<Task> addedTaskList, List<Task> updatedTaskList, List<String> removedTaskList) {
|
||||
|
||||
ArrayList<Observable> observablesToWait = new ArrayList<>($.map(updatedTaskList, t -> apiClient.updateTask(t.getId(), t)));
|
||||
observablesToWait.addAll($.map(removedTaskList, apiClient::deleteTask));
|
||||
|
||||
if (addedTaskList.size() != 0) {
|
||||
observablesToWait.add(addChallengeTasks(challenge.id, addedTaskList));
|
||||
}
|
||||
|
||||
challenge.tasksOrder = getTaskOrders(fullTaskList);
|
||||
|
||||
return Observable.from(observablesToWait)
|
||||
.flatMap(task -> task.subscribeOn(Schedulers.computation()))
|
||||
.toList()
|
||||
.flatMap(tasks -> apiClient.updateChallenge(challenge));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Void> deleteChallenge(String challengeId) {
|
||||
return apiClient.deleteChallenge(challengeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUsersGroups(List<Group> groups) {
|
||||
localRepository.setUsersGroups(groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<List<Group>> getLocalGroups() {
|
||||
return localRepository.getGroups();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.habitrpg.android.habitica.data.local;
|
||||
|
||||
|
||||
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 java.util.List;
|
||||
|
||||
import rx.Observable;
|
||||
|
||||
public interface ChallengeLocalRepository extends BaseLocalRepository {
|
||||
Observable<Challenge> getChallenge(String id);
|
||||
Observable<List<Task>> getTasks(Challenge challenge);
|
||||
|
||||
void setUsersGroups(List<Group> group);
|
||||
|
||||
Observable<List<Group>> getGroups();
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.habitrpg.android.habitica.data.local.implementation;
|
||||
|
||||
import com.habitrpg.android.habitica.data.local.ChallengeLocalRepository;
|
||||
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.raizlabs.android.dbflow.runtime.transaction.BaseTransaction;
|
||||
import com.raizlabs.android.dbflow.runtime.transaction.TransactionListener;
|
||||
import com.raizlabs.android.dbflow.sql.builder.Condition;
|
||||
import com.raizlabs.android.dbflow.sql.language.Delete;
|
||||
import com.raizlabs.android.dbflow.sql.language.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import rx.Observable;
|
||||
|
||||
public class DbFlowChallengeLocalRepository implements ChallengeLocalRepository {
|
||||
|
||||
@Override
|
||||
public Observable<Challenge> getChallenge(String id) {
|
||||
return Observable.defer(() -> Observable.just(new Select().from(Challenge.class).where(Condition.column("id").is(id)).querySingle()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<List<Task>> getTasks(Challenge challenge) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUsersGroups(List<Group> groups) {
|
||||
|
||||
new Delete().from(Group.class).query();
|
||||
|
||||
|
||||
for (Group group : groups) {
|
||||
group.isMember = true;
|
||||
group.async().save();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<List<Group>> getGroups() {
|
||||
return Observable.defer(() -> Observable.just(new Select().from(Group.class).where(Condition.column("isMember").is(true)).queryList()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -8,5 +8,5 @@ import com.habitrpg.android.habitica.models.tasks.Task;
|
|||
public class TaskSaveEvent {
|
||||
public Task task;
|
||||
public boolean created;
|
||||
|
||||
public boolean ignoreEvent;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,14 @@ package com.habitrpg.android.habitica.events.commands;
|
|||
*/
|
||||
public class DeleteTaskCommand {
|
||||
public String TaskIdToDelete;
|
||||
public boolean ignoreEvent;
|
||||
|
||||
public DeleteTaskCommand(String id) {
|
||||
this(id, false);
|
||||
}
|
||||
|
||||
public DeleteTaskCommand(String id, boolean ignore) {
|
||||
TaskIdToDelete = id;
|
||||
ignoreEvent = ignore;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.habitrpg.android.habitica.helpers;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
|
@ -70,15 +71,18 @@ public class PopupNotificationsManager {
|
|||
DataBindingUtils.loadImage(imageView, imageKey);
|
||||
|
||||
TextView youEarnedTexView = (TextView) view.findViewById(R.id.you_earned_message);
|
||||
youEarnedTexView.setTextColor(ContextCompat.getColor(context, R.color.textColorLight));
|
||||
youEarnedTexView.setText(youEarnedMessage);
|
||||
|
||||
String message = context.getString(R.string.nextPrizeUnlocks, notification.data.nextRewardAt);
|
||||
TextView nextUnlockTextView = (TextView) view.findViewById(R.id.next_unlock_message);
|
||||
nextUnlockTextView.setTextColor(ContextCompat.getColor(context, R.color.textColorLight));
|
||||
nextUnlockTextView.setText(message);
|
||||
|
||||
Button confirmButton = (Button) view.findViewById(R.id.confirm_button);
|
||||
confirmButton.setTextColor(ContextCompat.getColor(context, R.color.brand_300));
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(HabiticaApplication.currentActivity)
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(HabiticaApplication.currentActivity, R.style.AlertDialogTheme)
|
||||
.setTitle(title)
|
||||
.setView(view)
|
||||
.setMessage("");
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ public class ShopItem {
|
|||
if (getCurrency().equals("gold")) {
|
||||
return getValue() <= user.getStats().getGp();
|
||||
} else if (getCurrency().equals("gems")) {
|
||||
return getValue() <= (user.getBalance() * 4);
|
||||
return getValue() <= (user.getGemCount());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.habitrpg.android.habitica.models.social;
|
||||
|
||||
import com.habitrpg.android.habitica.HabitDatabase;
|
||||
import com.habitrpg.android.habitica.models.social.Group;
|
||||
import com.habitrpg.android.habitica.models.tasks.TasksOrder;
|
||||
import com.habitrpg.android.habitica.models.user.HabitRPGUser;
|
||||
import com.raizlabs.android.dbflow.annotation.Column;
|
||||
import com.raizlabs.android.dbflow.annotation.NotNull;
|
||||
|
|
@ -9,8 +9,6 @@ import com.raizlabs.android.dbflow.annotation.PrimaryKey;
|
|||
import com.raizlabs.android.dbflow.annotation.Table;
|
||||
import com.raizlabs.android.dbflow.structure.BaseModel;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@Table(databaseName = HabitDatabase.NAME)
|
||||
public class Challenge extends BaseModel {
|
||||
|
||||
|
|
@ -73,25 +71,5 @@ public class Challenge extends BaseModel {
|
|||
|
||||
public HabitRPGUser leader;
|
||||
|
||||
public HashMap<String, String[]> getTasksOrder() {
|
||||
HashMap<String, String[]> map = new HashMap();
|
||||
|
||||
if (!dailyList.isEmpty()) {
|
||||
map.put(TASK_ORDER_DAILYS, dailyList.split(","));
|
||||
}
|
||||
|
||||
if (!habitList.isEmpty()) {
|
||||
map.put(TASK_ORDER_HABITS, habitList.split(","));
|
||||
}
|
||||
|
||||
if (!rewardList.isEmpty()) {
|
||||
map.put(TASK_ORDER_REWARDS, rewardList.split(","));
|
||||
}
|
||||
|
||||
if (!todoList.isEmpty()) {
|
||||
map.put(TASK_ORDER_TODOS, todoList.split(","));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
public TasksOrder tasksOrder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,51 +4,66 @@ import com.google.gson.annotations.SerializedName;
|
|||
|
||||
import com.habitrpg.android.habitica.models.user.HabitRPGUser;
|
||||
import com.habitrpg.android.habitica.models.inventory.Quest;
|
||||
import com.habitrpg.android.habitica.HabitDatabase;
|
||||
import com.raizlabs.android.dbflow.annotation.Column;
|
||||
import com.raizlabs.android.dbflow.annotation.NotNull;
|
||||
import com.raizlabs.android.dbflow.annotation.PrimaryKey;
|
||||
import com.raizlabs.android.dbflow.annotation.Table;
|
||||
import com.raizlabs.android.dbflow.structure.BaseModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Negue on 16.09.2015.
|
||||
*/
|
||||
@Table(databaseName = HabitDatabase.NAME, tableName = "_group")
|
||||
public class Group extends BaseModel {
|
||||
|
||||
@Column
|
||||
@PrimaryKey
|
||||
@NotNull
|
||||
@SerializedName("_id")
|
||||
public String id;
|
||||
|
||||
@Column
|
||||
public double balance;
|
||||
|
||||
@Column
|
||||
public String description;
|
||||
|
||||
@Column
|
||||
public String leaderID;
|
||||
|
||||
@Column
|
||||
public String leaderName;
|
||||
|
||||
@Column
|
||||
public String name;
|
||||
|
||||
@Column
|
||||
public int memberCount;
|
||||
|
||||
@Column
|
||||
public Boolean isMember;
|
||||
|
||||
@Column
|
||||
public String type;
|
||||
|
||||
@Column
|
||||
public String logo;
|
||||
|
||||
public Quest quest;
|
||||
|
||||
public String privacy;
|
||||
|
||||
|
||||
public List<ChatMessage> chat;
|
||||
|
||||
public List<HabitRPGUser> members;
|
||||
|
||||
@Column
|
||||
public int challengeCount;
|
||||
|
||||
@Column
|
||||
public String leaderMessage;
|
||||
|
||||
// TODO Challenges
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package com.habitrpg.android.habitica.models.tasks;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.habitrpg.android.habitica.HabitDatabase;
|
||||
import com.raizlabs.android.dbflow.annotation.Column;
|
||||
import com.raizlabs.android.dbflow.annotation.ModelContainer;
|
||||
|
|
@ -13,7 +16,7 @@ import com.raizlabs.android.dbflow.structure.BaseModel;
|
|||
*/
|
||||
@ModelContainer
|
||||
@Table(databaseName = HabitDatabase.NAME)
|
||||
public class Days extends BaseModel {
|
||||
public class Days extends BaseModel implements Parcelable {
|
||||
|
||||
@Column
|
||||
@PrimaryKey
|
||||
|
|
@ -108,4 +111,44 @@ public class Days extends BaseModel {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.task_id);
|
||||
dest.writeByte(this.m ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.t ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.w ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.th ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.f ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.s ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.su ? (byte) 1 : (byte) 0);
|
||||
}
|
||||
|
||||
protected Days(Parcel in) {
|
||||
this.task_id = in.readString();
|
||||
this.m = in.readByte() != 0;
|
||||
this.t = in.readByte() != 0;
|
||||
this.w = in.readByte() != 0;
|
||||
this.th = in.readByte() != 0;
|
||||
this.f = in.readByte() != 0;
|
||||
this.s = in.readByte() != 0;
|
||||
this.su = in.readByte() != 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<Days> CREATOR = new Parcelable.Creator<Days>() {
|
||||
@Override
|
||||
public Days createFromParcel(Parcel source) {
|
||||
return new Days(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Days[] newArray(int size) {
|
||||
return new Days[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import com.raizlabs.android.dbflow.structure.BaseModel;
|
|||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -34,7 +36,7 @@ import java.util.concurrent.TimeUnit;
|
|||
*/
|
||||
@ModelContainer
|
||||
@Table(databaseName = HabitDatabase.NAME)
|
||||
public class Task extends BaseModel {
|
||||
public class Task extends BaseModel implements Parcelable {
|
||||
public static final String TYPE_HABIT = "habit";
|
||||
public static final String TYPE_TODO = "todo";
|
||||
public static final String TYPE_DAILY = "daily";
|
||||
|
|
@ -697,4 +699,83 @@ public class Task extends BaseModel {
|
|||
this.parsedNotes = this.getNotes();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.user_id);
|
||||
dest.writeValue(this.priority);
|
||||
dest.writeString(this.text);
|
||||
dest.writeString(this.notes);
|
||||
dest.writeString(this.attribute);
|
||||
dest.writeString(this.type);
|
||||
dest.writeDouble(this.value);
|
||||
dest.writeList(this.tags);
|
||||
dest.writeLong(this.dateCreated != null ? this.dateCreated.getTime() : -1);
|
||||
dest.writeInt(this.position);
|
||||
dest.writeValue(this.up);
|
||||
dest.writeValue(this.down);
|
||||
dest.writeByte(this.completed ? (byte) 1 : (byte) 0);
|
||||
dest.writeList(this.checklist);
|
||||
dest.writeList(this.reminders);
|
||||
dest.writeString(this.frequency);
|
||||
dest.writeValue(this.everyX);
|
||||
dest.writeValue(this.streak);
|
||||
dest.writeLong(this.startDate != null ? this.startDate.getTime() : -1);
|
||||
dest.writeParcelable(this.repeat, flags);
|
||||
dest.writeLong(this.duedate != null ? this.duedate.getTime() : -1);
|
||||
dest.writeString(this.specialTag);
|
||||
dest.writeString(this.id);
|
||||
}
|
||||
|
||||
public Task() {
|
||||
}
|
||||
|
||||
protected Task(Parcel in) {
|
||||
this.user_id = in.readString();
|
||||
this.priority = (Float) in.readValue(Float.class.getClassLoader());
|
||||
this.text = in.readString();
|
||||
this.notes = in.readString();
|
||||
this.attribute = in.readString();
|
||||
this.type = in.readString();
|
||||
this.value = in.readDouble();
|
||||
this.tags = new ArrayList<TaskTag>();
|
||||
in.readList(this.tags, TaskTag.class.getClassLoader());
|
||||
long tmpDateCreated = in.readLong();
|
||||
this.dateCreated = tmpDateCreated == -1 ? null : new Date(tmpDateCreated);
|
||||
this.position = in.readInt();
|
||||
this.up = (Boolean) in.readValue(Boolean.class.getClassLoader());
|
||||
this.down = (Boolean) in.readValue(Boolean.class.getClassLoader());
|
||||
this.completed = in.readByte() != 0;
|
||||
this.checklist = new ArrayList<ChecklistItem>();
|
||||
in.readList(this.checklist, ChecklistItem.class.getClassLoader());
|
||||
this.reminders = new ArrayList<RemindersItem>();
|
||||
in.readList(this.reminders, RemindersItem.class.getClassLoader());
|
||||
this.frequency = in.readString();
|
||||
this.everyX = (Integer) in.readValue(Integer.class.getClassLoader());
|
||||
this.streak = (Integer) in.readValue(Integer.class.getClassLoader());
|
||||
long tmpStartDate = in.readLong();
|
||||
this.startDate = tmpStartDate == -1 ? null : new Date(tmpStartDate);
|
||||
this.repeat = in.readParcelable(Days.class.getClassLoader());
|
||||
long tmpDuedate = in.readLong();
|
||||
this.duedate = tmpDuedate == -1 ? null : new Date(tmpDuedate);
|
||||
this.specialTag = in.readString();
|
||||
this.id = in.readString();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<Task> CREATOR = new Parcelable.Creator<Task>() {
|
||||
@Override
|
||||
public Task createFromParcel(Parcel source) {
|
||||
return new Task(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task[] newArray(int size) {
|
||||
return new Task[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -220,6 +220,10 @@ public class HabitRPGUser extends BaseModel {
|
|||
return this.balance;
|
||||
}
|
||||
|
||||
public int getGemCount(){
|
||||
return (int)(this.balance * 4);
|
||||
}
|
||||
|
||||
public void setBalance(double balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,21 @@
|
|||
package com.habitrpg.android.habitica.modules;
|
||||
|
||||
|
||||
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||
import com.habitrpg.android.habitica.data.SetupCustomizationRepository;
|
||||
import com.habitrpg.android.habitica.data.TagRepository;
|
||||
import com.habitrpg.android.habitica.data.TaskRepository;
|
||||
import com.habitrpg.android.habitica.data.UserRepository;
|
||||
import com.habitrpg.android.habitica.data.implementation.ChallengeRepositoryImpl;
|
||||
import com.habitrpg.android.habitica.data.implementation.SetupCustomizationRepositoryImpl;
|
||||
import com.habitrpg.android.habitica.data.implementation.TagRepositoryImpl;
|
||||
import com.habitrpg.android.habitica.data.implementation.TaskRepositoryImpl;
|
||||
import com.habitrpg.android.habitica.data.implementation.UserRepositoryImpl;
|
||||
import com.habitrpg.android.habitica.data.local.ChallengeLocalRepository;
|
||||
import com.habitrpg.android.habitica.data.local.TagLocalRepository;
|
||||
import com.habitrpg.android.habitica.data.local.TaskLocalRepository;
|
||||
import com.habitrpg.android.habitica.data.local.UserLocalRepository;
|
||||
import com.habitrpg.android.habitica.data.local.implementation.DbFlowChallengeLocalRepository;
|
||||
import com.habitrpg.android.habitica.data.local.implementation.DbFlowTaskLocalRepository;
|
||||
import com.habitrpg.android.habitica.data.local.implementation.DbFlowTagLocalRepository;
|
||||
import com.habitrpg.android.habitica.data.ApiClient;
|
||||
|
|
@ -33,6 +37,12 @@ public class RepositoryModule {
|
|||
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ChallengeLocalRepository provideChallengeLocalRepository(){
|
||||
return new DbFlowChallengeLocalRepository();
|
||||
}
|
||||
|
||||
@Provides
|
||||
TaskLocalRepository providesTaskLocalRepository() {
|
||||
return new DbFlowTaskLocalRepository();
|
||||
|
|
@ -44,6 +54,13 @@ public class RepositoryModule {
|
|||
return new TaskRepositoryImpl(localRepository, apiClient);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ChallengeRepository providesChallengeRepository(ChallengeLocalRepository localRepository, ApiClient apiClient) {
|
||||
return new ChallengeRepositoryImpl(localRepository, apiClient);
|
||||
}
|
||||
|
||||
|
||||
@Provides
|
||||
TagLocalRepository providesTagLocalRepository() {
|
||||
return new DbFlowTagLocalRepository();
|
||||
|
|
|
|||
|
|
@ -153,8 +153,8 @@ public class AvatarWithBarsViewModel implements View.OnClickListener {
|
|||
goldText.setText(String.valueOf(gp));
|
||||
silverText.setText(String.valueOf(sp));
|
||||
|
||||
Double gems = user.getBalance() * 4;
|
||||
gemsText.setText(String.valueOf(gems.intValue()));
|
||||
int gems = user.getGemCount();
|
||||
gemsText.setText(String.valueOf(gems));
|
||||
}
|
||||
|
||||
public void setHpBarData(float value, int valueMax) {
|
||||
|
|
@ -186,9 +186,9 @@ public class AvatarWithBarsViewModel implements View.OnClickListener {
|
|||
|
||||
@Subscribe
|
||||
public void onEvent(BoughtGemsEvent gemsEvent) {
|
||||
Double gems = userObject.getBalance() * 4;
|
||||
int gems = userObject.getGemCount();
|
||||
gems += gemsEvent.NewGemsToAdd;
|
||||
gemsText.setText(String.valueOf(gems.intValue()));
|
||||
gemsText.setText(String.valueOf(gems));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -34,11 +34,13 @@ import org.greenrobot.eventbus.EventBus;
|
|||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.databinding.ObservableArrayList;
|
||||
import android.databinding.ObservableList;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
|
|
@ -103,6 +105,7 @@ public class ChallengeDetailActivity extends BaseActivity {
|
|||
|
||||
private Challenge challenge;
|
||||
|
||||
|
||||
@Override
|
||||
protected int getLayoutResId() {
|
||||
return R.layout.activity_challenge_detail;
|
||||
|
|
@ -112,6 +115,11 @@ public class ChallengeDetailActivity extends BaseActivity {
|
|||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.menu_challenge_details, menu);
|
||||
|
||||
if(!challenge.leaderId.equals(HabiticaApplication.User.getId())){
|
||||
menu.setGroupVisible(R.id.challenge_edit_action_group, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -225,6 +233,7 @@ public class ChallengeDetailActivity extends BaseActivity {
|
|||
|
||||
ChallengeViewHolder challengeViewHolder = new ChallengeViewHolder(findViewById(R.id.challenge_header));
|
||||
challengeViewHolder.bind(challenge);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -240,11 +249,23 @@ public class ChallengeDetailActivity extends BaseActivity {
|
|||
|
||||
return true;
|
||||
|
||||
case R.id.action_edit:
|
||||
openChallengeEditActivity();
|
||||
return true;
|
||||
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void openChallengeEditActivity(){
|
||||
Intent intent = new Intent(this, CreateChallengeActivity.class);
|
||||
intent.putExtra(CreateChallengeActivity.CHALLENGE_ID_KEY, challenge.id);
|
||||
|
||||
startActivity(intent);
|
||||
|
||||
}
|
||||
|
||||
private void showChallengeLeaveDialog(){
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(this.getString(R.string.challenge_leave_title))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,581 @@
|
|||
package com.habitrpg.android.habitica.ui.activities;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.TextInputLayout;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.widget.AppCompatCheckedTextView;
|
||||
import android.support.v7.widget.AppCompatTextView;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.underscore.$;
|
||||
import com.habitrpg.android.habitica.HabiticaApplication;
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||
import com.habitrpg.android.habitica.events.TaskSaveEvent;
|
||||
import com.habitrpg.android.habitica.events.TaskTappedEvent;
|
||||
import com.habitrpg.android.habitica.events.commands.DeleteTaskCommand;
|
||||
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.ui.adapter.social.challenges.ChallengeTasksRecyclerViewAdapter;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.OnClick;
|
||||
import rx.Observable;
|
||||
|
||||
public class CreateChallengeActivity extends BaseActivity {
|
||||
public static final String CHALLENGE_ID_KEY = "challengeId";
|
||||
|
||||
@BindView(R.id.create_challenge_title_input_layout)
|
||||
TextInputLayout createChallengeTitleInputLayout;
|
||||
|
||||
@BindView(R.id.create_challenge_title)
|
||||
EditText createChallengeTitle;
|
||||
|
||||
@BindView(R.id.create_challenge_description_input_layout)
|
||||
TextInputLayout createChallengeDescriptionInputLayout;
|
||||
|
||||
@BindView(R.id.create_challenge_description)
|
||||
EditText createChallengeDescription;
|
||||
|
||||
@BindView(R.id.create_challenge_prize)
|
||||
EditText createChallengePrize;
|
||||
|
||||
|
||||
@BindView(R.id.create_challenge_tag_input_layout)
|
||||
TextInputLayout createChallengeTagInputLayout;
|
||||
|
||||
@BindView(R.id.create_challenge_tag)
|
||||
EditText createChallengeTag;
|
||||
|
||||
@BindView(R.id.create_challenge_gem_error)
|
||||
TextView createChallengeGemError;
|
||||
|
||||
@BindView(R.id.create_challenge_task_error)
|
||||
TextView createChallengeTaskError;
|
||||
|
||||
@BindView(R.id.challenge_location_spinner)
|
||||
Spinner challengeLocationSpinner;
|
||||
|
||||
@BindView(R.id.challenge_add_gem_btn)
|
||||
Button challengeAddGemBtn;
|
||||
|
||||
@BindView(R.id.challenge_remove_gem_btn)
|
||||
Button challengeRemoveGemBtn;
|
||||
|
||||
@BindView(R.id.create_challenge_task_list)
|
||||
RecyclerView createChallengeTaskList;
|
||||
|
||||
@Inject
|
||||
ChallengeRepository challengeRepository;
|
||||
|
||||
private ChallengeTasksRecyclerViewAdapter challengeTasks;
|
||||
|
||||
private GroupArrayAdapter locationAdapter;
|
||||
private String challengeId;
|
||||
private boolean editMode;
|
||||
|
||||
private HashMap<String, Task> addedTasks = new HashMap<>();
|
||||
private HashMap<String, Task> updatedTasks = new HashMap<>();
|
||||
private HashMap<String, Task> removedTasks = new HashMap<>();
|
||||
|
||||
// Add {*} Items
|
||||
Task addHabit;
|
||||
Task addDaily;
|
||||
Task addTodo;
|
||||
Task addReward;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResId() {
|
||||
return R.layout.activity_create_challenge;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void injectActivity(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.menu_create_challenge, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean savingInProgress = false;
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.action_save && !savingInProgress && validateAllFields()) {
|
||||
savingInProgress = true;
|
||||
ProgressDialog dialog = ProgressDialog.show(this, "", "Saving challenge data. Please wait...", true, false);
|
||||
|
||||
Observable<Challenge> observable;
|
||||
|
||||
if (editMode) {
|
||||
observable = updateChallenge();
|
||||
} else {
|
||||
observable = createChallenge();
|
||||
}
|
||||
|
||||
observable.subscribe(challenge -> {
|
||||
dialog.dismiss();
|
||||
savingInProgress = false;
|
||||
finish();
|
||||
}, throwable -> {
|
||||
dialog.dismiss();
|
||||
savingInProgress = false;
|
||||
});
|
||||
} else if(item.getItemId() == android.R.id.home){
|
||||
finish();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private boolean validateAllFields() {
|
||||
ArrayList<String> errorMessages = new ArrayList<>();
|
||||
|
||||
if (getEditTextString(createChallengeTitle).isEmpty()) {
|
||||
String titleEmptyError = getString(R.string.challenge_create_error_title);
|
||||
createChallengeTitleInputLayout.setError(titleEmptyError);
|
||||
errorMessages.add(titleEmptyError);
|
||||
} else {
|
||||
createChallengeTitleInputLayout.setErrorEnabled(false);
|
||||
}
|
||||
|
||||
if (getEditTextString(createChallengeTag).isEmpty()) {
|
||||
String tagEmptyError = getString(R.string.challenge_create_error_tag);
|
||||
|
||||
createChallengeTagInputLayout.setError(tagEmptyError);
|
||||
errorMessages.add(tagEmptyError);
|
||||
} else {
|
||||
createChallengeTagInputLayout.setErrorEnabled(false);
|
||||
}
|
||||
|
||||
String prizeError = checkPrizeAndMinimumForTavern();
|
||||
|
||||
if(!prizeError.isEmpty()){
|
||||
errorMessages.add(prizeError);
|
||||
}
|
||||
|
||||
// all "Add {*}"-Buttons are one task itself, so we need atleast more than 4
|
||||
if (challengeTasks.getTaskList().size() <= 4) {
|
||||
createChallengeTaskError.setVisibility(View.VISIBLE);
|
||||
errorMessages.add(getString(R.string.challenge_create_error_no_tasks));
|
||||
} else {
|
||||
createChallengeTaskError.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this)
|
||||
.setMessage($.join(errorMessages, "\n"));
|
||||
|
||||
AlertDialog alert = builder.create();
|
||||
alert.show();
|
||||
|
||||
return errorMessages.size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Intent intent = getIntent();
|
||||
Bundle bundle = intent.getExtras();
|
||||
|
||||
if (bundle != null) {
|
||||
challengeId = bundle.getString(CHALLENGE_ID_KEY, null);
|
||||
}
|
||||
|
||||
EventBus.getDefault().register(this);
|
||||
|
||||
fillControls();
|
||||
|
||||
if (challengeId != null) {
|
||||
fillControlsByChallenge();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
EventBus.getDefault().unregister(this);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEvent(DeleteTaskCommand deleteTask) {
|
||||
String taskIdToDelete = deleteTask.TaskIdToDelete;
|
||||
challengeTasks.removeTask(taskIdToDelete);
|
||||
|
||||
if (editMode) {
|
||||
if (addedTasks.containsKey(taskIdToDelete)) {
|
||||
addedTasks.remove(taskIdToDelete);
|
||||
} else {
|
||||
removedTasks.put(taskIdToDelete, null);
|
||||
|
||||
if (updatedTasks.containsKey(taskIdToDelete)) {
|
||||
updatedTasks.remove(taskIdToDelete);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEvent(TaskTappedEvent tappedEvent) {
|
||||
openNewTaskActivity(null, tappedEvent.Task);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEvent(TaskSaveEvent saveEvent) {
|
||||
|
||||
if (saveEvent.task.getId() == null) {
|
||||
saveEvent.task.setId(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
addOrUpdateTaskInList(saveEvent.task);
|
||||
}
|
||||
|
||||
@OnClick(R.id.challenge_add_gem_btn)
|
||||
public void onAddGem() {
|
||||
int currentVal = Integer.parseInt(createChallengePrize.getText().toString());
|
||||
currentVal++;
|
||||
|
||||
createChallengePrize.setText("" + currentVal);
|
||||
|
||||
checkPrizeAndMinimumForTavern();
|
||||
}
|
||||
|
||||
@OnClick(R.id.challenge_remove_gem_btn)
|
||||
public void onRemoveGem() {
|
||||
|
||||
int currentVal = Integer.parseInt(createChallengePrize.getText().toString());
|
||||
currentVal--;
|
||||
|
||||
createChallengePrize.setText("" + currentVal);
|
||||
|
||||
checkPrizeAndMinimumForTavern();
|
||||
}
|
||||
|
||||
private String checkPrizeAndMinimumForTavern() {
|
||||
String errorResult = "";
|
||||
|
||||
String inputValue = createChallengePrize.getText().toString();
|
||||
|
||||
if (inputValue.isEmpty()) {
|
||||
inputValue = "0";
|
||||
}
|
||||
|
||||
int currentVal = Integer.parseInt(inputValue);
|
||||
|
||||
// 0 is Tavern
|
||||
int selectedLocation = challengeLocationSpinner.getSelectedItemPosition();
|
||||
|
||||
double gemCount = HabiticaApplication.User.getGemCount();
|
||||
|
||||
if (selectedLocation == 0 && currentVal == 0) {
|
||||
createChallengeGemError.setVisibility(View.VISIBLE);
|
||||
String error = getString(R.string.challenge_create_error_tavern_one_gem);
|
||||
createChallengeGemError.setText(error);
|
||||
errorResult = error;
|
||||
} else if (currentVal > gemCount) {
|
||||
createChallengeGemError.setVisibility(View.VISIBLE);
|
||||
String error = getString(R.string.challenge_create_error_enough_gems);
|
||||
createChallengeGemError.setText(error);
|
||||
errorResult = error;
|
||||
} else {
|
||||
createChallengeGemError.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
challengeRemoveGemBtn.setEnabled(currentVal != 0);
|
||||
|
||||
return errorResult;
|
||||
}
|
||||
|
||||
private void fillControls() {
|
||||
Resources resources = getResources();
|
||||
|
||||
ActionBar supportActionBar = getSupportActionBar();
|
||||
if (supportActionBar != null) {
|
||||
supportActionBar.setDisplayShowHomeEnabled(true);
|
||||
supportActionBar.setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
|
||||
|
||||
supportActionBar.setTitle("");
|
||||
supportActionBar.setBackgroundDrawable(new ColorDrawable(resources.getColor(R.color.brand_200)));
|
||||
supportActionBar.setElevation(0);
|
||||
}
|
||||
|
||||
locationAdapter = new GroupArrayAdapter(this);
|
||||
locationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
challengeRepository.getLocalGroups().subscribe(groups -> {
|
||||
Group tavern = new Group();
|
||||
tavern.id = "00000000-0000-4000-A000-000000000000";
|
||||
tavern.name = getString(R.string.sidebar_tavern);
|
||||
|
||||
locationAdapter.add(tavern);
|
||||
|
||||
groups.forEach(group -> locationAdapter.add(group));
|
||||
}, Throwable::printStackTrace);
|
||||
|
||||
challengeLocationSpinner.setAdapter(locationAdapter);
|
||||
challengeLocationSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
checkPrizeAndMinimumForTavern();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||
|
||||
}
|
||||
});
|
||||
createChallengePrize.setOnKeyListener((view, i, keyEvent) -> {
|
||||
checkPrizeAndMinimumForTavern();
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
addHabit = createTask(ChallengeTasksRecyclerViewAdapter.TASK_TYPE_ADD_ITEM, resources.getString(R.string.add_habit));
|
||||
addDaily = createTask(ChallengeTasksRecyclerViewAdapter.TASK_TYPE_ADD_ITEM, resources.getString(R.string.add_daily));
|
||||
addTodo = createTask(ChallengeTasksRecyclerViewAdapter.TASK_TYPE_ADD_ITEM, resources.getString(R.string.add_todo));
|
||||
addReward = createTask(ChallengeTasksRecyclerViewAdapter.TASK_TYPE_ADD_ITEM, resources.getString(R.string.add_reward));
|
||||
|
||||
|
||||
ArrayList<Task> taskList = new ArrayList<>();
|
||||
taskList.add(addHabit);
|
||||
taskList.add(addDaily);
|
||||
taskList.add(addTodo);
|
||||
taskList.add(addReward);
|
||||
|
||||
challengeTasks = new ChallengeTasksRecyclerViewAdapter(null, 0, this, "", null, false, true);
|
||||
challengeTasks.setTasks(taskList);
|
||||
challengeTasks.addItemObservable().subscribe(t -> {
|
||||
if (t.equals(addHabit)) {
|
||||
openNewTaskActivity(Task.TYPE_HABIT, null);
|
||||
} else if (t.equals(addDaily)) {
|
||||
openNewTaskActivity(Task.TYPE_DAILY, null);
|
||||
} else if (t.equals(addTodo)) {
|
||||
openNewTaskActivity(Task.TYPE_TODO, null);
|
||||
} else if (t.equals(addReward)) {
|
||||
openNewTaskActivity(Task.TYPE_REWARD, null);
|
||||
}
|
||||
});
|
||||
|
||||
createChallengeTaskList.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
|
||||
// Stop only scrolling.
|
||||
return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING;
|
||||
}
|
||||
});
|
||||
createChallengeTaskList.setAdapter(challengeTasks);
|
||||
createChallengeTaskList.setLayoutManager(new LinearLayoutManager(this));
|
||||
}
|
||||
|
||||
private static Task createTask(String taskType, String taskName) {
|
||||
Task t = new Task();
|
||||
|
||||
t.setId(UUID.randomUUID().toString());
|
||||
t.setType(taskType);
|
||||
t.setText(taskName);
|
||||
|
||||
if (taskType.equals(Task.TYPE_HABIT)) {
|
||||
t.setUp(true);
|
||||
t.setDown(false);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
private void fillControlsByChallenge() {
|
||||
challengeRepository.getChallenge(challengeId).subscribe(challenge -> {
|
||||
|
||||
createChallengeTitle.setText(challenge.name);
|
||||
createChallengeDescription.setText(challenge.description);
|
||||
createChallengeTag.setText(challenge.shortName);
|
||||
createChallengePrize.setText(challenge.prize + "");
|
||||
|
||||
for (int i = 0; i < locationAdapter.getCount(); i++) {
|
||||
Group group = locationAdapter.getItem(i);
|
||||
|
||||
if (group.id == challenge.groupId) {
|
||||
challengeLocationSpinner.setSelection(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
checkPrizeAndMinimumForTavern();
|
||||
|
||||
challengeRepository.getChallengeTasks(challengeId).subscribe(tasks -> {
|
||||
tasks.tasks.forEach((s, task) -> addOrUpdateTaskInList(task));
|
||||
}, Throwable::printStackTrace, () -> {
|
||||
// activate editMode to track taskChanges
|
||||
editMode = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void openNewTaskActivity(String type, Task task) {
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
if (task == null) {
|
||||
bundle.putString(TaskFormActivity.TASK_TYPE_KEY, type);
|
||||
} else {
|
||||
bundle.putParcelable(TaskFormActivity.PARCELABLE_TASK, task);
|
||||
}
|
||||
|
||||
bundle.putBoolean(TaskFormActivity.SAVE_TO_DB, false);
|
||||
bundle.putBoolean(TaskFormActivity.SET_IGNORE_FLAG, true);
|
||||
bundle.putBoolean(TaskFormActivity.SHOW_TAG_SELECTION, false);
|
||||
bundle.putBoolean(TaskFormActivity.SHOW_CHECKLIST, false);
|
||||
|
||||
if (HabiticaApplication.User != null && HabiticaApplication.User.getPreferences() != null) {
|
||||
String allocationMode = HabiticaApplication.User.getPreferences().getAllocationMode();
|
||||
|
||||
bundle.putString(TaskFormActivity.USER_ID_KEY, HabiticaApplication.User.getId());
|
||||
bundle.putString(TaskFormActivity.ALLOCATION_MODE_KEY, allocationMode);
|
||||
}
|
||||
|
||||
Intent intent = new Intent(this, TaskFormActivity.class);
|
||||
intent.putExtras(bundle);
|
||||
|
||||
startActivityForResult(intent, 1);
|
||||
}
|
||||
|
||||
private Challenge getChallengeData() {
|
||||
Challenge c = new Challenge();
|
||||
|
||||
int locationPos = challengeLocationSpinner.getSelectedItemPosition();
|
||||
Group locationGroup = locationAdapter.getItem(locationPos);
|
||||
|
||||
if (challengeId != null) {
|
||||
c.id = challengeId;
|
||||
}
|
||||
|
||||
c.groupId = locationGroup.id;
|
||||
c.name = createChallengeTitle.getText().toString();
|
||||
c.description = createChallengeDescription.getText().toString();
|
||||
c.shortName = createChallengeTag.getText().toString();
|
||||
c.prize = Integer.parseInt(createChallengePrize.getText().toString());
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private Observable<Challenge> createChallenge() {
|
||||
Challenge c = getChallengeData();
|
||||
|
||||
List<Task> taskList = challengeTasks.getTaskList();
|
||||
taskList.remove(addHabit);
|
||||
taskList.remove(addDaily);
|
||||
taskList.remove(addTodo);
|
||||
taskList.remove(addReward);
|
||||
|
||||
return challengeRepository.createChallenge(c, taskList);
|
||||
}
|
||||
|
||||
private Observable<Challenge> updateChallenge() {
|
||||
Challenge c = getChallengeData();
|
||||
|
||||
List<Task> taskList = challengeTasks.getTaskList();
|
||||
taskList.remove(addHabit);
|
||||
taskList.remove(addDaily);
|
||||
taskList.remove(addTodo);
|
||||
taskList.remove(addReward);
|
||||
|
||||
return challengeRepository.updateChallenge(c, taskList, new ArrayList<>(addedTasks.values()),
|
||||
new ArrayList<>(updatedTasks.values()),
|
||||
new ArrayList<>(removedTasks.keySet())
|
||||
);
|
||||
}
|
||||
|
||||
private void addOrUpdateTaskInList(Task task) {
|
||||
if (!challengeTasks.replaceTask(task)) {
|
||||
Task taskAbove;
|
||||
|
||||
switch (task.getType()) {
|
||||
case Task.TYPE_HABIT:
|
||||
taskAbove = addHabit;
|
||||
break;
|
||||
case Task.TYPE_DAILY:
|
||||
taskAbove = addDaily;
|
||||
break;
|
||||
case Task.TYPE_TODO:
|
||||
taskAbove = addTodo;
|
||||
break;
|
||||
default:
|
||||
taskAbove = addReward;
|
||||
break;
|
||||
}
|
||||
|
||||
challengeTasks.addTaskUnder(task, taskAbove);
|
||||
|
||||
if (editMode) {
|
||||
addedTasks.put(task.getId(), task);
|
||||
}
|
||||
} else {
|
||||
// don't need to add the task to updatedTasks if its already been added right now
|
||||
if (editMode && !addedTasks.containsKey(task.getId())) {
|
||||
updatedTasks.put(task.getId(), task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getEditTextString(EditText editText) {
|
||||
return editText.getText().toString();
|
||||
}
|
||||
|
||||
private class GroupArrayAdapter extends ArrayAdapter<Group> {
|
||||
public GroupArrayAdapter(@NonNull Context context) {
|
||||
super(context, android.R.layout.simple_spinner_item);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
AppCompatTextView checkedTextView = (AppCompatTextView) super.getView(position, convertView, parent);
|
||||
checkedTextView.setText(getItem(position).name);
|
||||
return checkedTextView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||
AppCompatCheckedTextView checkedTextView = (AppCompatCheckedTextView) super.getDropDownView(position, convertView, parent);
|
||||
checkedTextView.setText(getItem(position).name);
|
||||
return checkedTextView;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -853,6 +853,10 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
|
||||
@Subscribe
|
||||
public void onEvent(final DeleteTaskCommand cmd) {
|
||||
if(cmd.ignoreEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
taskRepository.deleteTask(cmd.TaskIdToDelete)
|
||||
.subscribe(aVoid -> EventBus.getDefault().post(new TaskRemovedEvent(cmd.TaskIdToDelete)), throwable -> {});
|
||||
}
|
||||
|
|
@ -1213,6 +1217,9 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
|
||||
@Subscribe
|
||||
public void onEvent(final TaskSaveEvent event) {
|
||||
if(event.ignoreEvent)
|
||||
return;
|
||||
|
||||
Task task = event.task;
|
||||
if (event.created) {
|
||||
this.taskRepository.createTask(task).subscribe(task1 -> {}, throwable -> {});
|
||||
|
|
|
|||
|
|
@ -116,7 +116,14 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
|
|||
public static final String TASK_ID_KEY = "taskId";
|
||||
public static final String USER_ID_KEY = "userId";
|
||||
public static final String TASK_TYPE_KEY = "type";
|
||||
public static final String SHOW_TAG_SELECTION = "show_tag_selection";
|
||||
public static final String SHOW_CHECKLIST = "show_checklist";
|
||||
public static final String PARCELABLE_TASK = "parcelable_task";
|
||||
public static final String ALLOCATION_MODE_KEY = "allocationModeKey";
|
||||
public static final String SAVE_TO_DB = "saveToDb";
|
||||
|
||||
// in order to disable the event handler in MainActivity
|
||||
public static final String SET_IGNORE_FLAG = "ignoreFlag";
|
||||
|
||||
@BindView(R.id.task_value_edittext)
|
||||
EditText taskValue;
|
||||
|
|
@ -257,6 +264,9 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
|
|||
private String taskType;
|
||||
private String taskId;
|
||||
private String userId;
|
||||
private boolean showTagSelection;
|
||||
private boolean showChecklist;
|
||||
private boolean setIgnoreFlag;
|
||||
private Task task;
|
||||
private String allocationMode;
|
||||
private List<CheckBox> weekdayCheckboxes = new ArrayList<>();
|
||||
|
|
@ -270,6 +280,7 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
|
|||
|
||||
private RemindersManager remindersManager;
|
||||
private FirstDayOfTheWeekHelper firstDayOfTheWeekHelper;
|
||||
private boolean saveToDb;
|
||||
|
||||
@Override
|
||||
protected int getLayoutResId() {
|
||||
|
|
@ -282,10 +293,23 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
|
|||
|
||||
Intent intent = getIntent();
|
||||
Bundle bundle = intent.getExtras();
|
||||
|
||||
taskType = bundle.getString(TASK_TYPE_KEY);
|
||||
taskId = bundle.getString(TASK_ID_KEY);
|
||||
userId = bundle.getString(USER_ID_KEY);
|
||||
showTagSelection = bundle.getBoolean(SHOW_TAG_SELECTION, true);
|
||||
showChecklist = bundle.getBoolean(SHOW_CHECKLIST, true);
|
||||
allocationMode = bundle.getString(ALLOCATION_MODE_KEY);
|
||||
saveToDb = bundle.getBoolean(SAVE_TO_DB, true);
|
||||
setIgnoreFlag = bundle.getBoolean(SET_IGNORE_FLAG, false);
|
||||
|
||||
tagsWrapper.setVisibility(showTagSelection ? View.VISIBLE : View.GONE);
|
||||
|
||||
if(bundle.containsKey(PARCELABLE_TASK)){
|
||||
task = bundle.getParcelable(PARCELABLE_TASK);
|
||||
taskType = task.type;
|
||||
}
|
||||
|
||||
tagCheckBoxList = new ArrayList<>();
|
||||
selectedTags = new ArrayList<>();
|
||||
if (taskType == null) {
|
||||
|
|
@ -309,7 +333,13 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
|
|||
finish();
|
||||
dismissKeyboard();
|
||||
|
||||
EventBus.getDefault().post(new DeleteTaskCommand(taskId));
|
||||
String taskToDelete = this.taskId;
|
||||
|
||||
if(taskToDelete == null && task != null){
|
||||
taskToDelete = task.getId();
|
||||
}
|
||||
|
||||
EventBus.getDefault().post(new DeleteTaskCommand(taskToDelete, setIgnoreFlag));
|
||||
}).setNegativeButton(getString(R.string.no), (dialog, which) -> {
|
||||
dialog.dismiss();
|
||||
}).show());
|
||||
|
|
@ -378,6 +408,10 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
|
|||
attributeWrapper.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(!showChecklist){
|
||||
mainWrapper.removeView(checklistWrapper);
|
||||
}
|
||||
|
||||
if (taskId != null) {
|
||||
Task task = new Select().from(Task.class).byIds(taskId).querySingle();
|
||||
this.task = task;
|
||||
|
|
@ -387,6 +421,11 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
|
|||
|
||||
setTitle(task);
|
||||
|
||||
btnDelete.setEnabled(true);
|
||||
} else if(task != null) {
|
||||
populate(task);
|
||||
taskText.requestFocus();
|
||||
|
||||
btnDelete.setEnabled(true);
|
||||
} else {
|
||||
setTitle((Task) null);
|
||||
|
|
@ -407,7 +446,10 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
|
|||
// If it's a to-do, change the emojiToggle2 to the actual emojiToggle2 (prevents NPEs when not a to-do task)
|
||||
if (isTodo) {
|
||||
emojiToggle2 = (ImageButton) findViewById(R.id.emoji_toggle_btn2);
|
||||
} else {
|
||||
}
|
||||
|
||||
// if showChecklist is inactive the wrapper is wrapper, so the reference can't be found
|
||||
if(emojiToggle2 == null) {
|
||||
emojiToggle2 = emojiToggle0;
|
||||
}
|
||||
|
||||
|
|
@ -1179,12 +1221,16 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
|
|||
}
|
||||
//save
|
||||
this.task.setTags(taskTags);
|
||||
this.task.save();
|
||||
if(saveToDb){
|
||||
this.task.save();
|
||||
}
|
||||
|
||||
//send back to other elements.
|
||||
TaskSaveEvent event = new TaskSaveEvent();
|
||||
if (TaskFormActivity.this.task.getId() == null) {
|
||||
event.created = true;
|
||||
}
|
||||
event.ignoreEvent = setIgnoreFlag;
|
||||
|
||||
event.task = TaskFormActivity.this.task;
|
||||
EventBus.getDefault().post(event);
|
||||
|
|
|
|||
|
|
@ -1,18 +1,5 @@
|
|||
package com.habitrpg.android.habitica.ui.adapter.social;
|
||||
|
||||
import com.github.underscore.$;
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailActivityCommand;
|
||||
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailDialogCommand;
|
||||
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeFilterOptions;
|
||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||
import com.habitrpg.android.habitica.models.user.HabitRPGUser;
|
||||
|
||||
import net.pherth.android.emoji_library.EmojiParser;
|
||||
import net.pherth.android.emoji_library.EmojiTextView;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
|
@ -23,19 +10,28 @@ import android.view.ViewGroup;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.underscore.$;
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailActivityCommand;
|
||||
import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailDialogCommand;
|
||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||
import com.habitrpg.android.habitica.models.user.HabitRPGUser;
|
||||
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeFilterOptions;
|
||||
|
||||
import net.pherth.android.emoji_library.EmojiParser;
|
||||
import net.pherth.android.emoji_library.EmojiTextView;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
import static com.raizlabs.android.dbflow.config.FlowManager.getContext;
|
||||
|
||||
|
||||
public class ChallengesListViewAdapter extends RecyclerView.Adapter<ChallengesListViewAdapter.ChallengeViewHolder> {
|
||||
|
||||
|
||||
private List<Challenge> challenges = new ArrayList<>();
|
||||
private List<Challenge> challengesSource = new ArrayList<>();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,195 @@
|
|||
package com.habitrpg.android.habitica.ui.adapter.social.challenges;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.underscore.$;
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.helpers.TaskFilterHelper;
|
||||
import com.habitrpg.android.habitica.models.tasks.Task;
|
||||
import com.habitrpg.android.habitica.ui.adapter.tasks.SortableTasksRecyclerViewAdapter;
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.tasks.BaseTaskViewHolder;
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.tasks.DailyViewHolder;
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.tasks.HabitViewHolder;
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.tasks.RewardViewHolder;
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.tasks.TodoViewHolder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import rx.Observable;
|
||||
import rx.subjects.PublishSubject;
|
||||
|
||||
public class ChallengeTasksRecyclerViewAdapter
|
||||
extends SortableTasksRecyclerViewAdapter<BaseTaskViewHolder> {
|
||||
public static final String TASK_TYPE_ADD_ITEM = "ADD_ITEM";
|
||||
|
||||
private static final int TYPE_HEADER = 0;
|
||||
private static final int TYPE_HABIT = 1;
|
||||
private static final int TYPE_DAILY = 2;
|
||||
private static final int TYPE_TODO = 3;
|
||||
private static final int TYPE_REWARD = 4;
|
||||
private static final int TYPE_ADD_ITEM = 5;
|
||||
|
||||
private int dailyResetOffset = 0;
|
||||
private PublishSubject<Task> addItemSubject = PublishSubject.create();
|
||||
private boolean openTaskDisabled;
|
||||
private boolean taskActionsDisabled;
|
||||
|
||||
public ChallengeTasksRecyclerViewAdapter(@Nullable TaskFilterHelper taskFilterHelper, int layoutResource,
|
||||
Context newContext, String userID, @Nullable SortTasksCallback sortCallback,
|
||||
boolean openTaskDisabled, boolean taskActionsDisabled) {
|
||||
super("", taskFilterHelper, layoutResource, newContext, userID, sortCallback);
|
||||
this.openTaskDisabled = openTaskDisabled;
|
||||
this.taskActionsDisabled = taskActionsDisabled;
|
||||
}
|
||||
|
||||
public void setDailyResetOffset(int newResetOffset) {
|
||||
dailyResetOffset = newResetOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void injectThis(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadFromDatabase() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
Task task = this.filteredContent.get(position);
|
||||
|
||||
if (task.type.equals(Task.TYPE_HABIT))
|
||||
return TYPE_HABIT;
|
||||
|
||||
if (task.type.equals(Task.TYPE_DAILY))
|
||||
return TYPE_DAILY;
|
||||
|
||||
if (task.type.equals(Task.TYPE_TODO))
|
||||
return TYPE_TODO;
|
||||
|
||||
if (task.type.equals(Task.TYPE_REWARD))
|
||||
return TYPE_REWARD;
|
||||
|
||||
if (addItemSubject.hasObservers() && task.type.equals(TASK_TYPE_ADD_ITEM))
|
||||
return TYPE_ADD_ITEM;
|
||||
|
||||
return TYPE_HEADER;
|
||||
}
|
||||
|
||||
public Observable<Task> addItemObservable(){
|
||||
return addItemSubject;
|
||||
}
|
||||
|
||||
public int addTaskUnder(Task taskToAdd, Task taskAbove) {
|
||||
int position = $.findIndex(this.content, t -> t.getId().equals(taskAbove.getId()));
|
||||
|
||||
content.add(position + 1, taskToAdd);
|
||||
filter();
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseTaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
BaseTaskViewHolder viewHolder = null;
|
||||
|
||||
switch (viewType) {
|
||||
case TYPE_HABIT:
|
||||
viewHolder = new HabitViewHolder(getContentView(parent, R.layout.habit_item_card));
|
||||
break;
|
||||
case TYPE_DAILY:
|
||||
viewHolder = new DailyViewHolder(getContentView(parent, R.layout.daily_item_card), dailyResetOffset);
|
||||
break;
|
||||
case TYPE_TODO:
|
||||
viewHolder = new TodoViewHolder(getContentView(parent, R.layout.todo_item_card));
|
||||
break;
|
||||
case TYPE_REWARD:
|
||||
viewHolder = new RewardViewHolder(getContentView(parent, R.layout.reward_item_card));
|
||||
break;
|
||||
case TYPE_ADD_ITEM:
|
||||
viewHolder = new AddItemViewHolder(getContentView(parent, R.layout.challenge_add_task_item), addItemSubject);
|
||||
break;
|
||||
default:
|
||||
viewHolder = new DividerViewHolder(getContentView(parent, R.layout.challenge_task_divider));
|
||||
break;
|
||||
}
|
||||
|
||||
viewHolder.setDisabled(openTaskDisabled, taskActionsDisabled);
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
public List<Task> getTaskList(){
|
||||
return $.map(content, t -> t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param task
|
||||
* @return true if task found&updated
|
||||
*/
|
||||
public boolean replaceTask(Task task) {
|
||||
int i;
|
||||
for (i = 0; i < this.content.size(); ++i) {
|
||||
if (content.get(i).getId().equals(task.getId())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < content.size()) {
|
||||
content.set(i, task);
|
||||
|
||||
filter();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public class AddItemViewHolder extends BaseTaskViewHolder {
|
||||
|
||||
private Button addBtn;
|
||||
private PublishSubject<Task> callback;
|
||||
private Task newTask;
|
||||
|
||||
public AddItemViewHolder(View itemView, PublishSubject<Task> callback) {
|
||||
super(itemView, false);
|
||||
this.callback = callback;
|
||||
|
||||
addBtn = (Button) itemView.findViewById(R.id.btn_add_task);
|
||||
addBtn.setClickable(true);
|
||||
addBtn.setOnClickListener(view -> callback.onNext(newTask));
|
||||
context = itemView.getContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindHolder(Task newTask, int position) {
|
||||
this.newTask = newTask;
|
||||
addBtn.setText(newTask.text);
|
||||
}
|
||||
}
|
||||
|
||||
private class DividerViewHolder extends BaseTaskViewHolder {
|
||||
|
||||
private TextView divider_name;
|
||||
|
||||
public DividerViewHolder(View itemView) {
|
||||
super(itemView, false);
|
||||
|
||||
divider_name = (TextView) itemView.findViewById(R.id.divider_name);
|
||||
|
||||
context = itemView.getContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindHolder(Task newTask, int position) {
|
||||
divider_name.setText(newTask.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments;
|
||||
|
||||
import com.habitrpg.android.habitica.BuildConfig;
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.helpers.PurchaseTypes;
|
||||
|
|
@ -14,6 +15,9 @@ import org.solovyev.android.checkout.ProductTypes;
|
|||
import org.solovyev.android.checkout.RequestListener;
|
||||
import org.solovyev.android.checkout.Sku;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
|
@ -21,10 +25,13 @@ import android.util.Log;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.OnClick;
|
||||
|
||||
public class GemsPurchaseFragment extends BaseFragment implements GemPurchaseActivity.CheckoutFragment {
|
||||
|
||||
|
|
@ -36,12 +43,20 @@ public class GemsPurchaseFragment extends BaseFragment implements GemPurchaseAct
|
|||
GemPurchaseOptionsView gems42View;
|
||||
@BindView(R.id.gems_84_view)
|
||||
GemPurchaseOptionsView gems84View;
|
||||
@BindView(R.id.gemPurchaseOptions)
|
||||
ViewGroup gemPurchaseOptions;
|
||||
|
||||
@BindView(R.id.notAvailableTextView)
|
||||
TextView billingNotAvailableTextView;
|
||||
@BindView(R.id.notAvailableButton)
|
||||
Button billingNotAvailableButton;
|
||||
|
||||
@Inject
|
||||
CrashlyticsProxy crashlyticsProxy;
|
||||
|
||||
private GemPurchaseActivity listener;
|
||||
private BillingRequests billingRequests;
|
||||
private boolean billingNotSupported;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
|
|
@ -67,6 +82,10 @@ public class GemsPurchaseFragment extends BaseFragment implements GemPurchaseAct
|
|||
gems84View.setOnPurchaseClickListener(v -> purchaseGems(PurchaseTypes.Purchase84Gems));
|
||||
|
||||
gems84View.seedsImageButton.setOnClickListener(v -> ((GemPurchaseActivity) this.getActivity()).showSeedsPromo(getString(R.string.seeds_interstitial_gems), "store"));
|
||||
|
||||
if (billingNotSupported) {
|
||||
setBillingNotSupported();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -80,7 +99,7 @@ public class GemsPurchaseFragment extends BaseFragment implements GemPurchaseAct
|
|||
products -> {
|
||||
Inventory.Product gems = products.get(ProductTypes.IN_APP);
|
||||
if (!gems.supported) {
|
||||
// billing is not supported, user can't purchase anything
|
||||
setBillingNotSupported();
|
||||
return;
|
||||
}
|
||||
java.util.List<Sku> skus = gems.getSkus();
|
||||
|
|
@ -91,6 +110,15 @@ public class GemsPurchaseFragment extends BaseFragment implements GemPurchaseAct
|
|||
}
|
||||
}
|
||||
|
||||
private void setBillingNotSupported() {
|
||||
billingNotSupported = true;
|
||||
if (gemPurchaseOptions != null) {
|
||||
gemPurchaseOptions.setVisibility(View.GONE);
|
||||
billingNotAvailableButton.setVisibility(View.VISIBLE);
|
||||
billingNotAvailableTextView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListener(GemPurchaseActivity listener) {
|
||||
this.listener = listener;
|
||||
|
|
@ -136,6 +164,11 @@ public class GemsPurchaseFragment extends BaseFragment implements GemPurchaseAct
|
|||
crashlyticsProxy.fabricLogE("Purchase", "Error", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@OnClick(R.id.notAvailableButton)
|
||||
public void openWebsite() {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.BASE_URL + "/"));
|
||||
getContext().startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,11 @@ public class SubscriptionFragment extends BaseFragment implements GemPurchaseAct
|
|||
@BindView(R.id.subscribeBenefitsTitle)
|
||||
TextView subscribeBenefitsTitle;
|
||||
|
||||
@BindView(R.id.notAvailableTextView)
|
||||
TextView billingNotAvailableTextView;
|
||||
@BindView(R.id.notAvailableButton)
|
||||
Button billingNotAvailableButton;
|
||||
|
||||
@Nullable
|
||||
Sku selectedSubscriptionSku;
|
||||
List<Sku> skus;
|
||||
|
|
@ -106,6 +111,7 @@ public class SubscriptionFragment extends BaseFragment implements GemPurchaseAct
|
|||
|
||||
private HabitRPGUser user;
|
||||
private boolean hasLoadedSubscriptionOptions;
|
||||
private boolean billingNotSupported;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
|
|
@ -145,6 +151,10 @@ public class SubscriptionFragment extends BaseFragment implements GemPurchaseAct
|
|||
this.subscribeListitem2Box.setOnClickListener(view1 -> toggleDescriptionView(this.subscribeListitem2Button, this.subscribeListItem2Description));
|
||||
this.subscribeListitem3Box.setOnClickListener(view1 -> toggleDescriptionView(this.subscribeListitem3Button, this.subscribeListItem3Description));
|
||||
this.subscribeListitem4Box.setOnClickListener(view1 -> toggleDescriptionView(this.subscribeListitem4Button, this.subscribeListItem4Description));
|
||||
|
||||
if (billingNotSupported) {
|
||||
setBillingNotSupported();
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleDescriptionView(ImageView button, TextView descriptionView) {
|
||||
|
|
@ -173,6 +183,11 @@ public class SubscriptionFragment extends BaseFragment implements GemPurchaseAct
|
|||
products -> {
|
||||
Inventory.Product subscriptions = products.get(ProductTypes.SUBSCRIPTION);
|
||||
|
||||
if (!subscriptions.supported) {
|
||||
setBillingNotSupported();
|
||||
return;
|
||||
}
|
||||
|
||||
skus = subscriptions.getSkus();
|
||||
|
||||
for (Sku sku : skus) {
|
||||
|
|
@ -185,6 +200,16 @@ public class SubscriptionFragment extends BaseFragment implements GemPurchaseAct
|
|||
}
|
||||
}
|
||||
|
||||
private void setBillingNotSupported() {
|
||||
billingNotSupported = true;
|
||||
if (subscriptionOptions != null) {
|
||||
subscriptionOptions.setVisibility(View.GONE);
|
||||
loadingIndicator.setVisibility(View.GONE);
|
||||
billingNotAvailableButton.setVisibility(View.VISIBLE);
|
||||
billingNotAvailableTextView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateButtonLabel(Sku sku, String price, Inventory.Product subscriptions) {
|
||||
SubscriptionOptionView matchingView = buttonForSku(sku);
|
||||
if (matchingView != null) {
|
||||
|
|
@ -288,6 +313,8 @@ public class SubscriptionFragment extends BaseFragment implements GemPurchaseAct
|
|||
this.subscriptionDetailsView.setPlan(plan);
|
||||
this.subscribeBenefitsTitle.setText(R.string.subscribe_prompt_thanks);
|
||||
this.subscriptionOptions.setVisibility(View.GONE);
|
||||
billingNotAvailableButton.setVisibility(View.GONE);
|
||||
billingNotAvailableTextView.setVisibility(View.GONE);
|
||||
} else {
|
||||
if (!hasLoadedSubscriptionOptions) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public class AvatarCustomizationFragment extends BaseMainFragment {
|
|||
this.updateActiveCustomization();
|
||||
this.adapter.userSize = this.user.getPreferences().getSize();
|
||||
this.adapter.hairColor = this.user.getPreferences().getHair().getColor();
|
||||
this.adapter.gemBalance = user.getBalance() * 4;
|
||||
this.adapter.gemBalance = user.getGemCount();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
|
@ -134,7 +134,7 @@ public class AvatarCustomizationFragment extends BaseMainFragment {
|
|||
@Override
|
||||
public void updateUserData(HabitRPGUser user) {
|
||||
super.updateUserData(user);
|
||||
this.adapter.gemBalance = user.getBalance() * 4;
|
||||
this.adapter.gemBalance = user.getGemCount();
|
||||
this.updateActiveCustomization();
|
||||
if (adapter.getCustomizationList() != null) {
|
||||
List<String> ownedCustomizations = new ArrayList<>();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package com.habitrpg.android.habitica.ui.fragments.social;
|
|||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||
import com.habitrpg.android.habitica.data.local.ChallengeLocalRepository;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
||||
import com.habitrpg.android.habitica.models.social.Group;
|
||||
|
||||
|
|
@ -18,6 +20,8 @@ import android.widget.TextView;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
|
|
@ -32,6 +36,9 @@ public class GuildsOverviewFragment extends BaseMainFragment implements View.OnC
|
|||
@BindView(R.id.chat_refresh_layout)
|
||||
SwipeRefreshLayout swipeRefreshLayout;
|
||||
|
||||
@Inject
|
||||
ChallengeRepository challengeRepository;
|
||||
|
||||
private List<Group> guilds;
|
||||
private ArrayList<String> guildIDs;
|
||||
|
||||
|
|
@ -77,6 +84,8 @@ public class GuildsOverviewFragment extends BaseMainFragment implements View.OnC
|
|||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
|
||||
challengeRepository.setUsersGroups(groups);
|
||||
}, throwable -> {
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social.challenges;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.ui.activities.CreateChallengeActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.PartyInviteActivity;
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.ChallengesListViewAdapter;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||
|
|
@ -50,7 +56,7 @@ public class ChallengeListFragment extends BaseMainFragment implements SwipeRefr
|
|||
private Action0 refreshCallback;
|
||||
private boolean withFilter;
|
||||
|
||||
public void setWithFilter(boolean withFilter){
|
||||
public void setWithFilter(boolean withFilter) {
|
||||
this.withFilter = withFilter;
|
||||
}
|
||||
|
||||
|
|
@ -121,12 +127,12 @@ public class ChallengeListFragment extends BaseMainFragment implements SwipeRefr
|
|||
swipeRefreshLayout.setOnRefreshListener(this);
|
||||
swipeRefreshEmptyLayout.setOnRefreshListener(this);
|
||||
|
||||
challengeFilterLayout.setVisibility(withFilter?View.VISIBLE:View.GONE);
|
||||
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;
|
||||
}));
|
||||
challengeAdapter.setFilterByGroups(filterOptions);
|
||||
this.lastFilterOptions = filterOptions;
|
||||
}));
|
||||
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this.activity));
|
||||
recyclerView.setAdapter(challengeAdapter);
|
||||
|
|
@ -215,4 +221,27 @@ public class ChallengeListFragment extends BaseMainFragment implements SwipeRefr
|
|||
public String customTitle() {
|
||||
return getString(R.string.sidebar_challenges);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.menu_list_challenges, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
|
||||
switch (id) {
|
||||
case R.id.action_create_challenge:
|
||||
Intent intent = new Intent(getActivity(), CreateChallengeActivity.class);
|
||||
startActivity(intent);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.habitrpg.android.habitica.helpers.TaskFilterHelper;
|
|||
import com.habitrpg.android.habitica.data.ApiClient;
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.challenges.ChallengeTasksRecyclerViewAdapter;
|
||||
import com.habitrpg.android.habitica.ui.adapter.tasks.BaseTasksRecyclerViewAdapter;
|
||||
import com.habitrpg.android.habitica.ui.adapter.tasks.SortableTasksRecyclerViewAdapter;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment;
|
||||
|
|
@ -86,7 +87,10 @@ public class ChallengeTasksRecyclerViewFragment extends BaseFragment {
|
|||
}
|
||||
|
||||
public void setInnerAdapter() {
|
||||
this.recyclerAdapter = new ChallengeTasksRecyclerViewAdapter(null, 0, getContext(), userID, null);
|
||||
ChallengeTasksRecyclerViewAdapter challengeTasksRecyclerViewAdapter = new ChallengeTasksRecyclerViewAdapter(null, 0, getContext(), userID, null, true, true);
|
||||
this.recyclerAdapter = challengeTasksRecyclerViewAdapter;
|
||||
|
||||
challengeTasksRecyclerViewAdapter.setDailyResetOffset(user.getPreferences().getDayStart());
|
||||
|
||||
if (tasksOnInitialize != null && tasksOnInitialize.size() != 0 && recyclerAdapter != null && recyclerAdapter.getItemCount() == 0) {
|
||||
recyclerAdapter.setTasks(tasksOnInitialize);
|
||||
|
|
@ -137,96 +141,8 @@ public class ChallengeTasksRecyclerViewFragment extends BaseFragment {
|
|||
|
||||
// region Challenge specific RecyclerViewAdapters
|
||||
|
||||
public class ChallengeTasksRecyclerViewAdapter extends SortableTasksRecyclerViewAdapter<BaseTaskViewHolder> {
|
||||
private static final int TYPE_HEADER = 0;
|
||||
private static final int TYPE_HABIT = 1;
|
||||
private static final int TYPE_DAILY = 2;
|
||||
private static final int TYPE_TODO = 3;
|
||||
private static final int TYPE_REWARD = 4;
|
||||
|
||||
private int dailyResetOffset = 0;
|
||||
|
||||
public ChallengeTasksRecyclerViewAdapter(@Nullable TaskFilterHelper taskFilterHelper, int layoutResource, Context newContext, String userID, @Nullable SortTasksCallback sortCallback) {
|
||||
super("", taskFilterHelper, layoutResource, newContext, userID, sortCallback);
|
||||
|
||||
if (user != null) {
|
||||
dailyResetOffset = user.getPreferences().getDayStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void injectThis(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadFromDatabase() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
Task task = this.filteredContent.get(position);
|
||||
|
||||
if (task.type.equals(Task.TYPE_HABIT))
|
||||
return TYPE_HABIT;
|
||||
|
||||
if (task.type.equals(Task.TYPE_DAILY))
|
||||
return TYPE_DAILY;
|
||||
|
||||
if (task.type.equals(Task.TYPE_TODO))
|
||||
return TYPE_TODO;
|
||||
|
||||
if (task.type.equals(Task.TYPE_REWARD))
|
||||
return TYPE_REWARD;
|
||||
|
||||
return TYPE_HEADER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseTaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
BaseTaskViewHolder viewHolder;
|
||||
|
||||
switch (viewType) {
|
||||
case TYPE_HABIT:
|
||||
viewHolder = new HabitViewHolder(getContentView(parent, R.layout.habit_item_card));
|
||||
break;
|
||||
case TYPE_DAILY:
|
||||
viewHolder = new DailyViewHolder(getContentView(parent, R.layout.daily_item_card), dailyResetOffset);
|
||||
break;
|
||||
case TYPE_TODO:
|
||||
viewHolder = new TodoViewHolder(getContentView(parent, R.layout.todo_item_card));
|
||||
break;
|
||||
case TYPE_REWARD:
|
||||
viewHolder = new RewardViewHolder(getContentView(parent, R.layout.reward_item_card));
|
||||
break;
|
||||
default:
|
||||
viewHolder = new DividerViewHolder(getContentView(parent, R.layout.challenge_task_divider));
|
||||
break;
|
||||
}
|
||||
|
||||
//viewHolder.setDisabled(true);
|
||||
return viewHolder;
|
||||
}
|
||||
}
|
||||
|
||||
private class DividerViewHolder extends BaseTaskViewHolder {
|
||||
|
||||
private TextView divider_name;
|
||||
|
||||
public DividerViewHolder(View itemView) {
|
||||
super(itemView, false);
|
||||
|
||||
divider_name = (TextView) itemView.findViewById(R.id.divider_name);
|
||||
|
||||
context = itemView.getContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindHolder(Task newTask, int position) {
|
||||
divider_name.setText(newTask.text);
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,17 +138,10 @@ public class FloatingActionMenuBehavior extends CoordinatorLayout.Behavior {
|
|||
}
|
||||
|
||||
private void slideFabOffScreen(FloatingActionMenu view) {
|
||||
Animation slideOff = AnimationUtils.loadAnimation(context, R.anim.fab_slide_out);
|
||||
slideOff.setDuration(FAB_ANIMATION_DURATION);
|
||||
slideOff.setFillAfter(true);
|
||||
view.startAnimation(slideOff);
|
||||
view.hideMenu(true);
|
||||
}
|
||||
|
||||
private void slideFabOnScreen(FloatingActionMenu view) {
|
||||
Animation slideIn = AnimationUtils.loadAnimation(context, R.anim.fab_slide_in);
|
||||
slideIn.setDuration(FAB_ANIMATION_DURATION);
|
||||
slideIn.setFillAfter(true);
|
||||
view.startAnimation(slideIn);
|
||||
view.showMenu(false);
|
||||
view.showMenu(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -63,7 +63,6 @@ public abstract class BaseTaskViewHolder extends RecyclerView.ViewHolder impleme
|
|||
@BindView(R.id.approvalRequiredTextField)
|
||||
TextView approvalRequiredTextView;
|
||||
|
||||
boolean disabled;
|
||||
|
||||
public BaseTaskViewHolder(View itemView) {
|
||||
this(itemView, true);
|
||||
|
|
@ -187,7 +186,7 @@ public abstract class BaseTaskViewHolder extends RecyclerView.ViewHolder impleme
|
|||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v != itemView || isDisabled()) {
|
||||
if (v != itemView || this.openTaskDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -201,13 +200,11 @@ public abstract class BaseTaskViewHolder extends RecyclerView.ViewHolder impleme
|
|||
return true;
|
||||
}
|
||||
|
||||
public boolean isDisabled() {
|
||||
return disabled;
|
||||
}
|
||||
protected boolean openTaskDisabled, taskActionsDisabled;
|
||||
|
||||
public void setDisabled(boolean disabled) {
|
||||
this.disabled = disabled;
|
||||
public void setDisabled(boolean openTaskDisabled, boolean taskActionsDisabled) {
|
||||
this.openTaskDisabled = openTaskDisabled;
|
||||
this.taskActionsDisabled = taskActionsDisabled;
|
||||
|
||||
itemView.setEnabled(!disabled);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,9 +167,9 @@ public abstract class ChecklistedViewHolder extends BaseTaskViewHolder implement
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setDisabled(boolean disabled) {
|
||||
super.setDisabled(disabled);
|
||||
public void setDisabled(boolean openTaskDisabled, boolean taskActionsDisabled) {
|
||||
super.setDisabled(openTaskDisabled, taskActionsDisabled);
|
||||
|
||||
this.checkbox.setEnabled(!disabled);
|
||||
this.checkbox.setEnabled(!taskActionsDisabled);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,10 +88,10 @@ public class HabitViewHolder extends BaseTaskViewHolder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setDisabled(boolean disabled) {
|
||||
super.setDisabled(disabled);
|
||||
public void setDisabled(boolean openTaskDisabled, boolean taskActionsDisabled) {
|
||||
super.setDisabled(openTaskDisabled, taskActionsDisabled);
|
||||
|
||||
this.btnPlus.setEnabled(!disabled);
|
||||
this.btnMinus.setEnabled(!disabled);
|
||||
this.btnPlus.setEnabled(!taskActionsDisabled);
|
||||
this.btnMinus.setEnabled(!taskActionsDisabled);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,10 +89,10 @@ public class RewardViewHolder extends BaseTaskViewHolder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setDisabled(boolean disabled) {
|
||||
super.setDisabled(disabled);
|
||||
public void setDisabled(boolean openTaskDisabled, boolean taskActionsDisabled) {
|
||||
super.setDisabled(openTaskDisabled, taskActionsDisabled);
|
||||
|
||||
this.rewardButton.setEnabled(!disabled);
|
||||
this.rewardButton.setEnabled(!taskActionsDisabled);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ import android.animation.ValueAnimator;
|
|||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.AnticipateInterpolator;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
|
|
@ -44,6 +46,11 @@ public class LoginBackgroundView extends RelativeLayout {
|
|||
public LoginBackgroundView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
this.random = new Random();
|
||||
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
windowManager.getDefaultDisplay().getMetrics(metrics);
|
||||
height = (int) (metrics.heightPixels*SIZE_FACTOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -69,10 +76,7 @@ public class LoginBackgroundView extends RelativeLayout {
|
|||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
|
||||
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
|
||||
this.width = parentWidth;
|
||||
this.height = (int)(parentHeight*SIZE_FACTOR);
|
||||
this.width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
this.setMeasuredDimension(width, height);
|
||||
params.width = width;
|
||||
params.height = height;
|
||||
|
|
|
|||
|
|
@ -6,13 +6,15 @@ import com.google.gson.JsonElement;
|
|||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class ChallengeDeserializer implements JsonDeserializer<Challenge> {
|
||||
public class ChallengeSerializer implements JsonDeserializer<Challenge>, JsonSerializer<Challenge> {
|
||||
@Override
|
||||
public Challenge deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
|
||||
|
|
@ -43,7 +45,15 @@ public class ChallengeDeserializer implements JsonDeserializer<Challenge> {
|
|||
|
||||
if (profile != null) {
|
||||
challenge.leaderName = profile.get("name").getAsString();
|
||||
challenge.leaderId = leaderObj.get("id").getAsString();
|
||||
|
||||
JsonElement id = leaderObj.get("id");
|
||||
if (id == null) {
|
||||
id = leaderObj.get("_id");
|
||||
}
|
||||
|
||||
if (id != null) {
|
||||
challenge.leaderId = id.getAsString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -85,4 +95,22 @@ public class ChallengeDeserializer implements JsonDeserializer<Challenge> {
|
|||
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Challenge src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("id", src.id);
|
||||
object.addProperty("name", src.name);
|
||||
object.addProperty("shortName", src.shortName);
|
||||
object.addProperty("description", src.description);
|
||||
object.addProperty("memberCount", src.memberCount);
|
||||
object.addProperty("prize", src.prize);
|
||||
object.addProperty("official", src.official);
|
||||
|
||||
object.addProperty("group", src.groupId);
|
||||
object.add("tasksOrder", context.serialize(src.tasksOrder));
|
||||
|
||||
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ public class AvatarStatsWidgetProvider extends BaseWidgetProvider {
|
|||
int sp = (int) ((stats.getGp() - gp) * 100);
|
||||
remoteViews.setTextViewText(R.id.gold_tv, String.valueOf(gp));
|
||||
remoteViews.setTextViewText(R.id.silver_tv, String.valueOf(sp));
|
||||
remoteViews.setTextViewText(R.id.gems_tv, String.valueOf((int) (user.getBalance() * 4)));
|
||||
remoteViews.setTextViewText(R.id.gems_tv, String.valueOf(user.getGemCount()));
|
||||
remoteViews.setTextViewText(R.id.lvl_tv, context.getString(R.string.user_level, user.getStats().getLvl()));
|
||||
|
||||
AvatarView avatarView = new AvatarView(context, true, true, true);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.habitrpg.android.habitica.api;
|
|||
|
||||
|
||||
import com.habitrpg.android.habitica.data.implementation.ApiClientImpl;
|
||||
import com.habitrpg.android.habitica.helpers.PopupNotificationsManager;
|
||||
import com.habitrpg.android.habitica.proxy.impl.EmptyCrashlyticsProxy;
|
||||
import com.habitrpg.android.habitica.data.ApiClient;
|
||||
import com.habitrpg.android.habitica.BuildConfig;
|
||||
|
|
@ -39,7 +40,7 @@ public class BaseAPITests {
|
|||
BuildConfig.PORT,
|
||||
"",
|
||||
"");
|
||||
apiClient = new ApiClientImpl(ApiClientImpl.createGsonFactory(), hostConfig, new EmptyCrashlyticsProxy(), context);
|
||||
apiClient = new ApiClientImpl(ApiClientImpl.createGsonFactory(), hostConfig, new EmptyCrashlyticsProxy(), new PopupNotificationsManager(context), context);
|
||||
generateUser();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="store_title">Игронезируйте ваши задачи</string>
|
||||
<string name="store_short_description">Живите играючи и развивайте мотивацию и организованность!</string>
|
||||
<string name="store_description">Относитесь к своей жизни, как к игре, чтобы оставаться мотивированным и организованным! Habitica позволяет легко развлекаться при достижении целей.
|
||||
Введите свои привычки, свои ежедневные цели и список дел, а затем создайте собственный аватар. Выполняйте задачи, чтобы повысить уровень вашего аватара и разблокировать такие функции, как снаряжение, питомцы, навыки и даже квесты! Сражайтесь против монстрами с друзьями, чтобы поддержать друг друга , и использовать свое золото в игре в качестве поощрения, например, на экипировку или специальные награды, или даже на просмотр эпизода вашего любимого телешоу. Гибкая, социальная и веселая, Habitica - это идеальный способ мотивировать себя к чему-либо ».
|
||||
Если у вас есть какие-либо вопросы, не стесняйтесь отправлять их на mobile@habitica.com! А если вам понравится наше приложение, мы будем очень признательны, если вы оставите нам отзыв ».
|
||||
</string>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Reference in a new issue