Improve deleting challenge tasks. Fixes #1328

This commit is contained in:
Phillip Thelen 2020-07-21 17:53:55 +02:00
parent 2cce3c685d
commit 5b72add5ef
27 changed files with 166 additions and 49 deletions

View file

@ -66,6 +66,16 @@
android:gravity="top"
android:inputType="textCapSentences|textAutoCorrect|textMultiLine"/>
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/challenge_name_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
style="@style/Caption1"
android:gravity="center"
android:textColor="@color/gray_10"
tools:visibility="visible"
tools:text="Challenge Name"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"

View file

@ -25,6 +25,7 @@
android:layout_height="@dimen/avatar_header_height"
android:layout_gravity="center_vertical"
android:layout_marginEnd="20dp"
android:layout_marginStart="2dp"
android:contentDescription="@string/sidebar_avatar"
app:showBackground="true"
app:showMount="true"

View file

@ -437,9 +437,9 @@
<string name="subscription_status">Subscription Status</string>
<string name="challenge_leave_title">Leave Challenge</string>
<string name="challenge_leave_text">Are you sure you want to leave the Challenge “%s”?</string>
<string name="challenge_remove_tasks_title">Remove tasks</string>
<string name="challenge_remove_tasks_text">Do you want to remove the tasks?</string>
<string name="challenge_leave_description">You can choose to keep this Challenge\'s tasks on your personal task board or delete them when you leave</string>
<string name="leave_keep_tasks">Leave &amp; Keep Tasks</string>
<string name="leave_delte_tasks">Leave &amp; Delete Tasks</string>
<string name="remove_tasks">Remove</string>
<string name="keep_tasks">Keep</string>
<string name="my_challenges">My Challenges</string>
@ -1073,4 +1073,13 @@
<string name="use_saddle">Use Saddle</string>
<string name="hatch_your_pet">Hatch your Pet</string>
<string name="hatch">Hatch</string>
<string name="delete_challenge_task_title">Delete Challenge Task?</string>
<string name="delete_challenge_task_description">This is one of %d tasks that are part of the “%s” Challenge. You must leave the Challenge to delete this task.</string>
<string name="leave_delete_task">Leave &amp; Delete Task</string>
<string name="leave_delete_x_tasks">Leave &amp; Delete %d Tasks</string>
<string name="broken_challenge">Broken Challenge</string>
<string name="broken_challenge_description">This is one of %d tasks that are part of a Challenge that no longer exists. What would you like to do with these left over tasks?</string>
<string name="keep_x_tasks">Keep %d Tasks</string>
<string name="delete_x_tasks">Delete %d Tasks</string>
<string name="challenge_task_name">%s Challenge Task</string>
</resources>

View file

@ -383,4 +383,7 @@ interface ApiService {
@POST("members/transfer-gems")
fun transferGems(@Body data: Map<String, Any>): Flowable<HabitResponse<Void>>
@POST("tasks/unlink-all/{challengeID}")
fun unlinkAllTasks(@Path("challengeID") challengeID: String?, @Query("keep") keepOption: String): Flowable<HabitResponse<Void>>
}

View file

@ -258,4 +258,5 @@ interface ApiClient {
fun findUsernames(username: String, context: String?, id: String?): Flowable<List<FindUsernameResult>>
fun transferGems(giftedID: String, amount: Int): Flowable<Void>
fun unlinkAllTasks(challengeID: String?, keepOption: String): Flowable<Void>
}

View file

@ -59,4 +59,6 @@ interface TaskRepository : BaseRepository {
fun retrieveDailiesFromDate(date: Date): Flowable<TaskList>
fun retrieveCompletedTodos(userId: String): Flowable<TaskList>
fun syncErroredTasks(): Single<List<Task>>
fun unlinkAllTasks(challengeID: String?, keepOption: String): Flowable<Void>
fun getTasksForChallenge(challengeID: String?): Flowable<RealmResults<Task>>
}

