diff --git a/Habitica/res/layout/activity_task_form.xml b/Habitica/res/layout/activity_task_form.xml
index 82f5f0b12..ad3861b50 100644
--- a/Habitica/res/layout/activity_task_form.xml
+++ b/Habitica/res/layout/activity_task_form.xml
@@ -66,6 +66,16 @@
android:gravity="top"
android:inputType="textCapSentences|textAutoCorrect|textMultiLine"/>
+
Subscription Status
Leave Challenge
- Are you sure you want to leave the Challenge ā%sā?
- Remove tasks
- Do you want to remove the tasks?
+ You can choose to keep this Challenge\'s tasks on your personal task board or delete them when you leave
+ Leave & Keep Tasks
+ Leave & Delete Tasks
Remove
Keep
My Challenges
@@ -1073,4 +1073,13 @@
Use Saddle
Hatch your Pet
Hatch
+ Delete Challenge Task?
+ This is one of %d tasks that are part of the ā%sā Challenge. You must leave the Challenge to delete this task.
+ Leave & Delete Task
+ Leave & Delete %d Tasks
+ Broken Challenge
+ 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?
+ Keep %d Tasks
+ Delete %d Tasks
+ %s Challenge Task
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt
index 7ef1162ca..463ccd96e 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt
@@ -383,4 +383,7 @@ interface ApiService {
@POST("members/transfer-gems")
fun transferGems(@Body data: Map): Flowable>
+
+ @POST("tasks/unlink-all/{challengeID}")
+ fun unlinkAllTasks(@Path("challengeID") challengeID: String?, @Query("keep") keepOption: String): Flowable>
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt
index 3ed6fccbe..795a9e4ce 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt
@@ -258,4 +258,5 @@ interface ApiClient {
fun findUsernames(username: String, context: String?, id: String?): Flowable>
fun transferGems(giftedID: String, amount: Int): Flowable
+ fun unlinkAllTasks(challengeID: String?, keepOption: String): Flowable
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt
index 01026d5ac..05447f8ef 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt
@@ -59,4 +59,6 @@ interface TaskRepository : BaseRepository {
fun retrieveDailiesFromDate(date: Date): Flowable
fun retrieveCompletedTodos(userId: String): Flowable
fun syncErroredTasks(): Single>
+ fun unlinkAllTasks(challengeID: String?, keepOption: String): Flowable
+ fun getTasksForChallenge(challengeID: String?): Flowable>
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt
index 097fdbb91..2e0f91d05 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt
@@ -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 {
+ return apiService.unlinkAllTasks(challengeID, keepOption).compose(configureApiCallObserver())
+ }
+
override fun purchaseItem(type: String, itemKey: String, purchaseQuantity: Int): Flowable {
return apiService.purchaseItem(type, itemKey, mapOf(Pair("quantity", purchaseQuantity))).compose(configureApiCallObserver())
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt
index c8cc35aa8..3899118cd 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt
@@ -307,4 +307,12 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli
}
}.toList()
}
+
+ override fun unlinkAllTasks(challengeID: String?, keepOption: String): Flowable {
+ return apiClient.unlinkAllTasks(challengeID, keepOption)
+ }
+
+ override fun getTasksForChallenge(challengeID: String?): Flowable> {
+ return localRepository.getTasksForChallenge(challengeID)
+ }
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt
index eab649202..826bd03f0 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt
@@ -35,4 +35,5 @@ interface TaskLocalRepository : BaseLocalRepository {
fun saveCompletedTodos(userId: String, tasks: MutableCollection)
fun getErroredTasks(userID: String): Flowable>
fun getUser(userID: String): Flowable
+ fun getTasksForChallenge(challengeID: String?): Flowable>
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt
index 4f6b33ed7..2fb85458d 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt
@@ -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 {
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> {
+ return realm.where(Task::class.java)
+ .equalTo("challengeID", challengeID)
+ .findAll()
+ .asFlowable()
+ .filter { it.isLoaded }
+ .retry(1)
+ }
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt
index b6b579fa5..5f6cf1bde 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt
@@ -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
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.kt
index d1f32b9e3..07bb34cb9 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.kt
@@ -63,16 +63,16 @@ class ChallengeTasksRecyclerViewAdapter(taskFilterHelper: TaskFilterHelper?, lay
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindableViewHolder {
val viewHolder: BindableViewHolder = 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)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/DailiesRecyclerViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/DailiesRecyclerViewHolder.kt
index 147ec2b88..9535f6986 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/DailiesRecyclerViewHolder.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/DailiesRecyclerViewHolder.kt
@@ -12,7 +12,9 @@ class DailiesRecyclerViewHolder(data: OrderedRealmCollection?, 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)
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/HabitsRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/HabitsRecyclerViewAdapter.kt
index 1e41f002f..715e42566 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/HabitsRecyclerViewAdapter.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/HabitsRecyclerViewAdapter.kt
@@ -10,7 +10,9 @@ class HabitsRecyclerViewAdapter(data: OrderedRealmCollection?, 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)
}
}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RealmBaseTasksRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RealmBaseTasksRecyclerViewAdapter.kt
index 40e18dc74..92e8926ae 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RealmBaseTasksRecyclerViewAdapter.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RealmBaseTasksRecyclerViewAdapter.kt
@@ -112,6 +112,8 @@ abstract class RealmBaseTasksRecyclerViewAdapter(
override val checklistItemScoreEvents: Flowable> = checklistItemScoreSubject.toFlowable(BackpressureStrategy.DROP)
protected var taskOpenEventsSubject = PublishSubject.create()
override val taskOpenEvents: Flowable = taskOpenEventsSubject.toFlowable(BackpressureStrategy.DROP)
+ protected var brokenTaskEventsSubject = PublishSubject.create()
+ override val brokenTaskEvents: Flowable = brokenTaskEventsSubject.toFlowable(BackpressureStrategy.DROP)
private val isDataValid: Boolean
get() = data?.isValid ?: false
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt
index deda9fe5e..304ef4c40 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt
@@ -30,6 +30,8 @@ class RewardsRecyclerViewAdapter(private var customRewards: OrderedRealmCollecti
override val checklistItemScoreEvents: Flowable> = checklistItemScoreSubject.toFlowable(BackpressureStrategy.DROP)
private var taskOpenEventsSubject = PublishSubject.create()
override val taskOpenEvents: Flowable = taskOpenEventsSubject.toFlowable(BackpressureStrategy.LATEST)
+ protected var brokenTaskEventsSubject = PublishSubject.create()
+ override val brokenTaskEvents: Flowable = brokenTaskEventsSubject.toFlowable(BackpressureStrategy.DROP)
private var purchaseCardSubject = PublishSubject.create()
val purchaseCardEvents: Flowable = 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))
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/TaskRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/TaskRecyclerViewAdapter.kt
index 7f9a4b5db..1c2a0707e 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/TaskRecyclerViewAdapter.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/TaskRecyclerViewAdapter.kt
@@ -27,4 +27,5 @@ interface TaskRecyclerViewAdapter {
val taskScoreEvents: Flowable>
val checklistItemScoreEvents: Flowable>
val taskOpenEvents: Flowable
+ val brokenTaskEvents: Flowable
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/TodosRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/TodosRecyclerViewAdapter.kt
index 2afcc131d..f735ca531 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/TodosRecyclerViewAdapter.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/TodosRecyclerViewAdapter.kt
@@ -12,8 +12,10 @@ class TodosRecyclerViewAdapter(data: OrderedRealmCollection?, 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)
+ }
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt
index 77a260823..caa1a8649 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt
@@ -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) {
- 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()
- }
- }
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt
index 6fe7dab3e..f8c0aa044 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt
@@ -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 {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt
index 7308bd439..f513ef811 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt
@@ -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)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.kt
index e1d560367..ff9afb9e3 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.kt
@@ -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(itemView), View.OnClickListener {
+abstract class BaseTaskViewHolder constructor(itemView: View, var scoreTaskFunc: ((Task, TaskDirection) -> Unit), var openTaskFunc: ((Task) -> Unit), var brokenTaskFunc: ((Task) -> Unit)) : BindableViewHolder(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) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/ChecklistedViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/ChecklistedViewHolder.kt
index 36b582773..64bee280d 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/ChecklistedViewHolder.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/ChecklistedViewHolder.kt
@@ -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)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.kt
index 366ec5d80..003fd6884 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.kt
@@ -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)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/HabitViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/HabitViewHolder.kt
index 3346c61fb..9d5aecf8c 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/HabitViewHolder.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/HabitViewHolder.kt
@@ -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)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.kt
index 9bc563cda..bc2875d51 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.kt
@@ -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)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/TodoViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/TodoViewHolder.kt
index d7a2fe5f6..240e90203 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/TodoViewHolder.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/TodoViewHolder.kt
@@ -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)