fixes and tweaks

This commit is contained in:
Phillip Thelen 2022-08-02 17:02:07 +02:00
parent b648415560
commit da1c3a2b48
29 changed files with 114 additions and 85 deletions

View file

@ -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>

View file

@ -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")

View file

@ -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>

View file

@ -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)))
}
}

View file

@ -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(

View file

@ -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()

View file

@ -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)

View file

@ -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

View file

@ -1,2 +1,2 @@
NAME=4.0
CODE=4290
CODE=4300

View file

@ -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)

View file

@ -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()

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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)
}

View file

@ -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

View file

@ -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
}
}

View file

@ -53,7 +53,6 @@ class TaskListViewModel @Inject constructor(
else -> map(it)
}
}
.asLiveData()
val user = userRepository.getUser()
.asLiveData()

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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"

View file

@ -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"

View file

@ -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"/>

View file

@ -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"

View file

@ -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"

View file

@ -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>