From da1c3a2b4873eaa6984bcd3265584280ac708598 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Tue, 2 Aug 2022 17:02:07 +0200 Subject: [PATCH] fixes and tweaks --- Habitica/res/layout/achievement_list_item.xml | 2 +- .../android/habitica/api/ApiService.kt | 22 +++++----- .../data/implementation/ApiClientImpl.kt | 40 ++++++++++--------- .../ui/activities/FullProfileActivity.kt | 8 ++-- .../habitica/ui/activities/LoginActivity.kt | 5 +-- .../ui/activities/TaskFormActivity.kt | 17 ++++---- .../preferences/AccountPreferenceFragment.kt | 12 ++++-- .../views/tasks/form/ReminderItemFormView.kt | 2 +- version.properties | 2 +- .../wearos/habitica/MainApplication.kt | 3 +- .../wearos/habitica/data/ApiClient.kt | 17 +++++++- .../data/repositories/TaskLocalRepository.kt | 12 +++--- .../habitica/ui/activities/RYAActivity.kt | 3 +- .../ui/activities/TaskDetailActivity.kt | 2 + .../ui/activities/TaskListActivity.kt | 6 +-- .../ui/activities/TaskResultActivity.kt | 3 +- .../habitica/ui/viewmodels/RYAViewModel.kt | 2 + .../ui/viewmodels/TaskListViewModel.kt | 1 - .../main/res/drawable/button_state_color.xml | 2 +- .../res/drawable/button_text_state_color.xml | 4 +- .../src/main/res/drawable/radio_unchecked.xml | 2 +- .../res/drawable/row_background_outline.xml | 2 +- .../main/res/layout/activity_confirmation.xml | 4 +- wearos/src/main/res/layout/activity_login.xml | 4 +- wearos/src/main/res/layout/activity_rya.xml | 4 +- .../main/res/layout/activity_task_detail.xml | 2 +- .../main/res/layout/activity_task_form.xml | 5 ++- wearos/src/main/res/layout/logout_layout.xml | 3 +- wearos/src/main/res/values/styles.xml | 8 +++- 29 files changed, 114 insertions(+), 85 deletions(-) diff --git a/Habitica/res/layout/achievement_list_item.xml b/Habitica/res/layout/achievement_list_item.xml index 9197112d7..abf298dbf 100644 --- a/Habitica/res/layout/achievement_list_item.xml +++ b/Habitica/res/layout/achievement_list_item.xml @@ -41,7 +41,7 @@ android:id="@+id/achievement_description" android:layout_width="match_parent" android:layout_height="wrap_content" - style="@style/Caption3" + style="@style/Caption4" android:textColor="@color/text_secondary"/> \ No newline at end of file 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 05a4c32f8..c22918296 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 @@ -3,25 +3,17 @@ package com.habitrpg.android.habitica.api import com.habitrpg.android.habitica.models.Achievement import com.habitrpg.android.habitica.models.ContentResult import com.habitrpg.android.habitica.models.LeaveChallengeBody -import com.habitrpg.common.habitica.models.PurchaseValidationRequest -import com.habitrpg.common.habitica.models.PurchaseValidationResult import com.habitrpg.android.habitica.models.Tag import com.habitrpg.android.habitica.models.TeamPlan import com.habitrpg.android.habitica.models.WorldState -import com.habitrpg.common.habitica.models.auth.UserAuth -import com.habitrpg.common.habitica.models.auth.UserAuthResponse -import com.habitrpg.common.habitica.models.auth.UserAuthSocial import com.habitrpg.android.habitica.models.inventory.Equipment import com.habitrpg.android.habitica.models.inventory.Quest import com.habitrpg.android.habitica.models.members.Member import com.habitrpg.android.habitica.models.responses.BulkTaskScoringData import com.habitrpg.android.habitica.models.responses.BuyResponse -import com.habitrpg.common.habitica.models.responses.FeedResponse import com.habitrpg.android.habitica.models.responses.PostChatMessageResult import com.habitrpg.android.habitica.models.responses.SkillResponse -import com.habitrpg.common.habitica.models.responses.Status import com.habitrpg.android.habitica.models.responses.UnlockResponse -import com.habitrpg.common.habitica.models.responses.VerifyUsernameResponse import com.habitrpg.android.habitica.models.shops.Shop import com.habitrpg.android.habitica.models.shops.ShopItem import com.habitrpg.android.habitica.models.social.Challenge @@ -34,8 +26,16 @@ import com.habitrpg.android.habitica.models.tasks.TaskList import com.habitrpg.android.habitica.models.user.Items import com.habitrpg.android.habitica.models.user.Stats import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.common.habitica.models.PurchaseValidationRequest +import com.habitrpg.common.habitica.models.PurchaseValidationResult +import com.habitrpg.common.habitica.models.auth.UserAuth +import com.habitrpg.common.habitica.models.auth.UserAuthResponse +import com.habitrpg.common.habitica.models.auth.UserAuthSocial +import com.habitrpg.common.habitica.models.responses.FeedResponse import com.habitrpg.common.habitica.models.responses.HabitResponse +import com.habitrpg.common.habitica.models.responses.Status import com.habitrpg.common.habitica.models.responses.TaskDirectionData +import com.habitrpg.common.habitica.models.responses.VerifyUsernameResponse import io.reactivex.rxjava3.core.Flowable import retrofit2.http.Body import retrofit2.http.DELETE @@ -316,7 +316,7 @@ interface ApiService { fun getMemberWithUsername(@Path("username") username: String): Flowable> @GET("members/{mid}/achievements") - fun getMemberAchievements(@Path("mid") memberId: String): Flowable>> + fun getMemberAchievements(@Path("mid") memberId: String, @Query("lang") language: String?): Flowable>> @POST("members/send-private-message") fun postPrivateMessage(@Body messageDetails: Map): Flowable> @@ -332,10 +332,10 @@ interface ApiService { fun flagInboxMessage(@Path("mid") mid: String, @Body data: Map): Flowable> @GET("shops/{identifier}") - fun retrieveShopInventory(@Path("identifier") identifier: String): Flowable> + fun retrieveShopInventory(@Path("identifier") identifier: String, @Query("lang") language: String?): Flowable> @GET("shops/market-gear") - fun retrieveMarketGear(): Flowable> + fun retrieveMarketGear(@Query("lang") language: String?): Flowable> // Push notifications @POST("user/push-devices") 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 a99038881..a827dddf6 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 @@ -8,37 +8,23 @@ import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.api.ApiService import com.habitrpg.android.habitica.api.GSonFactoryCreator -import com.habitrpg.common.habitica.api.HostConfig -import com.habitrpg.common.habitica.api.Server import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.extensions.filterMap import com.habitrpg.android.habitica.helpers.NotificationsManager import com.habitrpg.android.habitica.models.Achievement import com.habitrpg.android.habitica.models.ContentResult import com.habitrpg.android.habitica.models.LeaveChallengeBody -import com.habitrpg.common.habitica.models.PurchaseValidationRequest -import com.habitrpg.common.habitica.models.PurchaseValidationResult import com.habitrpg.android.habitica.models.Tag import com.habitrpg.android.habitica.models.TeamPlan import com.habitrpg.android.habitica.models.WorldState -import com.habitrpg.common.habitica.models.auth.UserAuth -import com.habitrpg.common.habitica.models.auth.UserAuthResponse -import com.habitrpg.common.habitica.models.auth.UserAuthSocial -import com.habitrpg.common.habitica.models.auth.UserAuthSocialTokens import com.habitrpg.android.habitica.models.inventory.Equipment import com.habitrpg.android.habitica.models.inventory.Quest import com.habitrpg.android.habitica.models.members.Member import com.habitrpg.android.habitica.models.responses.BulkTaskScoringData import com.habitrpg.android.habitica.models.responses.BuyResponse -import com.habitrpg.common.habitica.models.responses.ErrorResponse -import com.habitrpg.common.habitica.models.responses.FeedResponse -import com.habitrpg.common.habitica.models.responses.HabitResponse import com.habitrpg.android.habitica.models.responses.PostChatMessageResult import com.habitrpg.android.habitica.models.responses.SkillResponse -import com.habitrpg.common.habitica.models.responses.Status -import com.habitrpg.common.habitica.models.responses.TaskDirectionData import com.habitrpg.android.habitica.models.responses.UnlockResponse -import com.habitrpg.common.habitica.models.responses.VerifyUsernameResponse import com.habitrpg.android.habitica.models.shops.Shop import com.habitrpg.android.habitica.models.shops.ShopItem import com.habitrpg.android.habitica.models.social.Challenge @@ -52,6 +38,20 @@ import com.habitrpg.android.habitica.models.user.Items import com.habitrpg.android.habitica.models.user.Stats import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.proxy.AnalyticsManager +import com.habitrpg.common.habitica.api.HostConfig +import com.habitrpg.common.habitica.api.Server +import com.habitrpg.common.habitica.models.PurchaseValidationRequest +import com.habitrpg.common.habitica.models.PurchaseValidationResult +import com.habitrpg.common.habitica.models.auth.UserAuth +import com.habitrpg.common.habitica.models.auth.UserAuthResponse +import com.habitrpg.common.habitica.models.auth.UserAuthSocial +import com.habitrpg.common.habitica.models.auth.UserAuthSocialTokens +import com.habitrpg.common.habitica.models.responses.ErrorResponse +import com.habitrpg.common.habitica.models.responses.FeedResponse +import com.habitrpg.common.habitica.models.responses.HabitResponse +import com.habitrpg.common.habitica.models.responses.Status +import com.habitrpg.common.habitica.models.responses.TaskDirectionData +import com.habitrpg.common.habitica.models.responses.VerifyUsernameResponse import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.FlowableTransformer @@ -131,7 +131,6 @@ class ApiClientImpl( val client = OkHttpClient.Builder() .cache(cache) - .addInterceptor(logging) .addNetworkInterceptor { chain -> val original = chain.request() var builder: Request.Builder = original.newBuilder() @@ -153,6 +152,7 @@ class ApiClientImpl( lastAPICallURL = original.url.toString() chain.proceed(request) } + .addInterceptor(logging) .readTimeout(2400, TimeUnit.SECONDS) .build() @@ -655,7 +655,7 @@ class ApiClientImpl( } override fun getMemberAchievements(memberId: String): Flowable> { - return apiService.getMemberAchievements(memberId).compose(configureApiCallObserver()) + return apiService.getMemberAchievements(memberId, languageCode).compose(configureApiCallObserver()) } override fun findUsernames(username: String, context: String?, id: String?): Flowable> { @@ -667,7 +667,7 @@ class ApiClientImpl( } override fun retrieveShopIventory(identifier: String): Flowable { - return apiService.retrieveShopInventory(identifier).compose(configureApiCallObserver()) + return apiService.retrieveShopInventory(identifier, languageCode).compose(configureApiCallObserver()) } override fun addPushDevice(pushDeviceData: Map): Flowable> { @@ -795,7 +795,9 @@ class ApiClientImpl( override fun updateEmail(newEmail: String, password: String): Flowable { val updateObject = HashMap() updateObject["newEmail"] = newEmail - updateObject["password"] = password + if (password.isNotBlank()) { + updateObject["password"] = password + } return apiService.updateEmail(updateObject).compose(configureApiCallObserver()) } @@ -844,7 +846,7 @@ class ApiClientImpl( } override fun retrieveMarketGear(): Flowable { - return apiService.retrieveMarketGear().compose(configureApiCallObserver()) + return apiService.retrieveMarketGear(languageCode).compose(configureApiCallObserver()) } override val worldState: Flowable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt index a715cabf1..819cc3a55 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt @@ -13,7 +13,6 @@ import android.widget.TableRow import android.widget.TextView import androidx.core.content.ContextCompat import androidx.core.os.bundleOf -import androidx.lifecycle.lifecycleScope import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.ApiClient @@ -31,16 +30,17 @@ import com.habitrpg.android.habitica.models.user.Outfit import com.habitrpg.android.habitica.models.user.Stats import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel import com.habitrpg.android.habitica.ui.adapter.social.AchievementProfileAdapter -import com.habitrpg.common.habitica.helpers.RecyclerViewState import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.SnackbarDisplayType import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import com.habitrpg.common.habitica.extensions.getThemeColor import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.helpers.RecyclerViewState import com.habitrpg.common.habitica.helpers.setMarkdown import com.habitrpg.common.habitica.views.PixelArtView import io.reactivex.rxjava3.core.Flowable import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.text.SimpleDateFormat @@ -192,8 +192,8 @@ class FullProfileActivity : BaseActivity() { private fun showSendMessageToUserDialog() { finish() - lifecycleScope.launch(context = Dispatchers.Main) { - delay(1000L) + MainScope().launch(context = Dispatchers.Main) { + delay(500L) MainNavigationController.navigate(R.id.inboxMessageListFragment, bundleOf(Pair("username", username), Pair("userID", userID))) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt index e1c04853d..97103dbea 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt @@ -57,9 +57,6 @@ class LoginActivity : BaseActivity() { private lateinit var viewModel: AuthenticationViewModel private lateinit var binding: ActivityLoginBinding - val messageClient: MessageClient by lazy { Wearable.getMessageClient(this) } - private val capabilityClient: CapabilityClient by lazy { Wearable.getCapabilityClient(this) } - @Inject lateinit var apiClient: ApiClient @Inject @@ -239,6 +236,8 @@ class LoginActivity : BaseActivity() { private fun handleAuthResponse(response: UserAuthResponse) { viewModel.handleAuthResponse(response) try { + val messageClient: MessageClient = Wearable.getMessageClient(this) + val capabilityClient: CapabilityClient = Wearable.getCapabilityClient(this) lifecycleScope.launch(Dispatchers.IO) { val info = Tasks.await( capabilityClient.getCapability( 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 89469aa1e..ab4ef842f 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 @@ -1,7 +1,6 @@ package com.habitrpg.android.habitica.ui.activities import android.app.Activity -import android.content.DialogInterface import android.content.Intent import android.content.SharedPreferences import android.content.res.ColorStateList @@ -31,20 +30,20 @@ import com.habitrpg.android.habitica.data.TaskRepository import com.habitrpg.android.habitica.databinding.ActivityTaskFormBinding import com.habitrpg.android.habitica.extensions.OnChangeTextWatcher import com.habitrpg.android.habitica.extensions.addCancelButton -import com.habitrpg.common.habitica.extensions.dpToPx -import com.habitrpg.common.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.common.habitica.models.tasks.Attribute -import com.habitrpg.common.habitica.models.tasks.Frequency -import com.habitrpg.common.habitica.models.tasks.HabitResetOption import com.habitrpg.android.habitica.models.tasks.Task -import com.habitrpg.common.habitica.models.tasks.TaskType import com.habitrpg.android.habitica.ui.helpers.dismissKeyboard import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog +import com.habitrpg.common.habitica.extensions.dpToPx +import com.habitrpg.common.habitica.extensions.getThemeColor +import com.habitrpg.common.habitica.models.tasks.Attribute +import com.habitrpg.common.habitica.models.tasks.Frequency +import com.habitrpg.common.habitica.models.tasks.HabitResetOption +import com.habitrpg.common.habitica.models.tasks.TaskType import io.realm.RealmList import java.util.Date import javax.inject.Inject @@ -276,11 +275,9 @@ class TaskFormActivity : BaseActivity() { isDiscardCancelled = true alert.dismiss() } - alert.setOnDismissListener( - DialogInterface.OnDismissListener { + alert.setOnDismissListener { isDiscardCancelled = true } - ) alert.show() } else { super.onBackPressed() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt index 012eff4f3..481f78b56 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt @@ -13,6 +13,7 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat.getSystemService import androidx.core.util.PatternsCompat +import androidx.core.view.isVisible import androidx.preference.EditTextPreference import androidx.preference.Preference import com.google.android.material.textfield.TextInputLayout @@ -139,17 +140,17 @@ class AccountPreferenceFragment : "username" -> showLoginNameDialog() "confirm_username" -> showConfirmUsernameDialog() "email" -> { - if (user?.authentication?.hasPassword == true) { - showEmailDialog() - } else { + if (user?.authentication?.hasPassword != true && user?.authentication?.localAuthentication?.email?.isNotBlank() == true) { showAddPasswordDialog(true) + } else { + showEmailDialog() } } "password" -> { if (user?.authentication?.hasPassword == true) { showChangePasswordDialog() } else { - showAddPasswordDialog(true) + showAddPasswordDialog(user?.authentication?.localAuthentication?.email?.isNotBlank() != true) } } "UserID" -> { @@ -354,6 +355,9 @@ class AccountPreferenceFragment : emailEditText?.errorText = getString(R.string.email_invalid) view?.findViewById(R.id.input_layout)?.hint = context?.getString(R.string.email) val passwordEditText = view?.findViewById(R.id.password_edit_text) + if (user?.authentication?.hasPassword != true) { + passwordEditText?.isVisible = false + } context?.let { context -> val dialog = HabiticaAlertDialog(context) dialog.setTitle(R.string.change_email) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/ReminderItemFormView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/ReminderItemFormView.kt index b6a40935a..600d290b0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/ReminderItemFormView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/ReminderItemFormView.kt @@ -144,7 +144,7 @@ class ReminderItemFormView @JvmOverloads constructor( valueChangedListener?.let { val zonedDateTime = ZonedDateTime.now() .withYear(year) - .withMonth(month) + .withMonth(month + 1) .withDayOfMonth(dayOfMonth) item.time = zonedDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) binding.textView.text = formattedTime diff --git a/version.properties b/version.properties index db52238f6..fc7e4798e 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ NAME=4.0 -CODE=4290 \ No newline at end of file +CODE=4300 \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/MainApplication.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/MainApplication.kt index d40424e3f..533c7d002 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/MainApplication.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/MainApplication.kt @@ -12,6 +12,7 @@ import com.habitrpg.wearos.habitica.data.repositories.TaskRepository import com.habitrpg.wearos.habitica.data.repositories.UserRepository import com.habitrpg.wearos.habitica.ui.activities.BaseActivity import com.habitrpg.wearos.habitica.ui.activities.FaintActivity +import com.habitrpg.wearos.habitica.ui.activities.LoginActivity import com.habitrpg.wearos.habitica.ui.activities.MainActivity import com.habitrpg.wearos.habitica.ui.activities.RYAActivity import dagger.hilt.android.HiltAndroidApp @@ -43,7 +44,7 @@ class MainApplication : Application() { val intent = Intent(this@MainApplication, FaintActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(intent) - } else if (it.needsCron && BaseActivity.currentActivityClassName != RYAActivity::class.java.name) { + } else if (it.needsCron && BaseActivity.currentActivityClassName != RYAActivity::class.java.name && BaseActivity.currentActivityClassName != LoginActivity::class.java.name) { val intent = Intent(this@MainApplication, RYAActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(intent) diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/data/ApiClient.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/data/ApiClient.kt index 42867493d..ba9d8c643 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/data/ApiClient.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/data/ApiClient.kt @@ -8,10 +8,14 @@ import com.habitrpg.common.habitica.api.HostConfig import com.habitrpg.common.habitica.api.Server import com.habitrpg.common.habitica.models.auth.UserAuth import com.habitrpg.common.habitica.models.auth.UserAuthSocial +import com.habitrpg.common.habitica.models.responses.ErrorResponse import com.habitrpg.wearos.habitica.managers.AppStateManager import com.habitrpg.wearos.habitica.models.NetworkResult import com.habitrpg.wearos.habitica.models.WearableHabitResponse import com.habitrpg.wearos.habitica.models.tasks.Task +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.Moshi +import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import okhttp3.Cache import okhttp3.CacheControl import okhttp3.OkHttpClient @@ -88,7 +92,7 @@ class ApiClient @Inject constructor( var cacheControl = CacheControl.Builder() cacheControl = if (request.method == "GET") { if (hasNetwork(context)) { - cacheControl.maxAge(5, TimeUnit.MINUTES) + cacheControl.maxAge(1, TimeUnit.MINUTES) } else { appStateManager.isAppConnected.value = false cacheControl.maxAge(1, TimeUnit.DAYS) @@ -107,7 +111,8 @@ class ApiClient @Inject constructor( val responseBuilder = response.newBuilder() responseBuilder.header("was-cached", (response.networkResponse == null).toString()) if (request.method == "GET") { - if (response.code == 504 || response.request.header("x-api-user") != hostConfig.userID) { + val userID = response.request.header("x-api-user") ?: request.header("x-api-user") + if (response.code == 504 || (userID != null && userID != hostConfig.userID)) { // Cache miss. Network might be down, but retry call without cache to be sure. response.close() chain.proceed(request.newBuilder() @@ -162,6 +167,9 @@ class ApiClient @Inject constructor( this.hostConfig.apiKey = apiToken ?: "" } + private val adapter: JsonAdapter? = Moshi.Builder() + .addLast(KotlinJsonAdapterFactory()).build().adapter(ErrorResponse::class.java).lenient() + private suspend fun process(call: suspend () -> Response>): NetworkResult { val response: Response> = call.invoke() @@ -172,7 +180,12 @@ class ApiClient @Inject constructor( if (response.code() == 504) { NetworkResult.Error(Exception(), !wasCached) } else { + response.errorBody()?.string()?.let { + val errorResponse = adapter?.fromJson(it) + throw(java.lang.Exception(errorResponse?.message)) + } throw(java.lang.Exception(response.message())) + } } else { val body = response.body() diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskLocalRepository.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskLocalRepository.kt index 7c4a20ede..459735370 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskLocalRepository.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskLocalRepository.kt @@ -1,7 +1,5 @@ package com.habitrpg.wearos.habitica.data.repositories -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.asFlow import com.habitrpg.common.habitica.models.tasks.TaskType import com.habitrpg.common.habitica.models.tasks.TasksOrder import com.habitrpg.wearos.habitica.models.tasks.Task @@ -25,20 +23,21 @@ class TaskLocalRepository @Inject constructor() { TaskType.REWARD to MutableStateFlow?>(null) ) - private val taskCountHelperValue = MutableLiveData() + private val taskCountHelperValue = MutableStateFlow(0) fun getTasks(type: TaskType): Flow> { return tasks[type]!!.filterNotNull() } fun saveTasks(tasks: TaskList, order: TasksOrder?) { - val taskMap = mutableMapOf( + val taskMap = mapOf( TaskType.HABIT to sortTasks(tasks.tasks, order?.habits ?: emptyList(), TaskType.HABIT), TaskType.DAILY to sortTasks(tasks.tasks, order?.dailys ?: emptyList(), TaskType.DAILY), TaskType.TODO to sortTasks(tasks.tasks, order?.todos ?: emptyList(), TaskType.TODO), TaskType.REWARD to sortTasks(tasks.tasks, order?.rewards ?: emptyList(), TaskType.REWARD) ) for (type in taskMap) { + this.tasks[type.key]?.value = null this.tasks[type.key]?.value = type.value } taskCountHelperValue.value = Date().time @@ -74,6 +73,7 @@ class TaskLocalRepository @Inject constructor() { oldList?.add(0, task) } oldList?.let { + tasks[task.type]?.value = null tasks[task.type]?.value = it } taskCountHelperValue.value = Date().time @@ -89,7 +89,7 @@ class TaskLocalRepository @Inject constructor() { return emptyFlow() } - fun getTaskCounts() = taskCountHelperValue.asFlow().map { + fun getTaskCounts() = taskCountHelperValue.map { mapOf( TaskType.HABIT.value to (tasks[TaskType.HABIT]?.value?.size ?: 0), TaskType.DAILY.value to (tasks[TaskType.DAILY]?.value?.size ?: 0), @@ -98,7 +98,7 @@ class TaskLocalRepository @Inject constructor() { ) } - fun getActiveTaskCounts() = taskCountHelperValue.asFlow().map { + fun getActiveTaskCounts() = taskCountHelperValue.map { mapOf( TaskType.HABIT.value to (tasks[TaskType.HABIT]?.value?.size ?: 0), TaskType.DAILY.value to (tasks[TaskType.DAILY]?.value?.filter { it.isDue == true && !it.completed }?.size diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/RYAActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/RYAActivity.kt index 7b0585326..6cef6d48a 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/RYAActivity.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/RYAActivity.kt @@ -27,6 +27,7 @@ class RYAActivity : BaseActivity() { super.onCreate(savedInstanceState) viewModel.tasks.observe(this) { + if (!viewModel.hasTaskData) return@observe if (it.isEmpty()) { runCron() return@observe @@ -64,7 +65,7 @@ class RYAActivity : BaseActivity() { super.onDestroy() } - lateinit var startTime: Date + private lateinit var startTime: Date private fun runCron() { startTime = Date() diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskDetailActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskDetailActivity.kt index 2edffc240..9146366f0 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskDetailActivity.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskDetailActivity.kt @@ -63,6 +63,8 @@ class TaskDetailActivity : BaseActivity 4 && hasDrop || (chips.size > 5 && !hasDrop)) { chips = chips.subList(0, if (hasDrop) 4 else 5) } - secondsToShow = chips.size + secondsToShow = max(chips.size, 2) chips.forEach { binding.gridLayout.addView(it) it.size = chipSize diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/RYAViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/RYAViewModel.kt index 9ca8ba36f..c59aa5ac1 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/RYAViewModel.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/RYAViewModel.kt @@ -26,6 +26,7 @@ class RYAViewModel @Inject constructor( ) : BaseViewModel(userRepository, taskRepository, exceptionBuilder, appStateManager) { var hasRunCron: Boolean = false val tasks = MutableLiveData>() + var hasTaskData = false private val tasksToComplete = mutableListOf() @@ -35,6 +36,7 @@ class RYAViewModel @Inject constructor( .map { it.filter { task -> task.isDue == true && !task.completed } } .first() tasks.value = taskList + hasTaskData = true } } diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt index 4fc09fc5d..e89d6e79e 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt @@ -53,7 +53,6 @@ class TaskListViewModel @Inject constructor( else -> map(it) } } - .asLiveData() val user = userRepository.getUser() .asLiveData() diff --git a/wearos/src/main/res/drawable/button_state_color.xml b/wearos/src/main/res/drawable/button_state_color.xml index 4c8bf51e4..c0b709aa4 100644 --- a/wearos/src/main/res/drawable/button_state_color.xml +++ b/wearos/src/main/res/drawable/button_state_color.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/wearos/src/main/res/drawable/button_text_state_color.xml b/wearos/src/main/res/drawable/button_text_state_color.xml index e9eb6c913..8bade828b 100644 --- a/wearos/src/main/res/drawable/button_text_state_color.xml +++ b/wearos/src/main/res/drawable/button_text_state_color.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/wearos/src/main/res/drawable/radio_unchecked.xml b/wearos/src/main/res/drawable/radio_unchecked.xml index b2a039403..a2d83871b 100644 --- a/wearos/src/main/res/drawable/radio_unchecked.xml +++ b/wearos/src/main/res/drawable/radio_unchecked.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/wearos/src/main/res/drawable/row_background_outline.xml b/wearos/src/main/res/drawable/row_background_outline.xml index 508cf22a3..83b3cc2cf 100644 --- a/wearos/src/main/res/drawable/row_background_outline.xml +++ b/wearos/src/main/res/drawable/row_background_outline.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/wearos/src/main/res/layout/activity_confirmation.xml b/wearos/src/main/res/layout/activity_confirmation.xml index 5b4c7543a..4892cc4f2 100644 --- a/wearos/src/main/res/layout/activity_confirmation.xml +++ b/wearos/src/main/res/layout/activity_confirmation.xml @@ -9,10 +9,10 @@ android:id="@+id/text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_margin="@dimen/spacing_xlarge" + android:layout_margin="@dimen/spacing_large" tools:visibility="visible" style="@style/Text.Body1" - android:textColor="@color/gray_200" + android:textColor="@color/watch_gray_10" android:drawablePadding="@dimen/spacing_medium" android:gravity="center"/> \ No newline at end of file diff --git a/wearos/src/main/res/layout/activity_login.xml b/wearos/src/main/res/layout/activity_login.xml index f2037ab3c..d262a6074 100644 --- a/wearos/src/main/res/layout/activity_login.xml +++ b/wearos/src/main/res/layout/activity_login.xml @@ -84,7 +84,7 @@ android:paddingHorizontal="16dp" android:background="@drawable/row_background_outline" android:autofillHints="username" - android:textColorHint="@color/watch_gray_200" + style="@style/EditText" android:textSize="14sp" android:layout_marginBottom="@dimen/spacing_small"/> @@ -78,7 +78,7 @@ android:layout_height="wrap_content" android:text="@string/starting_your_day" style="@style/Text.SubHeader1" - android:textColor="@color/gray_500" + android:textColor="@color/watch_gray_500" android:gravity="center" android:layout_gravity="center" android:layout_margin="@dimen/spacing_xlarge" diff --git a/wearos/src/main/res/layout/activity_task_detail.xml b/wearos/src/main/res/layout/activity_task_detail.xml index 6c51c28bb..df42ef61b 100644 --- a/wearos/src/main/res/layout/activity_task_detail.xml +++ b/wearos/src/main/res/layout/activity_task_detail.xml @@ -26,7 +26,7 @@ android:id="@+id/task_notes_view" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/gray_400" + android:textColor="@color/watch_gray_200" android:gravity="center" style="@style/Text.Body1"/> diff --git a/wearos/src/main/res/layout/activity_task_form.xml b/wearos/src/main/res/layout/activity_task_form.xml index 54430454c..8642f6628 100644 --- a/wearos/src/main/res/layout/activity_task_form.xml +++ b/wearos/src/main/res/layout/activity_task_form.xml @@ -21,14 +21,14 @@ android:layout_height="wrap_content" style="@style/Text.SubHeader1" android:textSize="14sp" - android:textColor="@color/gray_200" + android:textColor="@color/watch_gray_200" /> @@ -64,6 +64,7 @@ android:importantForAutofill="no" android:minHeight="52dp" android:paddingHorizontal="18dp" + style="@style/EditText" android:hint="@string/task_title_hint" android:background="@drawable/row_background_outline" android:focusable="false" diff --git a/wearos/src/main/res/layout/logout_layout.xml b/wearos/src/main/res/layout/logout_layout.xml index 9502771e4..38bc33dac 100644 --- a/wearos/src/main/res/layout/logout_layout.xml +++ b/wearos/src/main/res/layout/logout_layout.xml @@ -2,7 +2,8 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + android:background="@color/watch_black"> - @@ -99,4 +99,10 @@ 16sp + + \ No newline at end of file