This commit is contained in:
Phillip Thelen 2022-06-27 22:09:27 +02:00
parent 0d0c4e4038
commit 6791b1e065
13 changed files with 104 additions and 31 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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