mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-21 05:09:00 +00:00
fixes and tweaks
This commit is contained in:
parent
b648415560
commit
da1c3a2b48
29 changed files with 114 additions and 85 deletions
|
|
@ -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"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
@ -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<HabitResponse<Member>>
|
||||
|
||||
@GET("members/{mid}/achievements")
|
||||
fun getMemberAchievements(@Path("mid") memberId: String): Flowable<HabitResponse<List<Achievement>>>
|
||||
fun getMemberAchievements(@Path("mid") memberId: String, @Query("lang") language: String?): Flowable<HabitResponse<List<Achievement>>>
|
||||
|
||||
@POST("members/send-private-message")
|
||||
fun postPrivateMessage(@Body messageDetails: Map<String, String>): Flowable<HabitResponse<PostChatMessageResult>>
|
||||
|
|
@ -332,10 +332,10 @@ interface ApiService {
|
|||
fun flagInboxMessage(@Path("mid") mid: String, @Body data: Map<String, String>): Flowable<HabitResponse<Void>>
|
||||
|
||||
@GET("shops/{identifier}")
|
||||
fun retrieveShopInventory(@Path("identifier") identifier: String): Flowable<HabitResponse<Shop>>
|
||||
fun retrieveShopInventory(@Path("identifier") identifier: String, @Query("lang") language: String?): Flowable<HabitResponse<Shop>>
|
||||
|
||||
@GET("shops/market-gear")
|
||||
fun retrieveMarketGear(): Flowable<HabitResponse<Shop>>
|
||||
fun retrieveMarketGear(@Query("lang") language: String?): Flowable<HabitResponse<Shop>>
|
||||
|
||||
// Push notifications
|
||||
@POST("user/push-devices")
|
||||
|
|
|
|||
|
|
@ -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<List<Achievement>> {
|
||||
return apiService.getMemberAchievements(memberId).compose(configureApiCallObserver())
|
||||
return apiService.getMemberAchievements(memberId, languageCode).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun findUsernames(username: String, context: String?, id: String?): Flowable<List<FindUsernameResult>> {
|
||||
|
|
@ -667,7 +667,7 @@ class ApiClientImpl(
|
|||
}
|
||||
|
||||
override fun retrieveShopIventory(identifier: String): Flowable<Shop> {
|
||||
return apiService.retrieveShopInventory(identifier).compose(configureApiCallObserver())
|
||||
return apiService.retrieveShopInventory(identifier, languageCode).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun addPushDevice(pushDeviceData: Map<String, String>): Flowable<List<Void>> {
|
||||
|
|
@ -795,7 +795,9 @@ class ApiClientImpl(
|
|||
override fun updateEmail(newEmail: String, password: String): Flowable<Void> {
|
||||
val updateObject = HashMap<String, String>()
|
||||
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<Shop> {
|
||||
return apiService.retrieveMarketGear().compose(configureApiCallObserver())
|
||||
return apiService.retrieveMarketGear(languageCode).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override val worldState: Flowable<WorldState>
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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<TextInputLayout>(R.id.input_layout)?.hint = context?.getString(R.string.email)
|
||||
val passwordEditText = view?.findViewById<ValidatingEditText>(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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
NAME=4.0
|
||||
CODE=4290
|
||||
CODE=4300
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<ErrorResponse>? = Moshi.Builder()
|
||||
.addLast(KotlinJsonAdapterFactory()).build().adapter(ErrorResponse::class.java).lenient()
|
||||
|
||||
private suspend fun <T: Any> process(call: suspend () -> Response<WearableHabitResponse<T>>): NetworkResult<T> {
|
||||
val response: Response<WearableHabitResponse<T>> = 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()
|
||||
|
|
|
|||
|
|
@ -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<List<Task>?>(null)
|
||||
)
|
||||
|
||||
private val taskCountHelperValue = MutableLiveData<Long>()
|
||||
private val taskCountHelperValue = MutableStateFlow<Long>(0)
|
||||
|
||||
fun getTasks(type: TaskType): Flow<List<Task>> {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class RYAActivity : BaseActivity<ActivityRyaBinding, RYAViewModel>() {
|
|||
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<ActivityRyaBinding, RYAViewModel>() {
|
|||
super.onDestroy()
|
||||
}
|
||||
|
||||
lateinit var startTime: Date
|
||||
private lateinit var startTime: Date
|
||||
|
||||
private fun runCron() {
|
||||
startTime = Date()
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ class TaskDetailActivity : BaseActivity<ActivityTaskDetailBinding, TaskDetailVie
|
|||
binding.taskStreakView.text = format.format(dueDate)
|
||||
binding.taskStreakView.isVisible = true
|
||||
binding.taskStreakView.setCompoundDrawables(null, null, null, null)
|
||||
} ?: run {
|
||||
binding.taskStreakView.isVisible = false
|
||||
}
|
||||
} else {
|
||||
val streakString = task?.streakString
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import com.habitrpg.wearos.habitica.ui.adapters.ToDoListAdapter
|
|||
import com.habitrpg.wearos.habitica.ui.viewmodels.TaskListViewModel
|
||||
import com.habitrpg.wearos.habitica.util.HabiticaScrollingLayoutCallback
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@AndroidEntryPoint
|
||||
|
|
@ -66,8 +67,8 @@ class TaskListActivity : BaseActivity<ActivityTasklistBinding, TaskListViewModel
|
|||
}
|
||||
}
|
||||
|
||||
viewModel.tasks.observe(this) {
|
||||
if (!it.isNullOrEmpty()) {
|
||||
lifecycleScope.launch {
|
||||
viewModel.tasks.collectLatest {
|
||||
adapter.data = it
|
||||
}
|
||||
}
|
||||
|
|
@ -80,7 +81,6 @@ class TaskListActivity : BaseActivity<ActivityTasklistBinding, TaskListViewModel
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
adapter.onTaskScore = {
|
||||
scoreTask(it)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import com.habitrpg.wearos.habitica.ui.views.TaskRewardChip
|
|||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.lang.Integer.max
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.toDuration
|
||||
|
||||
|
|
@ -128,7 +129,7 @@ class TaskResultActivity : BaseActivity<ActivityTaskResultBinding, TaskResultVie
|
|||
if (chips.size > 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
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class RYAViewModel @Inject constructor(
|
|||
) : BaseViewModel(userRepository, taskRepository, exceptionBuilder, appStateManager) {
|
||||
var hasRunCron: Boolean = false
|
||||
val tasks = MutableLiveData<List<Task>>()
|
||||
var hasTaskData = false
|
||||
|
||||
private val tasksToComplete = mutableListOf<Task>()
|
||||
|
||||
|
|
@ -35,6 +36,7 @@ class RYAViewModel @Inject constructor(
|
|||
.map { it.filter { task -> task.isDue == true && !task.completed } }
|
||||
.first()
|
||||
tasks.value = taskList
|
||||
hasTaskData = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ class TaskListViewModel @Inject constructor(
|
|||
else -> map(it)
|
||||
}
|
||||
}
|
||||
.asLiveData()
|
||||
val user = userRepository.getUser()
|
||||
.asLiveData()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_enabled="true" android:color="@color/watch_purple_100" />
|
||||
<item android:state_enabled="false" android:color="@color/gray_5" />
|
||||
<item android:state_enabled="false" android:color="@color/watch_purple_5" />
|
||||
</selector>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_enabled="true" android:color="@color/black" />
|
||||
<item android:state_enabled="false" android:color="@color/gray_200" />
|
||||
<item android:state_enabled="true" android:color="@color/watch_black" />
|
||||
<item android:state_enabled="false" android:color="@color/watch_gray_10" />
|
||||
</selector>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
||||
<size android:width="18dp" android:height="18dp" />
|
||||
<stroke android:width="2dp" android:color="@color/gray_200" />
|
||||
<stroke android:width="2dp" android:color="@color/watch_gray_10" />
|
||||
</shape>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||
<corners android:radius="40dp" />
|
||||
<stroke android:color="@color/gray_100" android:width="2dp" />
|
||||
<stroke android:color="@color/watch_gray_5" android:width="2dp" />
|
||||
</shape>
|
||||
|
|
@ -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"/>
|
||||
</LinearLayout>
|
||||
|
|
@ -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"/>
|
||||
<EditText
|
||||
|
|
@ -95,7 +95,7 @@
|
|||
android:background="@drawable/row_background_outline"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:autofillHints="password"
|
||||
android:textColorHint="@color/watch_gray_200"
|
||||
style="@style/EditText"
|
||||
android:inputType="textPassword|text"
|
||||
android:textSize="14sp"
|
||||
android:imeOptions="actionDone"
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/checklist_disclaimer"
|
||||
android:textColor="@color/gray_400"
|
||||
android:textColor="@color/watch_gray_200"
|
||||
android:gravity="center"
|
||||
style="@style/Text.Body1"
|
||||
android:layout_marginTop="@dimen/spacing_medium" />
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"/>
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/confirmation_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Text.Body1"
|
||||
android:textSize="14sp"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/watch_white"
|
||||
/>
|
||||
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
<com.habitrpg.wearos.habitica.ui.views.HabiticaScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:background="@color/watch_black">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="HabiticaAppTheme" parent="@android:style/Theme.DeviceDefault">
|
||||
<style name="HabiticaAppTheme" parent="Theme.AppCompat">
|
||||
<item name="android:windowBackground">@color/watch_black</item>
|
||||
<item name="fontFamily">sans-serif</item>
|
||||
</style>
|
||||
|
|
@ -99,4 +99,10 @@
|
|||
<item name="android:textSize">16sp</item>
|
||||
</style>
|
||||
|
||||
<style name="EditText">
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
<item name="android:textColor">@color/watch_gray_200</item>
|
||||
<item name="android:textColorHint">@color/watch_gray_200</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
Loading…
Reference in a new issue