diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt index 85f019de4..d2ebc22f5 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt @@ -6,13 +6,22 @@ import android.view.ViewGroup import android.widget.FrameLayout import androidx.activity.ComponentActivity import androidx.core.view.children +import androidx.lifecycle.lifecycleScope import androidx.viewbinding.ViewBinding import androidx.wear.activity.ConfirmationActivity +import com.google.android.gms.tasks.Tasks +import com.google.android.gms.wearable.CapabilityClient +import com.google.android.gms.wearable.MessageClient +import com.google.android.gms.wearable.Wearable import com.habitrpg.android.habitica.databinding.ActivityWrapperBinding import com.habitrpg.wearos.habitica.ui.viewmodels.BaseViewModel import com.habitrpg.wearos.habitica.ui.views.IndeterminateProgressView +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch abstract class BaseActivity : ComponentActivity() { + val messageClient: MessageClient by lazy { Wearable.getMessageClient(this) } + val capabilityClient: CapabilityClient by lazy { Wearable.getCapabilityClient(this) } companion object { var currentActivityClassName: String? = null } @@ -64,4 +73,37 @@ abstract class BaseActivity : ComponentActivi } } } + + internal fun openRemoteActivity(url: String) { + sendMessage("open_activity", url, null) + } + + internal fun sendMessage( + permission: String, + url: String, + data: ByteArray?, + function: ((Boolean) -> Unit)? = null + ) { + lifecycleScope.launch(Dispatchers.IO) { + val info = Tasks.await( + capabilityClient.getCapability( + permission, + CapabilityClient.FILTER_REACHABLE + ) + ) + val nodeID = info.nodes.firstOrNull { it.isNearby } + if (nodeID != null) { + function?.invoke(true) + Tasks.await( + messageClient.sendMessage( + nodeID.id, + url, + data + ) + ) + } else { + function?.invoke(false) + } + } + } } \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/LoginActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/LoginActivity.kt index 4d448d8af..b7313743a 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/LoginActivity.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/LoginActivity.kt @@ -81,7 +81,7 @@ class LoginActivity: BaseActivity() { } private fun openRegisterOnPhone() { - + openRemoteActivity("/show/register") } private fun loginLocal() { diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/RYAActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/RYAActivity.kt index 582f8db14..c0d0acc47 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/RYAActivity.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/RYAActivity.kt @@ -4,9 +4,6 @@ import android.os.Bundle import androidx.activity.viewModels import androidx.core.view.children import androidx.core.view.isVisible -import com.google.android.gms.wearable.CapabilityClient -import com.google.android.gms.wearable.MessageClient -import com.google.android.gms.wearable.Wearable import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.ActivityRyaBinding import com.habitrpg.android.habitica.databinding.RowDailyBinding @@ -18,8 +15,6 @@ import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class RYAActivity : BaseActivity() { - val messageClient: MessageClient by lazy { Wearable.getMessageClient(this) } - val capabilityClient: CapabilityClient by lazy { Wearable.getCapabilityClient(this) } override val viewModel: RYAViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { @@ -40,7 +35,7 @@ class RYAActivity : BaseActivity() { } binding.phoneButton.setOnClickListener { - + openRemoteActivity("/show/rya") } binding.startDayButton.setOnClickListener { diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/SplashActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/SplashActivity.kt index 38080c4a3..dde4ac344 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/SplashActivity.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/SplashActivity.kt @@ -5,10 +5,6 @@ import android.os.Bundle import androidx.activity.viewModels import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope -import com.google.android.gms.tasks.Tasks -import com.google.android.gms.wearable.CapabilityClient -import com.google.android.gms.wearable.MessageClient -import com.google.android.gms.wearable.Wearable import com.habitrpg.android.habitica.databinding.ActivitySplashBinding import com.habitrpg.wearos.habitica.ui.viewmodels.SplashViewModel import dagger.hilt.android.AndroidEntryPoint @@ -18,8 +14,6 @@ import kotlinx.coroutines.launch @AndroidEntryPoint class SplashActivity: BaseActivity() { override val viewModel: SplashViewModel by viewModels() - private val messageClient: MessageClient by lazy { Wearable.getMessageClient(this) } - private val capabilityClient: CapabilityClient by lazy { Wearable.getCapabilityClient(this) } override fun onCreate(savedInstanceState: Bundle?) { binding = ActivitySplashBinding.inflate(layoutInflater) @@ -38,17 +32,14 @@ class SplashActivity: BaseActivity() { } messageClient.addListener(viewModel) - lifecycleScope.launch(Dispatchers.IO) { - val info = Tasks.await(capabilityClient.getCapability("provide_auth", CapabilityClient.FILTER_REACHABLE)) - val nodeID = info.nodes.firstOrNull { it.isNearby } - if (nodeID != null) { - showAccountLoader(true) - Tasks.await(messageClient.sendMessage(nodeID.id, "/request/auth", null)) - } else { - showAccountLoader(false) - startLoginActivity() + sendMessage("provide_auth", "/request/auth", null) { + if (it) { + showAccountLoader(true) + } else { + showAccountLoader(false) + startLoginActivity() + } } - } } private fun startMainActivity() { diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskDetailActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskDetailActivity.kt index 04ab8389b..03e9f282e 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskDetailActivity.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskDetailActivity.kt @@ -3,22 +3,13 @@ package com.habitrpg.wearos.habitica.ui.activities import android.os.Bundle import androidx.activity.viewModels import androidx.core.view.isVisible -import androidx.lifecycle.lifecycleScope -import com.google.android.gms.tasks.Tasks -import com.google.android.gms.wearable.CapabilityClient -import com.google.android.gms.wearable.MessageClient -import com.google.android.gms.wearable.Wearable import com.habitrpg.android.habitica.databinding.ActivityTaskDetailBinding import com.habitrpg.wearos.habitica.ui.viewmodels.TaskDetailViewModel import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch import java.util.Locale @AndroidEntryPoint class TaskDetailActivity: BaseActivity() { - val messageClient: MessageClient by lazy { Wearable.getMessageClient(this) } - val capabilityClient: CapabilityClient by lazy { Wearable.getCapabilityClient(this) } override val viewModel: TaskDetailViewModel by viewModels() @@ -34,13 +25,7 @@ class TaskDetailActivity: BaseActivity() { +class TaskFormActivity : BaseActivity() { var taskType: TaskType? = null - set(value) { - field = value - binding.taskTypeButton.text = value?.value - } + set(value) { + field = value + 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) + } override val viewModel: TaskFormViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { binding = ActivityTaskFormBinding.inflate(layoutInflater) super.onCreate(savedInstanceState) + binding.editText.setOnEditorActionListener { _, actionId, event -> + if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE) { + if (binding.editText.text?.isNotEmpty() == true) { + binding.editTaskWrapper.isVisible = false + binding.taskConfirmationWrapper.isVisible = true + binding.confirmationText.text = binding.editText.text + binding.editText.clearFocus() + } + } + false + } + binding.editButton.setOnClickListener { + binding.editTaskWrapper.isVisible = true + binding.taskConfirmationWrapper.isVisible = false + } + binding.todoButton.setOnClickListener { taskType = TaskType.TODO } + binding.dailyButton.setOnClickListener { taskType = TaskType.DAILY } + binding.habitButton.setOnClickListener { taskType = TaskType.HABIT } - binding.editText.doOnTextChanged { text, _, _, _ -> - binding.saveButton.isEnabled = text?.isNotBlank() == true - } - binding.taskTypeButton.setOnClickListener { - showTaskTypeSelector() - } binding.saveButton.setOnClickListener { binding.saveButton.isEnabled = false - lifecycleScope.launch { + lifecycleScope.launch(CoroutineExceptionHandler { _, _ -> + binding.saveButton.isEnabled = true + binding.editTaskWrapper.isVisible = true + binding.taskConfirmationWrapper.isVisible = false + }) { viewModel.saveTask(binding.editText.text, taskType) finish() + + parent.startActivity(Intent(parent, TaskListActivity::class.java).apply { + putExtra("task_type", taskType?.value) + }) } } if (intent.extras?.containsKey("task_type") == true) { taskType = TaskType.from(intent.getStringExtra("task_type")) - binding.taskTypeButton.isVisible = false + 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) } else { taskType = TaskType.TODO binding.header.textView.text = getString(R.string.create_task_title) } } - private fun showTaskTypeSelector() { - val taskTypes = arrayOf( - TaskType.HABIT, - TaskType.DAILY, - TaskType.TODO, - TaskType.REWARD - ) - val adapter = ArrayAdapter(this, R.layout.spinner_item, taskTypes) - val alert = AlertDialog.Builder(this).setAdapter(adapter) { _, which -> - taskType = taskTypes[which] - binding.taskTypeButton.text = taskType?.value + private fun updateTaskTypeButton(button: TextView, thisType: TaskType) { + if (taskType == thisType) { + button.backgroundTintList = + ColorStateList.valueOf(ContextCompat.getColor(this, R.color.watch_purple_10)) + button.background.alpha = 100 + button.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.radio_checked, 0) + } else { + button.backgroundTintList = + ColorStateList.valueOf(ContextCompat.getColor(this, R.color.watch_purple_5)) + button.background.alpha = 255 + button.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.radio_unchecked, 0) } - alert.show() } } \ No newline at end of file diff --git a/wearos/src/main/res/drawable/edit.xml b/wearos/src/main/res/drawable/edit.xml new file mode 100644 index 000000000..faddfce42 --- /dev/null +++ b/wearos/src/main/res/drawable/edit.xml @@ -0,0 +1,5 @@ + + + diff --git a/wearos/src/main/res/drawable/radio_checked.xml b/wearos/src/main/res/drawable/radio_checked.xml new file mode 100644 index 000000000..d49fac748 --- /dev/null +++ b/wearos/src/main/res/drawable/radio_checked.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wearos/src/main/res/drawable/radio_unchecked.xml b/wearos/src/main/res/drawable/radio_unchecked.xml new file mode 100644 index 000000000..b2a039403 --- /dev/null +++ b/wearos/src/main/res/drawable/radio_unchecked.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/wearos/src/main/res/drawable/save.xml b/wearos/src/main/res/drawable/save.xml new file mode 100644 index 000000000..5b1064846 --- /dev/null +++ b/wearos/src/main/res/drawable/save.xml @@ -0,0 +1,5 @@ + + + diff --git a/wearos/src/main/res/layout/activity_task_form.xml b/wearos/src/main/res/layout/activity_task_form.xml index ee116f8dc..3aaeea411 100644 --- a/wearos/src/main/res/layout/activity_task_form.xml +++ b/wearos/src/main/res/layout/activity_task_form.xml @@ -1,14 +1,61 @@ + android:layout_height="match_parent" + xmlns:tools="http://schemas.android.com/tools"> + + + +