mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-04-14 19:56:32 +00:00
Improve deleting challenge tasks. Fixes #1328
This commit is contained in:
parent
2cce3c685d
commit
5b72add5ef
27 changed files with 166 additions and 49 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 & Keep Tasks</string>
|
||||
<string name="leave_delte_tasks">Leave & 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 & Delete Task</string>
|
||||
<string name="leave_delete_x_tasks">Leave & 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>
|
||||
|
|
|
|||
|
|
@ -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>>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue