mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-04-14 19:56:32 +00:00
implement bulk attribute point allocation. Fixes #821
This commit is contained in:
parent
418b2ee8aa
commit
95b1be7415
10 changed files with 125 additions and 8 deletions
20
Habitica/res/drawable/seekbar_thumb.xml
Normal file
20
Habitica/res/drawable/seekbar_thumb.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:bottom="2dp"
|
||||
android:left="2dp"
|
||||
android:right="2dp"
|
||||
android:top="2dp">
|
||||
<rotate android:fromDegrees="45">
|
||||
<shape>
|
||||
<size
|
||||
android:width="10dp"
|
||||
android:height="10dp" />
|
||||
<solid android:color="@color/white" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/gray_400" />
|
||||
</shape>
|
||||
</rotate>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
|
@ -711,4 +711,5 @@
|
|||
<string name="distribute_evenly_help">Assigns the same number of points to each attribute.</string>
|
||||
<string name="distribute_class_help">Assigns more points to the attributes important to your Class.</string>
|
||||
<string name="distribute_task_help">Assigns points based on the Strength, Intelligence, Constitution, and Perception categories associated with the tasks you complete.</string>
|
||||
<string name="allocating_points">Allocating Points</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -350,4 +350,7 @@ public interface ApiService {
|
|||
|
||||
@POST("user/allocate")
|
||||
Observable<HabitResponse<Stats>> allocatePoint(@Query("stat") String stat);
|
||||
|
||||
@POST("user/allocate-bulk")
|
||||
Observable<HabitResponse<Stats>> bulkAllocatePoints(@Body Map<String, Integer> stats);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,4 +249,6 @@ public interface ApiClient {
|
|||
Observable<Void> updatePassword(String newPassword, String oldPassword, String oldPasswordConfirmation);
|
||||
|
||||
Observable<Stats> allocatePoint(String stat);
|
||||
|
||||
Observable<Stats> bulkAllocatePoints(int strength, int intelligence, int constitution, int perception);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,4 +77,7 @@ public interface UserRepository extends BaseRepository {
|
|||
|
||||
@NotNull
|
||||
Observable<Stats> allocatePoint(@Nullable User user, @Stats.StatsTypes String s);
|
||||
|
||||
@NotNull
|
||||
Observable<Stats> bulkAllocatePoints(int strength, int intelligence, int constitution, int perception);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -986,4 +986,14 @@ public class ApiClientImpl implements Action1<Throwable>, ApiClient {
|
|||
public Observable<Stats> allocatePoint(String stat) {
|
||||
return apiService.allocatePoint(stat).compose(configureApiCallObserver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Stats> bulkAllocatePoints(int strength, int intelligence, int constitution, int perception) {
|
||||
Map<String, Integer> stats = new HashMap<>();
|
||||
stats.put("str", strength);
|
||||
stats.put("int", intelligence);
|
||||
stats.put("con", constitution);
|
||||
stats.put("per", perception);
|
||||
return apiService.bulkAllocatePoints(stats).compose(configureApiCallObserver());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,6 +311,12 @@ public class UserRepositoryImpl extends BaseRepositoryImpl<UserLocalRepository>
|
|||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Observable<Stats> bulkAllocatePoints(int strength, int intelligence, int constitution, int perception) {
|
||||
return apiClient.bulkAllocatePoints(strength, intelligence, constitution, perception);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCron(List<Task> tasks) {
|
||||
Observable<List<TaskScoringResult>> observable;
|
||||
|
|
|
|||
|
|
@ -122,8 +122,11 @@ class StatsFragment: BaseMainFragment() {
|
|||
}
|
||||
|
||||
private fun showBulkAllocateDialog() {
|
||||
val dialog = BulkAllocateStatsDialog(context, HabiticaBaseApplication.getComponent())
|
||||
dialog.show()
|
||||
val context = context
|
||||
if (context != null) {
|
||||
val dialog = BulkAllocateStatsDialog(context, HabiticaBaseApplication.getComponent())
|
||||
dialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun changeAutoAllocationMode(@Stats.AutoAllocationTypes allocationMode: String) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
package com.habitrpg.android.habitica.ui.views
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.app.ProgressDialog
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v7.app.AlertDialog
|
||||
import android.view.LayoutInflater
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
|
|
@ -12,10 +13,11 @@ import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
|||
import com.habitrpg.android.habitica.models.user.User
|
||||
import kotlinx.android.synthetic.main.dialog_bulk_allocate.*
|
||||
import rx.Subscription
|
||||
import rx.functions.Action0
|
||||
import rx.functions.Action1
|
||||
import javax.inject.Inject
|
||||
|
||||
class BulkAllocateStatsDialog(context: Context?, component: AppComponent) : AlertDialog(context) {
|
||||
class BulkAllocateStatsDialog(context: Context, component: AppComponent) : AlertDialog(context) {
|
||||
|
||||
@Inject
|
||||
lateinit var userRepository: UserRepository
|
||||
|
|
@ -62,11 +64,27 @@ class BulkAllocateStatsDialog(context: Context?, component: AppComponent) : Aler
|
|||
val view = inflater.inflate(R.layout.dialog_bulk_allocate, null)
|
||||
|
||||
setView(view)
|
||||
this.setButton(android.support.v7.app.AlertDialog.BUTTON_POSITIVE, context?.getString(R.string.done)) { _, _ ->
|
||||
this.setButton(AlertDialog.BUTTON_POSITIVE, context.getString(R.string.save)) { _, _ ->
|
||||
saveChanges()
|
||||
}
|
||||
this.setButton(AlertDialog.BUTTON_NEUTRAL, context.getString(R.string.action_cancel)) { _, _ ->
|
||||
this.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveChanges() {
|
||||
val progressDialog = ProgressDialog.show(context, context.getString(R.string.allocating_points), null, true)
|
||||
userRepository.bulkAllocatePoints(strengthSliderView.currentValue, intelligenceSliderView.currentValue, constitutionSliderView.currentValue, perceptionSliderView.currentValue)
|
||||
.subscribe({
|
||||
progressDialog.dismiss()
|
||||
this.dismiss()
|
||||
}, {
|
||||
RxErrorHandler.reportError(it)
|
||||
progressDialog.dismiss()
|
||||
this.dismiss()
|
||||
})
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
subscription = userRepository.user.subscribe(Action1 {
|
||||
|
|
@ -74,19 +92,59 @@ class BulkAllocateStatsDialog(context: Context?, component: AppComponent) : Aler
|
|||
}, RxErrorHandler.handleEmptyError())
|
||||
|
||||
strengthSliderView.allocateAction = {
|
||||
checkRedistribution(strengthSliderView)
|
||||
updateTitle()
|
||||
}
|
||||
intelligenceSliderView.allocateAction = {
|
||||
checkRedistribution(intelligenceSliderView)
|
||||
updateTitle()
|
||||
}
|
||||
constitutionSliderView.allocateAction = {
|
||||
checkRedistribution(constitutionSliderView)
|
||||
updateTitle()
|
||||
}
|
||||
perceptionSliderView.allocateAction = {
|
||||
checkRedistribution(perceptionSliderView)
|
||||
updateTitle()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkRedistribution(excludedSlider: StatsSliderView) {
|
||||
val diff = allocatedPoints - pointsToAllocate
|
||||
if (diff > 0) {
|
||||
var highestSlider: StatsSliderView? = null
|
||||
if (excludedSlider != strengthSliderView) {
|
||||
highestSlider = getSliderWithHigherValue(highestSlider, strengthSliderView)
|
||||
}
|
||||
if (excludedSlider != intelligenceSliderView) {
|
||||
highestSlider = getSliderWithHigherValue(highestSlider, intelligenceSliderView)
|
||||
}
|
||||
if (excludedSlider != constitutionSliderView) {
|
||||
highestSlider = getSliderWithHigherValue(highestSlider, constitutionSliderView)
|
||||
}
|
||||
if (excludedSlider != perceptionSliderView) {
|
||||
highestSlider = getSliderWithHigherValue(highestSlider, perceptionSliderView)
|
||||
}
|
||||
if (highestSlider != null) {
|
||||
highestSlider.currentValue -= diff
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSliderWithHigherValue(firstSlider: StatsSliderView?, secondSlider: StatsSliderView?): StatsSliderView? {
|
||||
if (firstSlider == null) {
|
||||
return secondSlider
|
||||
}
|
||||
if (secondSlider == null) {
|
||||
return firstSlider
|
||||
}
|
||||
if (firstSlider.currentValue > secondSlider.currentValue) {
|
||||
return firstSlider
|
||||
} else {
|
||||
return secondSlider
|
||||
}
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
subscription?.unsubscribe()
|
||||
super.dismiss()
|
||||
|
|
@ -99,5 +157,7 @@ class BulkAllocateStatsDialog(context: Context?, component: AppComponent) : Aler
|
|||
} else {
|
||||
titleView.setBackgroundColor(ContextCompat.getColor(context, R.color.gray_400))
|
||||
}
|
||||
|
||||
getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = allocatedPoints > 0
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
package com.habitrpg.android.habitica.ui.views
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.PorterDuff
|
||||
import android.os.Build
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
|
|
@ -11,7 +14,7 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.extensions.styledAttributes
|
||||
import kotlinx.android.synthetic.main.stats_slider_view.view.*
|
||||
|
||||
class StatsSliderView(context: Context?, attrs: AttributeSet?) : LinearLayout(context, attrs) {
|
||||
class StatsSliderView(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) {
|
||||
|
||||
var previousValue = 0
|
||||
set(value) {
|
||||
|
|
@ -44,8 +47,14 @@ class StatsSliderView(context: Context?, attrs: AttributeSet?) : LinearLayout(co
|
|||
statTypeTitle.text = attributes.getString(R.styleable.StatsSliderView_statsTitle)
|
||||
val statColor = attributes.getColor(R.styleable.StatsSliderView_statsColor, 0)
|
||||
statTypeTitle.setTextColor(attributes.getColor(R.styleable.StatsSliderView_statsTextColor, 0))
|
||||
statsSeekBar.progressDrawable.setColorFilter(statColor, PorterDuff.Mode.MULTIPLY)
|
||||
statsSeekBar.thumb.setColorFilter(statColor, PorterDuff.Mode.MULTIPLY)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
statsSeekBar.progressTintList = ColorStateList.valueOf(statColor)
|
||||
} else {
|
||||
statsSeekBar.progressDrawable.setColorFilter(statColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
val thumbDrawable = ContextCompat.getDrawable(context, R.drawable.seekbar_thumb)
|
||||
thumbDrawable?.setColorFilter(statColor, PorterDuff.Mode.MULTIPLY)
|
||||
statsSeekBar.thumb = thumbDrawable
|
||||
}
|
||||
|
||||
statsSeekBar.setOnSeekBarChangeListener(object: SeekBar.OnSeekBarChangeListener {
|
||||
|
|
|
|||
Loading…
Reference in a new issue