mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-17 11:19:01 +00:00
UI fixes
This commit is contained in:
parent
0d0c4e4038
commit
6791b1e065
13 changed files with 104 additions and 31 deletions
|
|
@ -55,6 +55,8 @@
|
|||
<string name="create_task_title">Create a Task</string>
|
||||
<string name="complete_task_title">Complete a Task</string>
|
||||
<string name="create_task">Create %s</string>
|
||||
<string name="new_task_x">New %s</string>
|
||||
<string name="save_task_x">Save %s</string>
|
||||
|
||||
<string name="are_you_sure">Are you sure?</string>
|
||||
<string name="task">Task</string>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.habitrpg.android.habitica">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<uses-feature android:name="android.hardware.type.watch" />
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import android.content.Intent
|
|||
import com.habitrpg.common.habitica.extensions.setupCoil
|
||||
import com.habitrpg.common.habitica.helpers.MarkdownParser
|
||||
import com.habitrpg.common.habitica.views.HabiticaIconsHelper
|
||||
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
|
||||
|
|
@ -20,6 +21,7 @@ import javax.inject.Inject
|
|||
class MainApplication : Application() {
|
||||
|
||||
@Inject lateinit var userRepository: UserRepository
|
||||
@Inject lateinit var taskRepository: TaskRepository
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
|
@ -40,5 +42,9 @@ class MainApplication : Application() {
|
|||
}
|
||||
}.collect()
|
||||
}
|
||||
MainScope().launch {
|
||||
userRepository.retrieveUser()
|
||||
taskRepository.retrieveTasks()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package com.habitrpg.wearos.habitica.data
|
||||
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
import com.amplitude.api.Amplitude
|
||||
import com.habitrpg.common.habitica.BuildConfig
|
||||
import com.habitrpg.common.habitica.api.HostConfig
|
||||
|
|
@ -10,6 +12,7 @@ import com.habitrpg.common.habitica.models.auth.UserAuthSocial
|
|||
import com.habitrpg.wearos.habitica.models.WearableHabitResponse
|
||||
import com.habitrpg.wearos.habitica.models.tasks.Task
|
||||
import okhttp3.Cache
|
||||
import okhttp3.CacheControl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
|
|
@ -34,7 +37,21 @@ class ApiClient @Inject constructor(
|
|||
buildRetrofit()
|
||||
}
|
||||
|
||||
fun buildRetrofit() {
|
||||
private fun hasNetwork(context: Context): Boolean {
|
||||
val connectivityManager =
|
||||
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
val networkCapabilities = connectivityManager.activeNetwork ?: return false
|
||||
val actNw =
|
||||
connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
|
||||
return when {
|
||||
actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
|
||||
actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
|
||||
actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildRetrofit() {
|
||||
val logging = HttpLoggingInterceptor()
|
||||
if (BuildConfig.DEBUG) {
|
||||
logging.level = HttpLoggingInterceptor.Level.BODY
|
||||
|
|
@ -44,15 +61,36 @@ class ApiClient @Inject constructor(
|
|||
|
||||
val calendar = GregorianCalendar()
|
||||
val timeZone = calendar.timeZone
|
||||
val timezoneOffset = -TimeUnit.MINUTES.convert(timeZone.getOffset(calendar.timeInMillis).toLong(), TimeUnit.MILLISECONDS)
|
||||
|
||||
val cacheSize: Long = 10 * 1024 * 1024 // 10 MB
|
||||
val timezoneOffset = -TimeUnit.MINUTES.convert(
|
||||
timeZone.getOffset(calendar.timeInMillis).toLong(),
|
||||
TimeUnit.MILLISECONDS
|
||||
)
|
||||
|
||||
val cacheSize = (5 * 1024 * 1024).toLong()
|
||||
val cache = Cache(File(context.cacheDir, "http_cache"), cacheSize)
|
||||
|
||||
val client = OkHttpClient.Builder()
|
||||
.cache(cache)
|
||||
.addInterceptor(logging)
|
||||
.addInterceptor { chain ->
|
||||
val request = chain.request()
|
||||
var cacheContol = CacheControl.Builder()
|
||||
cacheContol = if (request.method == "GET") {
|
||||
if (hasNetwork(context)) {
|
||||
cacheContol.maxAge(5, TimeUnit.MINUTES)
|
||||
} else {
|
||||
cacheContol.maxAge(1, TimeUnit.DAYS)
|
||||
.onlyIfCached()
|
||||
}
|
||||
} else {
|
||||
cacheContol.noCache()
|
||||
.noStore()
|
||||
}
|
||||
chain.proceed(request.newBuilder().header(
|
||||
"Cache-Control",
|
||||
cacheContol.build().toString()
|
||||
).build())
|
||||
}
|
||||
.addNetworkInterceptor { chain ->
|
||||
val original = chain.request()
|
||||
var builder: Request.Builder = original.newBuilder()
|
||||
|
|
@ -70,8 +108,16 @@ class ApiClient @Inject constructor(
|
|||
builder = builder.header("Authorization", "Basic " + BuildConfig.STAGING_KEY)
|
||||
}
|
||||
val request = builder.method(original.method, original.body)
|
||||
.removeHeader("Pragma")
|
||||
.build()
|
||||
chain.proceed(request)
|
||||
val response = chain.proceed(request)
|
||||
if (request.method == "GET") {
|
||||
response.newBuilder()
|
||||
.header("Cache-Control", request.header("Cache-Control") ?: "")
|
||||
.build()
|
||||
} else {
|
||||
response
|
||||
}
|
||||
}
|
||||
.readTimeout(2400, TimeUnit.SECONDS)
|
||||
.build()
|
||||
|
|
@ -111,6 +157,8 @@ class ApiClient @Inject constructor(
|
|||
suspend fun runCron() = process(apiService.runCron())
|
||||
|
||||
suspend fun getTasks() = process(apiService.getTasks())
|
||||
suspend fun scoreTask(id: String, direction: String) = process(apiService.scoreTask(id, direction))
|
||||
suspend fun scoreTask(id: String, direction: String) =
|
||||
process(apiService.scoreTask(id, direction))
|
||||
|
||||
suspend fun createTask(task: Task) = process(apiService.createTask(task))
|
||||
}
|
||||
|
|
@ -113,14 +113,16 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainViewModel>() {
|
|||
adapter.notifyItemChanged(0)
|
||||
val index = adapter.data.indexOfFirst { it.identifier == "stats" }
|
||||
adapter.data[index].detailText = getString(R.string.user_level, it.stats?.lvl ?: 0)
|
||||
adapter.notifyItemChanged(index)
|
||||
adapter.notifyItemChanged(index+1)
|
||||
}
|
||||
viewModel.taskCounts.observe(this) {
|
||||
adapter.data.forEach { menuItem ->
|
||||
if (it.containsKey(menuItem.identifier) && it[menuItem.identifier]!! > 0) {
|
||||
menuItem.detailText = it[menuItem.identifier].toString()
|
||||
} else {
|
||||
menuItem.detailText = null
|
||||
if (it.containsKey(menuItem.identifier)) {
|
||||
if (it[menuItem.identifier]!! > 0) {
|
||||
menuItem.detailText = it[menuItem.identifier].toString()
|
||||
} else {
|
||||
menuItem.detailText = null
|
||||
}
|
||||
}
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
package com.habitrpg.wearos.habitica.ui.activities
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.TextView
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.postDelayed
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.databinding.ActivityTaskFormBinding
|
||||
|
|
@ -25,7 +28,8 @@ class TaskFormActivity : BaseActivity<ActivityTaskFormBinding, TaskFormViewModel
|
|||
updateTaskTypeButton(binding.todoButton, TaskType.TODO)
|
||||
updateTaskTypeButton(binding.dailyButton, TaskType.DAILY)
|
||||
updateTaskTypeButton(binding.habitButton, TaskType.HABIT)
|
||||
binding.confirmationTitle.text = getString(R.string.create_task, value?.value)
|
||||
binding.confirmationTitle.text = getString(R.string.new_task_x, taskType?.value)
|
||||
binding.saveButton.text = getString(R.string.save_task_x, taskType?.value)
|
||||
}
|
||||
override val viewModel: TaskFormViewModel by viewModels()
|
||||
|
||||
|
|
@ -72,13 +76,24 @@ class TaskFormActivity : BaseActivity<ActivityTaskFormBinding, TaskFormViewModel
|
|||
binding.taskTypeHeader.isVisible = false
|
||||
binding.taskTypeWrapper.isVisible = false
|
||||
binding.header.textView.text = getString(R.string.create_task, taskType?.value)
|
||||
binding.confirmationTitle.text = getString(R.string.create_task, taskType?.value)
|
||||
binding.editText.requestFocus()
|
||||
} else {
|
||||
taskType = TaskType.TODO
|
||||
binding.header.textView.text = getString(R.string.create_task_title)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (binding.editText.hasFocus()) {
|
||||
binding.editText.postDelayed(100) {
|
||||
val imm: InputMethodManager =
|
||||
getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.showSoftInput(binding.editText, InputMethodManager.SHOW_FORCED)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTaskTypeButton(button: TextView, thisType: TaskType) {
|
||||
if (taskType == thisType) {
|
||||
button.backgroundTintList =
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
package com.habitrpg.wearos.habitica.ui.viewmodels
|
||||
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.habitrpg.wearos.habitica.data.repositories.TaskRepository
|
||||
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
|
||||
import com.habitrpg.wearos.habitica.managers.LoadingManager
|
||||
import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
|
|
@ -18,13 +16,4 @@ class MainViewModel @Inject constructor(
|
|||
) : BaseViewModel(userRepository, exceptionBuilder, loadingManager) {
|
||||
val taskCounts = taskRepository.getActiveTaskCounts().asLiveData()
|
||||
val user = userRepository.getUser().asLiveData()
|
||||
|
||||
init {
|
||||
viewModelScope.launch(exceptionBuilder.userFacing(this)) {
|
||||
loadingManager.startLoading()
|
||||
userRepository.retrieveUser()
|
||||
taskRepository.retrieveTasks()
|
||||
loadingManager.endLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ import com.habitrpg.wearos.habitica.managers.LoadingManager
|
|||
import com.habitrpg.wearos.habitica.models.tasks.Task
|
||||
import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -24,12 +25,16 @@ class TaskListViewModel @Inject constructor(
|
|||
) : BaseViewModel(userRepository, exceptionBuilder, loadingManager) {
|
||||
val taskType = TaskType.from(savedStateHandle.get<String>("task_type"))
|
||||
val tasks = taskRepository.getTasks(taskType ?: TaskType.HABIT).asLiveData()
|
||||
val user = userRepository.getUser()
|
||||
val user = userRepository.getUser()
|
||||
.asLiveData()
|
||||
|
||||
fun scoreTask(task: Task, direction: TaskDirection, onResult: (TaskScoringResult?) -> Unit) {
|
||||
viewModelScope.launch(exceptionBuilder.userFacing(this)) {
|
||||
val result = taskRepository.scoreTask(user.value, task, direction)
|
||||
val result = taskRepository.scoreTask(
|
||||
userRepository.localRepository.getUser().first(),
|
||||
task,
|
||||
direction
|
||||
)
|
||||
onResult(result)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@
|
|||
android:paddingHorizontal="16dp"
|
||||
android:background="@drawable/row_background_outline"
|
||||
android:autofillHints="username"
|
||||
android:textColorHint="@color/watch_gray_200"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginBottom="@dimen/spacing_small"/>
|
||||
<EditText
|
||||
|
|
@ -93,6 +94,7 @@
|
|||
android:background="@drawable/row_background_outline"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:autofillHints="password"
|
||||
android:textColorHint="@color/watch_gray_200"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginBottom="@dimen/spacing_small"/>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -12,14 +12,15 @@
|
|||
android:id="@+id/task_type_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
style="@style/Text.Body1"
|
||||
android:layout_marginBottom="10dp"/>
|
||||
<TextView
|
||||
android:id="@+id/task_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TextAppearance.AppCompat.Subhead"
|
||||
style="@style/Text.Subheader1"
|
||||
android:textColor="@color/white"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="18dp"/>
|
||||
<TextView
|
||||
android:id="@+id/task_notes_view"
|
||||
|
|
@ -27,12 +28,14 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/gray_400"
|
||||
android:textSize="14sp"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="30dp"/>
|
||||
<Button
|
||||
android:id="@+id/edit_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/ChipButton"
|
||||
android:drawableStart="@drawable/handoff"
|
||||
android:text="@string/edit_on_phone"/>
|
||||
</LinearLayout>
|
||||
</com.habitrpg.wearos.habitica.ui.views.HabiticaScrollView>
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
android:paddingHorizontal="18dp"
|
||||
android:hint="@string/task_title_hint"
|
||||
android:background="@drawable/row_background_outline"
|
||||
android:inputType="textCapWords" />
|
||||
android:inputType="textCapSentences" />
|
||||
<TextView
|
||||
android:id="@+id/task_type_header"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<com.habitrpg.wearos.habitica.ui.views.AddTaskButton
|
||||
android:id="@+id/add_task_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="44dp"
|
||||
android:layout_height="39dp"
|
||||
android:layout_gravity="center|bottom"
|
||||
app:layout_behavior="com.habitrpg.wearos.habitica.util.ScrollAwayBehavior"/>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
android:id="@+id/detail_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Text.Body2"
|
||||
style="@style/Text.Body1"
|
||||
android:textColor="@color/watch_purple_200"
|
||||
android:layout_marginEnd="@dimen/spacing_medium"/>
|
||||
</LinearLayout>
|
||||
|
|
|
|||
Loading…
Reference in a new issue