diff --git a/.tx/config b/.tx/config index 69b82749a..a5d996740 100644 --- a/.tx/config +++ b/.tx/config @@ -30,3 +30,4 @@ file_filter = Habitica/res/values-/strings.xml source_file = Habitica/res/values/strings.xml source_lang = en type = ANDROID + diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml index bb8ad7aa5..84c486967 100644 --- a/Habitica/AndroidManifest.xml +++ b/Habitica/AndroidManifest.xml @@ -161,9 +161,7 @@ android:value=".ui.activities.MainActivity" /> - val updatedItem: ChecklistItem? = task.checklist.lastOrNull { itemId == it.id } + val updatedItem: ChecklistItem? = task.checklist?.lastOrNull { itemId == it.id } if (updatedItem != null) { localRepository.executeTransaction { updatedItem.completed = !updatedItem.completed } } @@ -132,18 +132,27 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli return Observable.just(task) } lastTaskAction = now - if (task.tags.size > 0) { - val tags = RealmList(*localRepository.getUnmanagedCopy(task.tags).toTypedArray()) - task.tags = tags + task.tags?.let { + if (it.size > 0) { + val tags = RealmList(*localRepository.getUnmanagedCopy(it).toTypedArray()) + task.tags = tags + } } - if (task.checklist.size > 0) { - val checklist = RealmList(*localRepository.getUnmanagedCopy(task.checklist).toTypedArray()) - task.checklist = checklist + + task.checklist?.let { + if (it.size > 0) { + val checklist = RealmList(*localRepository.getUnmanagedCopy(it).toTypedArray()) + task.checklist = checklist + } } - if (task.reminders.size > 0) { - val reminders = RealmList(*localRepository.getUnmanagedCopy(task.reminders).toTypedArray()) - task.reminders = reminders + + task.reminders?.let { + if (it.size > 0) { + val reminders = RealmList(*localRepository.getUnmanagedCopy(it).toTypedArray()) + task.reminders = reminders + } } + return apiClient.createTask(task) .map { task1 -> task1.dateCreated = Date() @@ -158,10 +167,7 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli return Observable.just(task) } lastTaskAction = now - val id = task.id - if (id == null) { - return Observable.just(task) - } + val id = task.id ?: return Observable.just(task) return localRepository.getTaskCopy(id).first() .flatMap { task1 -> apiClient.updateTask(id, task1) } .map { task1 -> 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 6d9cad9d0..7585400a2 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 @@ -40,16 +40,13 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), removeOldTasks(userId, sortedTasks) val allChecklistItems = ArrayList() - for (t in sortedTasks) { - allChecklistItems.addAll(t.checklist) - } + sortedTasks.forEach { it.checklist?.let { it1 -> allChecklistItems.addAll(it1) } } removeOldChecklists(allChecklistItems) val allReminders = ArrayList() - for (t in sortedTasks) { - allReminders.addAll(t.reminders) - } + sortedTasks.forEach { it.reminders?.let { it1 -> allReminders.addAll(it1) } } removeOldReminders(allReminders) + realm.executeTransactionAsync { realm1 -> realm1.insertOrUpdate(sortedTasks) } } @@ -93,8 +90,8 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), val tasksToDelete = localTasks.filterNot { onlineTaskList.contains(it) } realm.executeTransaction { for (localTask in tasksToDelete) { - localTask.checklist.deleteAllFromRealm() - localTask.reminders.deleteAllFromRealm() + localTask.checklist?.deleteAllFromRealm() + localTask.reminders?.deleteAllFromRealm() localTask.deleteFromRealm() } } @@ -110,8 +107,8 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), val tasksToDelete = localTasks.filterNot { onlineTaskList.contains(it) } realm.executeTransaction { for (localTask in tasksToDelete) { - localTask.checklist.deleteAllFromRealm() - localTask.reminders.deleteAllFromRealm() + localTask.checklist?.deleteAllFromRealm() + localTask.reminders?.deleteAllFromRealm() localTask.deleteFromRealm() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt index 82fed7258..a414f0958 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt @@ -4,6 +4,7 @@ import com.habitrpg.android.habitica.data.local.UserLocalRepository import com.habitrpg.android.habitica.models.Skill import com.habitrpg.android.habitica.models.Tag import com.habitrpg.android.habitica.models.TutorialStep +import com.habitrpg.android.habitica.models.social.Challenge import com.habitrpg.android.habitica.models.social.ChatMessage import com.habitrpg.android.habitica.models.user.User import io.realm.Realm @@ -40,6 +41,9 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), if (user.tags != null) { removeOldTags(user.id, user.tags) } + if (user.challenges != null) { + removeOldChallenges(user.id, user.challenges) + } } private fun removeOldTags(userId: String, onlineTags: List) { @@ -52,6 +56,16 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), } } + private fun removeOldChallenges(userId: String, onlineChallenges: List) { + val challenges = realm.where(Challenge::class.java).equalTo("userId", userId).findAll().createSnapshot() + val challengesToDelete = challenges.filterNot { onlineChallenges.contains(it) } + realm.executeTransaction { + for (challenge in challengesToDelete) { + challenge.isParticipating = false + } + } + } + override fun getSkills(user: User): Observable> { val habitClass = if (user.preferences.disableClasses) "none" else user.stats.habitClass return realm.where(Skill::class.java) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt index e64543eb5..70a17626a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt @@ -33,21 +33,24 @@ class TaskAlarmManager(private var context: Context, private var taskRepository: } private fun setAlarmsForTask(task: Task) { - val reminders = task.reminders - for (reminder in reminders) { - var currentReminder = reminder - if (task.type == Task.TYPE_DAILY) { - //Ensure that we set to the next available time - currentReminder = this.setTimeForDailyReminder(currentReminder, task) + task.reminders?.let { + for (reminder in it) { + var currentReminder = reminder + if (task.type == Task.TYPE_DAILY) { + //Ensure that we set to the next available time + currentReminder = this.setTimeForDailyReminder(currentReminder, task) + } + this.setAlarmForRemindersItem(task, currentReminder) } - this.setAlarmForRemindersItem(task, currentReminder) } + } private fun removeAlarmsForTask(task: Task) { - val reminders = task.reminders - for (reminder in reminders) { - this.removeAlarmForRemindersItem(reminder) + task.reminders?.let { + for (reminder in it) { + this.removeAlarmForRemindersItem(reminder) + } } } @@ -78,12 +81,12 @@ class TaskAlarmManager(private var context: Context, private var taskRepository: } private fun setTimeForDailyReminder(remindersItem: RemindersItem?, task: Task): RemindersItem? { - val oldTime = remindersItem!!.time + val oldTime = remindersItem?.time val newTime = task.getNextReminderOccurence(oldTime) ?: return null val calendar = Calendar.getInstance() calendar.time = newTime - calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), oldTime.hours, oldTime.minutes, 0) - remindersItem.time = calendar.time + calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), oldTime?.hours ?: 0, oldTime?.minutes ?: 0, 0) + remindersItem?.time = calendar.time return remindersItem } @@ -124,20 +127,18 @@ class TaskAlarmManager(private var context: Context, private var taskRepository: val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager sender.cancel() am.cancel(sender) - } companion object { - val TASK_ID_INTENT_KEY = "TASK_ID" - val TASK_NAME_INTENT_KEY = "TASK_NAME" + const val TASK_ID_INTENT_KEY = "TASK_ID" + const val TASK_NAME_INTENT_KEY = "TASK_NAME" fun scheduleDailyReminder(context: Context?) { val prefs = PreferenceManager.getDefaultSharedPreferences(context) if (prefs.getBoolean("use_reminder", false)) { - val timeval = prefs.getString("reminder_time", "19:00") - val pieces = timeval!!.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + val pieces = timeval?.split(":".toRegex())?.dropLastWhile { it.isEmpty() }?.toTypedArray() ?: return val hour = Integer.parseInt(pieces[0]) val minute = Integer.parseInt(pieces[1]) val cal = Calendar.getInstance() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt index ae69b950d..3834440e5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt @@ -28,7 +28,7 @@ open class Task : RealmObject, Parcelable { @Stats.StatsTypes var attribute: String? = Stats.STRENGTH var value: Double = 0.0 - var tags: RealmList = RealmList() + var tags: RealmList? = RealmList() var dateCreated: Date? = null var position: Int? = 0 var group: TaskGroupPlan? = null @@ -39,8 +39,8 @@ open class Task : RealmObject, Parcelable { var counterDown: Int? = 0 //todos/dailies var completed: Boolean = false - var checklist: RealmList = RealmList() - var reminders: RealmList = RealmList() + var checklist: RealmList? = RealmList() + var reminders: RealmList? = RealmList() //dailies var frequency: String? = null var everyX: Int? = 0 @@ -83,7 +83,7 @@ open class Task : RealmObject, Parcelable { private var weeksOfMonth: MutableList? = null val completedChecklistCount: Int - get() = checklist.count { it.completed } + get() = checklist?.count { it.completed } ?: 0 val lightTaskColor: Int get() { @@ -128,7 +128,7 @@ open class Task : RealmObject, Parcelable { get() = isDue == true && !completed val isChecklistDisplayActive: Boolean - get() = this.isDisplayedActive && this.checklist.size != this.completedChecklistCount + get() = this.isDisplayedActive && this.checklist?.size != this.completedChecklistCount val isGroupTask: Boolean get() = group?.approvalApproved == true @@ -140,11 +140,11 @@ open class Task : RealmObject, Parcelable { @Retention(AnnotationRetention.SOURCE) annotation class TaskTypes - fun containsAllTagIds(tagIdList: List): Boolean = tags.mapTo(ArrayList()) { it.getId() }.containsAll(tagIdList) + fun containsAllTagIds(tagIdList: List): Boolean = tags?.mapTo(ArrayList()) { it.getId() }?.containsAll(tagIdList) ?: false fun checkIfDue(): Boolean? = isDue == true - fun getNextReminderOccurence(oldTime: Date): Date? { + fun getNextReminderOccurence(oldTime: Date?): Date? { val today = Calendar.getInstance() val newTime = GregorianCalendar() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.java index ef357de27..aa9bae009 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.java @@ -564,7 +564,7 @@ public class MainActivity extends BaseActivity implements TutorialView.OnTutoria } else { try { super.onBackPressed(); - } catch (IllegalStateException ignored) {} + } catch (Exception ignored) {} if (this.activeFragment != null && activeFragment.get() != null) { this.activeFragment.get().updateUserData(user); } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java index adff765ca..0e0556b26 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java @@ -170,7 +170,7 @@ public class ChallengesListViewAdapter extends RealmRecyclerViewAdapter { if (worldBossObject == null) { return state } - state.worldBossActive = worldBossObject["active"].asBoolean - state.worldBossKey = worldBossObject["key"].asString + if (worldBossObject.has("active") && !worldBossObject["active"].isJsonNull) { + state.worldBossActive = worldBossObject["active"].asBoolean + } + if (worldBossObject.has("key") && !worldBossObject["key"].isJsonNull) { + state.worldBossKey = worldBossObject["key"].asString + } if (worldBossObject.has("progress")) { val progress = QuestProgress() val progressObj = worldBossObject.getAsJsonObject("progress") diff --git a/build.gradle b/build.gradle index d023b51f5..69ec5a081 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.2.21' + ext.kotlin_version = '1.2.30' ext.build_tools_version = '26.0.2' ext.sdk_version = 27