View file

@ -332,6 +332,10 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener;
return apiService.buyItem(itemKey, mapOf(Pair("quantity", purchaseQuantity))).compose(configureApiCallObserver())
}
override fun unlinkAllTasks(challengeID: String?, keepOption: String): Flowable<Void> {
return apiService.unlinkAllTasks(challengeID, keepOption).compose(configureApiCallObserver())
}
override fun purchaseItem(type: String, itemKey: String, purchaseQuantity: Int): Flowable<Any> {
return apiService.purchaseItem(type, itemKey, mapOf(Pair("quantity", purchaseQuantity))).compose(configureApiCallObserver())
}

View file

@ -307,4 +307,12 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli
}
}.toList()
}
override fun unlinkAllTasks(challengeID: String?, keepOption: String): Flowable<Void> {
return apiClient.unlinkAllTasks(challengeID, keepOption)
}
override fun getTasksForChallenge(challengeID: String?): Flowable<RealmResults<Task>> {
return localRepository.getTasksForChallenge(challengeID)
}
}

View file

@ -35,4 +35,5 @@ interface TaskLocalRepository : BaseLocalRepository {
fun saveCompletedTodos(userId: String, tasks: MutableCollection<Task>)
fun getErroredTasks(userID: String): Flowable<RealmResults<Task>>
fun getUser(userID: String): Flowable<User>
fun getTasksForChallenge(challengeID: String?): Flowable<RealmResults<Task>>
}

View file

@ -225,7 +225,8 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
.findAll()
.asFlowable()
.filter { it.isLoaded }
.retry(1) }
.retry(1)
}
override fun getUser(userID: String): Flowable<User> {
return realm.where(User::class.java)
@ -235,4 +236,13 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
.filter { realmObject -> realmObject.isLoaded && realmObject.isValid && !realmObject.isEmpty() }
.map { users -> users.first() }
}
override fun getTasksForChallenge(challengeID: String?): Flowable<RealmResults<Task>> {
return realm.where(Task::class.java)
.equalTo("challengeID", challengeID)
.findAll()
.asFlowable()
.filter { it.isLoaded }
.retry(1)
}
}

View file

@ -21,9 +21,7 @@ import androidx.core.view.forEachIndexed
import androidx.core.widget.NestedScrollView
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.components.UserComponent
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.*
import com.habitrpg.android.habitica.extensions.OnChangeTextWatcher
import com.habitrpg.android.habitica.extensions.addCancelButton
import com.habitrpg.android.habitica.extensions.dpToPx
@ -31,6 +29,7 @@ import com.habitrpg.android.habitica.extensions.getThemeColor
import com.habitrpg.android.habitica.helpers.RxErrorHandler
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
import com.habitrpg.android.habitica.models.Tag
import com.habitrpg.android.habitica.models.social.Challenge
import com.habitrpg.android.habitica.models.tasks.HabitResetOption
import com.habitrpg.android.habitica.models.tasks.Task
import com.habitrpg.android.habitica.models.user.Stats
@ -55,6 +54,8 @@ class TaskFormActivity : BaseActivity() {
lateinit var tagRepository: TagRepository
@Inject
lateinit var taskAlarmManager: TaskAlarmManager
@Inject
lateinit var challengeRepository: ChallengeRepository
private val toolbar: Toolbar by bindView(R.id.toolbar)
private val scrollView: NestedScrollView by bindView(R.id.scroll_view)
@ -90,6 +91,10 @@ class TaskFormActivity : BaseActivity() {
private val tagsTitleView: TextView by bindView(R.id.tags_title)
private val tagsWrapper: LinearLayout by bindView(R.id.tags_wrapper)
private val challengeNameView: TextView by bindView(R.id.challenge_name_view)
private var challenge: Challenge? = null
private var isCreating = true
private var isChallengeTask = false
private var usesTaskAttributeStats = false
@ -193,6 +198,13 @@ class TaskFormActivity : BaseActivity() {
task = it
//tintColor = ContextCompat.getColor(this, it.mediumTaskColor)
fillForm(it)
task?.challengeID?.let {
compositeSubscription.add(challengeRepository.retrieveChallenge(it).subscribe(Consumer {
challenge = it
challengeNameView.text = getString(R.string.challenge_task_name, it.name)
challengeNameView.visibility = View.VISIBLE
}, RxErrorHandler.handleEmptyError()))
}
}, RxErrorHandler.handleEmptyError()))
}
bundle.containsKey(PARCELABLE_TASK) -> {
@ -464,6 +476,10 @@ class TaskFormActivity : BaseActivity() {
}
private fun deleteTask() {
if (task?.challengeID?.isNotBlank() == true && task?.challengeBroken?.isNotBlank() != true) {
showChallengeDeleteTask()
return
}
val alert = HabiticaAlertDialog(this)
alert.setTitle(R.string.are_you_sure)
alert.addButton(R.string.delete_task, true) { _, _ ->
@ -476,6 +492,36 @@ class TaskFormActivity : BaseActivity() {
alert.show()
}
private fun showChallengeDeleteTask() {
compositeSubscription.add(taskRepository.getTasksForChallenge(task?.challengeID).subscribe(Consumer { tasks ->
val taskCount = tasks.size
val alert = HabiticaAlertDialog(this)
alert.setTitle(getString(R.string.delete_challenge_task_title))
alert.setMessage(getString(R.string.delete_challenge_task_description, taskCount, challenge?.name ?: ""))
alert.addButton(R.string.leave_delete_task, true, true) { _, _ ->
challenge?.let {
compositeSubscription.add(challengeRepository.leaveChallenge(it, "keep-all")
.flatMap { taskRepository.deleteTask(task?.id ?: "") }
.flatMap { userRepository.retrieveUser(true) }
.subscribe(Consumer {
finish()
}, RxErrorHandler.handleEmptyError()))
}
}
alert.addButton(getString(R.string.leave_delete_x_tasks, taskCount), false, true) { _, _ ->
challenge?.let {
compositeSubscription.add(challengeRepository.leaveChallenge(it, "remove-all")
.flatMap { userRepository.retrieveUser(true) }
.subscribe(Consumer {
finish()
}, RxErrorHandler.handleEmptyError()))
}
}
alert.setExtraCloseButtonVisibility(View.VISIBLE)
alert.show()
}, RxErrorHandler.handleEmptyError()))
}
private fun dismissKeyboard() {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
val currentFocus = currentFocus

View file

@ -63,16 +63,16 @@ class ChallengeTasksRecyclerViewAdapter(taskFilterHelper: TaskFilterHelper?, lay
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindableViewHolder<Task> {
val viewHolder: BindableViewHolder<Task> = when (viewType) {
TYPE_HABIT -> HabitViewHolder(getContentView(parent, R.layout.habit_item_card), { _, _ -> }) { task ->
TYPE_HABIT -> HabitViewHolder(getContentView(parent, R.layout.habit_item_card), { _, _ -> }, { }) { task ->
taskOpenEventsSubject.onNext(task)
}
TYPE_DAILY -> DailyViewHolder(getContentView(parent, R.layout.daily_item_card), { _, _ -> }, { _, _ -> }) { task ->
TYPE_DAILY -> DailyViewHolder(getContentView(parent, R.layout.daily_item_card), { _, _ -> }, { _, _ -> }, { }) { task ->
taskOpenEventsSubject.onNext(task)
}
TYPE_TODO -> TodoViewHolder(getContentView(parent, R.layout.todo_item_card), { _, _ -> }, { _, _ -> }) { task ->
TYPE_TODO -> TodoViewHolder(getContentView(parent, R.layout.todo_item_card), { _, _ -> }, { _, _ -> }, { }) { task ->
taskOpenEventsSubject.onNext(task)
}
TYPE_REWARD -> RewardViewHolder(getContentView(parent, R.layout.reward_item_card), { _, _ -> }) { task ->
TYPE_REWARD -> RewardViewHolder(getContentView(parent, R.layout.reward_item_card), { _, _ -> }, { }) { task ->
taskOpenEventsSubject.onNext(task)
}
TYPE_ADD_ITEM -> AddItemViewHolder(getContentView(parent, R.layout.challenge_add_task_item), addItemSubject)

View file

@ -12,7 +12,9 @@ class DailiesRecyclerViewHolder(data: OrderedRealmCollection<Task>?, autoUpdate:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DailyViewHolder =
DailyViewHolder(getContentView(parent), { task, direction -> taskScoreEventsSubject.onNext(Pair(task, direction)) },
{ task, item -> checklistItemScoreSubject.onNext(Pair(task, item))}) {
{ task, item -> checklistItemScoreSubject.onNext(Pair(task, item))}, {
task -> taskOpenEventsSubject.onNext(task)
}) {
task -> brokenTaskEventsSubject.onNext(task)
}
}

View file

@ -10,7 +10,9 @@ class HabitsRecyclerViewAdapter(data: OrderedRealmCollection<Task>?, autoUpdate:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HabitViewHolder =
HabitViewHolder(getContentView(parent), { task, direction -> taskScoreEventsSubject.onNext(Pair(task, direction)) }) {
HabitViewHolder(getContentView(parent), { task, direction -> taskScoreEventsSubject.onNext(Pair(task, direction)) }, {
task -> taskOpenEventsSubject.onNext(task)
}) {
task -> brokenTaskEventsSubject.onNext(task)
}
}

View file

@ -112,6 +112,8 @@ abstract class RealmBaseTasksRecyclerViewAdapter<VH : BaseTaskViewHolder>(
override val checklistItemScoreEvents: Flowable<Pair<Task, ChecklistItem>> = checklistItemScoreSubject.toFlowable(BackpressureStrategy.DROP)
protected var taskOpenEventsSubject = PublishSubject.create<Task>()
override val taskOpenEvents: Flowable<Task> = taskOpenEventsSubject.toFlowable(BackpressureStrategy.DROP)
protected var brokenTaskEventsSubject = PublishSubject.create<Task>()
override val brokenTaskEvents: Flowable<Task> = brokenTaskEventsSubject.toFlowable(BackpressureStrategy.DROP)
private val isDataValid: Boolean
get() = data?.isValid ?: false

View file

@ -30,6 +30,8 @@ class RewardsRecyclerViewAdapter(private var customRewards: OrderedRealmCollecti
override val checklistItemScoreEvents: Flowable<Pair<Task, ChecklistItem>> = checklistItemScoreSubject.toFlowable(BackpressureStrategy.DROP)
private var taskOpenEventsSubject = PublishSubject.create<Task>()
override val taskOpenEvents: Flowable<Task> = taskOpenEventsSubject.toFlowable(BackpressureStrategy.LATEST)
protected var brokenTaskEventsSubject = PublishSubject.create<Task>()
override val brokenTaskEvents: Flowable<Task> = brokenTaskEventsSubject.toFlowable(BackpressureStrategy.DROP)
private var purchaseCardSubject = PublishSubject.create<ShopItem>()
val purchaseCardEvents: Flowable<ShopItem> = purchaseCardSubject.toFlowable(BackpressureStrategy.LATEST)
@ -64,8 +66,10 @@ class RewardsRecyclerViewAdapter(private var customRewards: OrderedRealmCollecti
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == VIEWTYPE_CUSTOM_REWARD) {
RewardViewHolder(getContentView(parent), { task, direction -> taskScoreEventsSubject.onNext(Pair(task, direction)) }) {
RewardViewHolder(getContentView(parent), { task, direction -> taskScoreEventsSubject.onNext(Pair(task, direction)) }, {
task -> taskOpenEventsSubject.onNext(task)
}) {
task -> brokenTaskEventsSubject.onNext(task)
}
} else {
val viewHolder = ShopItemViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.row_shopitem, parent, false))

View file

@ -27,4 +27,5 @@ interface TaskRecyclerViewAdapter {
val taskScoreEvents: Flowable<Pair<Task, TaskDirection>>
val checklistItemScoreEvents: Flowable<Pair<Task, ChecklistItem>>
val taskOpenEvents: Flowable<Task>
val brokenTaskEvents: Flowable<Task>
}

View file

@ -12,8 +12,10 @@ class TodosRecyclerViewAdapter(data: OrderedRealmCollection<Task>?, autoUpdate:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder =
TodoViewHolder(getContentView(parent), { task, direction -> taskScoreEventsSubject.onNext(Pair(task, direction)) },
{ task, item -> checklistItemScoreSubject.onNext(Pair(task, item))}) {
task -> taskOpenEventsSubject.onNext(task)
}
{ task, item -> checklistItemScoreSubject.onNext(Pair(task, item))}, {
task -> taskOpenEventsSubject.onNext(task)
}) {
task -> brokenTaskEventsSubject.onNext(task)
}
}

View file

@ -353,34 +353,16 @@ class ChallengeDetailFragment: BaseMainFragment() {
val context = context ?: return
val alert = HabiticaAlertDialog(context)
alert.setTitle(this.getString(R.string.challenge_leave_title))
alert.setMessage(this.getString(R.string.challenge_leave_text, challenge?.name ?: ""))
alert.addButton(R.string.yes, true) { dialog, _ ->
dialog.dismiss()
showRemoveTasksDialog(Consumer { keepTasks ->
val challenge = challenge ?: return@Consumer
challengeRepository.leaveChallenge(challenge, keepTasks).subscribe(Consumer {}, RxErrorHandler.handleEmptyError())
})
alert.setMessage(this.getString(R.string.challenge_leave_description))
alert.addButton(R.string.leave_keep_tasks, true) { dialog, _ ->
val challenge = challenge ?: return@addButton
challengeRepository.leaveChallenge(challenge, "keep-all").subscribe(Consumer {}, RxErrorHandler.handleEmptyError())
}
alert.addButton(R.string.no, false) { dialog, _ ->
dialog.dismiss()
alert.addButton(R.string.leave_delte_tasks, false, true) { dialog, _ ->
val challenge = challenge ?: return@addButton
challengeRepository.leaveChallenge(challenge, "remove-all").subscribe(Consumer {}, RxErrorHandler.handleEmptyError())
}
alert.setExtraCloseButtonVisibility(View.VISIBLE)
alert.show()
}
private fun showRemoveTasksDialog(callback: Consumer<String>) {
context?.let {
val alert = HabiticaAlertDialog(it)
alert.setTitle(this.getString(R.string.challenge_remove_tasks_title))
alert.setMessage(this.getString(R.string.challenge_remove_tasks_text))
alert.addButton(R.string.remove_tasks, false) { dialog, _ ->
callback.accept("remove-all")
dialog.dismiss()
}
alert.addButton(R.string.keep_tasks, false) { dialog, _ ->
callback.accept("keep-all")
dialog.dismiss()
}
alert.show()
}
}
}

View file

@ -61,6 +61,7 @@ class RewardsRecyclerviewFragment : TaskRecyclerViewFragment() {
val intent = Intent(activity, SkillMemberActivity::class.java)
startActivityForResult(intent, 11)
}, RxErrorHandler.handleEmptyError())?.let { compositeSubscription.add(it) }
recyclerAdapter?.brokenTaskEvents?.subscribeWithErrorHandler(Consumer { showBrokenChallengeDialog(it) })?.let { compositeSubscription.add(it) }
}
override fun getLayoutManager(context: Context?): LinearLayoutManager {

View file

@ -38,6 +38,7 @@ import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
import com.habitrpg.android.habitica.ui.viewHolders.tasks.BaseTaskViewHolder
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import java.util.*
@ -262,6 +263,7 @@ open class TaskRecyclerViewFragment : BaseFragment(), androidx.swiperefreshlayou
recyclerAdapter?.checklistItemScoreEvents
?.flatMap { taskRepository.scoreChecklistItem(it.first.id ?: "", it.second.id ?: "")
}?.subscribeWithErrorHandler(Consumer {})?.let { compositeSubscription.add(it) }
recyclerAdapter?.brokenTaskEvents?.subscribeWithErrorHandler(Consumer { showBrokenChallengeDialog(it) })?.let { compositeSubscription.add(it) }
}
val bottomPadding = (binding.recyclerView.paddingBottom + TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60f, resources.displayMetrics)).toInt()
@ -287,6 +289,25 @@ open class TaskRecyclerViewFragment : BaseFragment(), androidx.swiperefreshlayou
}
}
protected fun showBrokenChallengeDialog(task: Task) {
context?.let {
taskRepository.getTasksForChallenge(task.challengeID).subscribe(Consumer { tasks ->
val taskCount = tasks.size
val dialog = HabiticaAlertDialog(it)
dialog.setTitle(R.string.broken_challenge)
dialog.setMessage(it.getString(R.string.broken_challenge_description, taskCount))
dialog.addButton(it.getString(R.string.keep_x_tasks, taskCount), true) { _, _ ->
taskRepository.unlinkAllTasks(task.challengeID, "keep-all").subscribe(Consumer {}, RxErrorHandler.handleEmptyError())
}
dialog.addButton(it.getString(R.string.delete_x_tasks, taskCount), false, true) { _, _ ->
taskRepository.unlinkAllTasks(task.challengeID, "remove-all").subscribe(Consumer {}, RxErrorHandler.handleEmptyError())
}
dialog.setExtraCloseButtonVisibility(View.VISIBLE)
dialog.show()
}, RxErrorHandler.handleEmptyError())
}
}
private fun setEmptyLabels() {
if (this.classType != null) {
binding.recyclerView.setEmptyView(binding.emptyView)

View file

@ -20,7 +20,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
abstract class BaseTaskViewHolder constructor(itemView: View, var scoreTaskFunc: ((Task, TaskDirection) -> Unit), var openTaskFunc: ((Task) -> Unit)) : BindableViewHolder<Task>(itemView), View.OnClickListener {
abstract class BaseTaskViewHolder constructor(itemView: View, var scoreTaskFunc: ((Task, TaskDirection) -> Unit), var openTaskFunc: ((Task) -> Unit), var brokenTaskFunc: ((Task) -> Unit)) : BindableViewHolder<Task>(itemView), View.OnClickListener {
var task: Task? = null
@ -80,6 +80,11 @@ abstract class BaseTaskViewHolder constructor(itemView: View, var scoreTaskFunc:
//titleTextView.movementMethod = LinkMovementMethod.getInstance()
expandNotesButton?.setOnClickListener { expandTask() }
iconViewChallenge?.setOnClickListener {
task?.let { t ->
if (task?.challengeBroken?.isNotBlank() == true) brokenTaskFunc(t)
}
}
notesTextView?.addEllipsesListener(object : EllipsisTextView.EllipsisListener {
override fun ellipsisStateChanged(ellipses: Boolean) {
GlobalScope.launch(Dispatchers.Main.immediate) {

View file

@ -25,7 +25,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
abstract class ChecklistedViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> Unit), var scoreChecklistItemFunc: ((Task, ChecklistItem) -> Unit), openTaskFunc: ((Task) -> Unit)) : BaseTaskViewHolder(itemView, scoreTaskFunc, openTaskFunc), CompoundButton.OnCheckedChangeListener {
abstract class ChecklistedViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> Unit), var scoreChecklistItemFunc: ((Task, ChecklistItem) -> Unit), openTaskFunc: ((Task) -> Unit), brokenTaskFunc: ((Task) -> Unit)) : BaseTaskViewHolder(itemView, scoreTaskFunc, openTaskFunc, brokenTaskFunc), CompoundButton.OnCheckedChangeListener {
private val checkboxHolder: ViewGroup by bindView(itemView, R.id.checkBoxHolder)
internal val checkbox: CheckBox by bindView(itemView, R.id.checkBox)

View file

@ -10,7 +10,7 @@ import com.habitrpg.android.habitica.ui.helpers.bindView
import java.text.DateFormat
import java.util.*
class DailyViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> Unit), scoreChecklistItemFunc: ((Task, ChecklistItem) -> Unit), openTaskFunc: ((Task) -> Unit)) : ChecklistedViewHolder(itemView, scoreTaskFunc, scoreChecklistItemFunc, openTaskFunc) {
class DailyViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> Unit), scoreChecklistItemFunc: ((Task, ChecklistItem) -> Unit), openTaskFunc: ((Task) -> Unit), brokenTaskFunc: ((Task) -> Unit)) : ChecklistedViewHolder(itemView, scoreTaskFunc, scoreChecklistItemFunc, openTaskFunc, brokenTaskFunc) {
private val streakTextView: TextView by bindView(itemView, R.id.streakTextView)
private val reminderTextView: TextView by bindView(itemView, R.id.reminder_textview)

View file

@ -10,7 +10,7 @@ import com.habitrpg.android.habitica.models.responses.TaskDirection
import com.habitrpg.android.habitica.models.tasks.Task
import com.habitrpg.android.habitica.ui.helpers.bindView
class HabitViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> Unit), openTaskFunc: ((Task) -> Unit)) : BaseTaskViewHolder(itemView, scoreTaskFunc, openTaskFunc) {
class HabitViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> Unit), openTaskFunc: ((Task) -> Unit), brokenTaskFunc: ((Task) -> Unit)) : BaseTaskViewHolder(itemView, scoreTaskFunc, openTaskFunc, brokenTaskFunc) {
private val btnPlusWrapper: FrameLayout by bindView(itemView, R.id.btnPlusWrapper)
private val btnPlusIconView: ImageView by bindView(itemView, R.id.btnPlusIconView)

View file

@ -13,7 +13,7 @@ import com.habitrpg.android.habitica.ui.ItemDetailDialog
import com.habitrpg.android.habitica.ui.helpers.bindView
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
class RewardViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> Unit), openTaskFunc: ((Task) -> Unit)) : BaseTaskViewHolder(itemView, scoreTaskFunc, openTaskFunc) {
class RewardViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> Unit), openTaskFunc: ((Task) -> Unit), brokenTaskFunc: ((Task) -> Unit)) : BaseTaskViewHolder(itemView, scoreTaskFunc, openTaskFunc, brokenTaskFunc) {
private val buyButton: View by bindView(itemView, R.id.buyButton)
internal val priceLabel: TextView by bindView(itemView, R.id.priceLabel)

View file

@ -8,7 +8,7 @@ import com.habitrpg.android.habitica.models.tasks.Task
import java.text.DateFormat
class TodoViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> Unit), scoreChecklistItemFunc: ((Task, ChecklistItem) -> Unit), openTaskFunc: ((Task) -> Unit)) : ChecklistedViewHolder(itemView, scoreTaskFunc, scoreChecklistItemFunc, openTaskFunc) {
class TodoViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> Unit), scoreChecklistItemFunc: ((Task, ChecklistItem) -> Unit), openTaskFunc: ((Task) -> Unit), brokenTaskFunc: ((Task) -> Unit)) : ChecklistedViewHolder(itemView, scoreTaskFunc, scoreChecklistItemFunc, openTaskFunc, brokenTaskFunc) {
private val dateFormatter: DateFormat = android.text.format.DateFormat.getDateFormat(context)