Auto-login user if they are logged in on phone

This commit is contained in:
Phillip Thelen 2022-06-10 10:01:17 +02:00
parent 29be9a4ee3
commit 29c0c37e0e
33 changed files with 251 additions and 67 deletions

View file

@ -302,6 +302,15 @@
android:name=".widget.TodosWidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS" />
<service android:name=".widget.HabitButtonWidgetService"/>
<service android:name=".receivers.DeviceCommunicationService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data android:scheme="wear" android:host="*" />
</intent-filter>
</service>
</application>
<queries>

View file

@ -8,6 +8,7 @@ import com.habitrpg.android.habitica.helpers.notifications.HabiticaFirebaseMessa
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager;
import com.habitrpg.android.habitica.modules.UserModule;
import com.habitrpg.android.habitica.modules.UserRepositoryModule;
import com.habitrpg.android.habitica.receivers.DeviceCommunicationService;
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver;
import com.habitrpg.android.habitica.receivers.NotificationPublisher;
import com.habitrpg.android.habitica.receivers.TaskAlarmBootReceiver;
@ -367,4 +368,6 @@ public interface UserComponent {
void inject(@NotNull StableViewModel stableViewModel);
void inject(@NotNull DeathActivity deathActivity);
void inject(@NotNull DeviceCommunicationService deviceCommunicationService);
}

View file

@ -232,7 +232,7 @@ class ApiClientImpl(
if (res.message != null && res.message == "RECEIPT_ALREADY_USED") {
return
}
}
if (error.response()?.raw()?.request?.url?.toString()?.endsWith("/user/push-devices") == true) {
// workaround for an error that sometimes displays that the user already has this push device
return

View file

@ -0,0 +1,32 @@
package com.habitrpg.android.habitica.receivers
import android.util.Log
import com.google.android.gms.wearable.MessageEvent
import com.google.android.gms.wearable.Wearable
import com.google.android.gms.wearable.WearableListenerService
import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.common.habitica.api.HostConfig
import javax.inject.Inject
class DeviceCommunicationService: WearableListenerService() {
@Inject
lateinit var hostConfig: HostConfig
private val messageClient by lazy { Wearable.getMessageClient(this) }
init {
HabiticaBaseApplication.userComponent?.inject(this)
}
override fun onMessageReceived(event: MessageEvent) {
super.onMessageReceived(event)
when (event.path) {
"/request/auth" -> processAuthRequest(event)
}
}
private fun processAuthRequest(event: MessageEvent) {
Log.d("DeviceCommunicationServ", "processAuthRequest: AUTH REQUESTED")
messageClient.sendMessage(event.sourceNodeId, "/auth", "${hostConfig.userID}:${hostConfig.apiKey}".toByteArray())
}
}

View file

@ -127,6 +127,6 @@ class LocalNotificationActionReceiver : BroadcastReceiver() {
}
private fun getMessageText(key: String?): String? {
return RemoteInput.getResultsFromIntent(intent)?.getCharSequence(key)?.toString()
return intent?.let { RemoteInput.getResultsFromIntent(it)?.getCharSequence(key)?.toString() }
}
}

View file

@ -21,6 +21,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavDestination
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import com.google.android.gms.wearable.Wearable
import com.google.firebase.perf.FirebasePerformance
import com.habitrpg.android.habitica.BuildConfig
import com.habitrpg.android.habitica.R
@ -30,10 +31,7 @@ import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.data.TaskRepository
import com.habitrpg.android.habitica.data.local.UserQuestStatus
import com.habitrpg.android.habitica.databinding.ActivityMainBinding
import com.habitrpg.common.habitica.extensions.dpToPx
import com.habitrpg.common.habitica.extensions.getThemeColor
import com.habitrpg.android.habitica.extensions.hideKeyboard
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
import com.habitrpg.android.habitica.extensions.observeOnce
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
import com.habitrpg.android.habitica.extensions.updateStatusBarColor
@ -47,10 +45,7 @@ import com.habitrpg.android.habitica.interactors.CheckClassSelectionUseCase
import com.habitrpg.android.habitica.interactors.DisplayItemDropUseCase
import com.habitrpg.android.habitica.interactors.NotifyUserUseCase
import com.habitrpg.android.habitica.models.TutorialStep
import com.habitrpg.common.habitica.models.responses.MaintenanceResponse
import com.habitrpg.common.habitica.models.responses.TaskScoringResult
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.common.habitica.views.AvatarView
import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel
import com.habitrpg.android.habitica.ui.TutorialView
import com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment
@ -63,6 +58,12 @@ import com.habitrpg.android.habitica.widget.AvatarStatsWidgetProvider
import com.habitrpg.android.habitica.widget.DailiesWidgetProvider
import com.habitrpg.android.habitica.widget.HabitButtonWidgetProvider
import com.habitrpg.android.habitica.widget.TodoListWidgetProvider
import com.habitrpg.common.habitica.extensions.dpToPx
import com.habitrpg.common.habitica.extensions.getThemeColor
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
import com.habitrpg.common.habitica.models.responses.MaintenanceResponse
import com.habitrpg.common.habitica.models.responses.TaskScoringResult
import com.habitrpg.common.habitica.views.AvatarView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
@ -140,6 +141,8 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
return
} else {
Wearable.getCapabilityClient(this).addLocalCapability("provide_auth")
}
setupToolbar(binding.toolbar)

View file

@ -12,11 +12,11 @@ import com.habitrpg.common.habitica.BuildConfig
fun Application.setupCoil() {
var builder = ImageLoader.Builder(this)
.allowHardware(false)
.componentRegistry {
.components {
if (Build.VERSION.SDK_INT >= 28) {
add(ImageDecoderDecoder(this@setupCoil))
add(ImageDecoderDecoder.Factory())
} else {
add(GifDecoder())
add(GifDecoder.Factory())
}
}
if (BuildConfig.DEBUG) {

View file

@ -15,7 +15,7 @@ import android.widget.ImageView
import androidx.core.graphics.drawable.toBitmap
import androidx.core.view.marginStart
import androidx.core.view.marginTop
import coil.clear
import coil.dispose
import coil.load
import com.habitrpg.common.habitica.BuildConfig
import com.habitrpg.common.habitica.R
@ -150,7 +150,7 @@ class AvatarView : FrameLayout {
continue
}
imageView.tag = layerName
imageView.clear()
imageView.dispose()
imageView.setImageResource(0)
imageView.load(
@ -182,7 +182,7 @@ class AvatarView : FrameLayout {
}
}
while (i < (imageViewHolder.size)) {
imageViewHolder[i].clear()
imageViewHolder[i].dispose()
imageViewHolder[i].setImageResource(0)
imageViewHolder[i].tag = null
i++

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.habitrpg.wearos.habitica">
package="com.habitrpg.android.habitica">
<uses-permission android:name="android.permission.WAKE_LOCK" />
@ -11,16 +11,11 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:name=".MainApplication"
android:name="com.habitrpg.wearos.habitica.MainApplication"
android:theme="@style/Theme.AppCompat.NoActionBar">
<uses-library
android:name="com.google.android.wearable"
android:required="true" />
<!--
Set to true if your app is Standalone, that is, it does not require the handheld
app to run.
-->
<meta-data
android:name="com.google.android.wearable.standalone"
android:value="true" />
@ -29,20 +24,23 @@
android:name="com.habitrpg.wearos.habitica.ui.activities.MainActivity"
android:exported="true"
android:label="@string/app_name">
</activity>
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.SplashActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ui.activities.LoginActivity" />
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.LoginActivity" />
<activity android:name=".ui.activities.TaskListActivity" />
<activity android:name=".ui.activities.TaskFormActivity" />
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.TaskListActivity" />
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.TaskFormActivity" />
<activity android:name=".ui.activities.AvatarActivity" />
<activity android:name=".ui.activities.StatsActivity" />
<activity android:name=".ui.activities.SettingsActivity" />
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.AvatarActivity" />
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.StatsActivity" />
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.SettingsActivity" />
<activity android:name="androidx.wear.activity.ConfirmationActivity" />
</application>

View file

@ -3,11 +3,11 @@ package com.habitrpg.wearos.habitica.models.tasks
import android.os.Parcel
import android.os.Parcelable
import android.text.Spanned
import com.habitrpg.android.habitica.R
import com.habitrpg.common.habitica.helpers.MarkdownParser
import com.habitrpg.common.habitica.models.tasks.Attribute
import com.habitrpg.common.habitica.models.tasks.Frequency
import com.habitrpg.common.habitica.models.tasks.TaskType
import com.habitrpg.wearos.habitica.R
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.json.JSONArray

View file

@ -7,7 +7,7 @@ import android.view.ViewOutlineProvider
import android.widget.FrameLayout
import androidx.activity.viewModels
import com.habitrpg.common.habitica.extensions.dpToPx
import com.habitrpg.wearos.habitica.databinding.ActivityAvatarBinding
import com.habitrpg.android.habitica.databinding.ActivityAvatarBinding
import com.habitrpg.wearos.habitica.ui.viewmodels.AvatarViewModel
import dagger.hilt.android.AndroidEntryPoint
import java.lang.Integer.max

View file

@ -7,13 +7,10 @@ import android.content.Intent
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import com.habitrpg.common.habitica.models.auth.UserAuthResponse
import com.habitrpg.wearos.habitica.R
import com.habitrpg.wearos.habitica.databinding.ActivityLoginBinding
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.ActivityLoginBinding
import com.habitrpg.wearos.habitica.ui.viewmodels.LoginViewModel
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
@AndroidEntryPoint
class LoginActivity: BaseActivity<ActivityLoginBinding, LoginViewModel>() {

View file

@ -7,8 +7,8 @@ import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import androidx.wear.widget.WearableLinearLayoutManager
import com.habitrpg.common.habitica.models.tasks.TaskType
import com.habitrpg.wearos.habitica.R
import com.habitrpg.wearos.habitica.databinding.ActivityMainBinding
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.ActivityMainBinding
import com.habitrpg.wearos.habitica.models.MenuItem
import com.habitrpg.wearos.habitica.ui.adapters.HubAdapter
import com.habitrpg.wearos.habitica.ui.viewmodels.MainViewModel
@ -28,9 +28,6 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainViewModel>() {
WearableLinearLayoutManager(this@MainActivity, HabiticaScrollingLayoutCallback())
adapter = this@MainActivity.adapter
}
if (!viewModel.isAuthenticated) {
openLoginActivity()
}
}
override fun onStart() {
@ -125,12 +122,6 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainViewModel>() {
startActivity(Intent(this, SettingsActivity::class.java))
}
private fun openLoginActivity() {
val intent = Intent(this, LoginActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
private fun openTasklist(type: TaskType) {
val intent = Intent(this, TaskListActivity::class.java).apply {
putExtra("task_type", type.value)

View file

@ -4,8 +4,8 @@ import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.wear.widget.WearableLinearLayoutManager
import com.habitrpg.wearos.habitica.R
import com.habitrpg.wearos.habitica.databinding.ActivitySettingsBinding
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.ActivitySettingsBinding
import com.habitrpg.wearos.habitica.ui.adapters.SettingsAdapter
import com.habitrpg.wearos.habitica.ui.adapters.SettingsItem
import com.habitrpg.wearos.habitica.ui.viewmodels.SettingsViewModel

View file

@ -0,0 +1,75 @@
package com.habitrpg.wearos.habitica.ui.activities
import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
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
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@AndroidEntryPoint
class SplashActivity: BaseActivity<ActivitySplashBinding, SplashViewModel>() {
override val viewModel: SplashViewModel by viewModels()
val messageClient: MessageClient by lazy { Wearable.getMessageClient(this) }
val capabilityClient: CapabilityClient by lazy { Wearable.getCapabilityClient(this) }
override fun onCreate(savedInstanceState: Bundle?) {
binding = ActivitySplashBinding.inflate(layoutInflater)
super.onCreate(savedInstanceState)
if (viewModel.hasAuthentication) {
startMainActivity()
}
viewModel.onLoginCompleted = {
if (it) {
startMainActivity()
} else {
startLoginActivity()
}
}
}
private fun startMainActivity() {
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
private fun startLoginActivity() {
val intent = Intent(this, LoginActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
private fun requestAuthenticationData(nodeID: String) {
Tasks.await(messageClient.sendMessage(nodeID, "/request/auth", null).apply {
addOnSuccessListener {
}
})
}
override fun onResume() {
super.onResume()
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) {
requestAuthenticationData(nodeID.id)
}
}
}
override fun onPause() {
messageClient.removeListener(viewModel)
super.onPause()
}
}

View file

@ -2,7 +2,7 @@ package com.habitrpg.wearos.habitica.ui.activities
import android.os.Bundle
import androidx.activity.viewModels
import com.habitrpg.wearos.habitica.databinding.ActivityStatsBinding
import com.habitrpg.android.habitica.databinding.ActivityStatsBinding
import com.habitrpg.wearos.habitica.ui.viewmodels.StatsViewModel
import dagger.hilt.android.AndroidEntryPoint

View file

@ -2,7 +2,7 @@ package com.habitrpg.wearos.habitica.ui.activities
import android.os.Bundle
import androidx.activity.viewModels
import com.habitrpg.wearos.habitica.databinding.ActivityTaskFormBinding
import com.habitrpg.android.habitica.databinding.ActivityTaskFormBinding
import com.habitrpg.wearos.habitica.ui.viewmodels.TaskFormViewModel
import dagger.hilt.android.AndroidEntryPoint

View file

@ -8,8 +8,8 @@ import androidx.wear.widget.WearableLinearLayoutManager
import com.habitrpg.common.habitica.models.responses.TaskDirection
import com.habitrpg.common.habitica.models.responses.TaskScoringResult
import com.habitrpg.common.habitica.models.tasks.TaskType
import com.habitrpg.wearos.habitica.R
import com.habitrpg.wearos.habitica.databinding.ActivityTasklistBinding
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.ActivityTasklistBinding
import com.habitrpg.wearos.habitica.models.tasks.Task
import com.habitrpg.wearos.habitica.ui.adapters.DailyListAdapter
import com.habitrpg.wearos.habitica.ui.adapters.HabitListAdapter

View file

@ -3,7 +3,7 @@ package com.habitrpg.wearos.habitica.ui.adapters
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.habitrpg.common.habitica.extensions.layoutInflater
import com.habitrpg.wearos.habitica.databinding.RowDailyBinding
import com.habitrpg.android.habitica.databinding.RowDailyBinding
import com.habitrpg.wearos.habitica.ui.viewHolders.tasks.DailyViewHolder
class DailyListAdapter: TaskListAdapter() {

View file

@ -3,7 +3,7 @@ package com.habitrpg.wearos.habitica.ui.adapters
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.habitrpg.common.habitica.extensions.layoutInflater
import com.habitrpg.wearos.habitica.databinding.RowHabitBinding
import com.habitrpg.android.habitica.databinding.RowHabitBinding
import com.habitrpg.wearos.habitica.ui.viewHolders.tasks.HabitViewHolder
class HabitListAdapter: TaskListAdapter() {

View file

@ -3,8 +3,8 @@ package com.habitrpg.wearos.habitica.ui.adapters
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.habitrpg.common.habitica.extensions.layoutInflater
import com.habitrpg.wearos.habitica.databinding.RowHeaderBinding
import com.habitrpg.wearos.habitica.databinding.RowHubBinding
import com.habitrpg.android.habitica.databinding.RowHeaderBinding
import com.habitrpg.android.habitica.databinding.RowHubBinding
import com.habitrpg.wearos.habitica.models.MenuItem
import com.habitrpg.wearos.habitica.ui.viewHolders.HeaderViewHolder
import com.habitrpg.wearos.habitica.ui.viewHolders.HubViewHolder

View file

@ -3,7 +3,7 @@ package com.habitrpg.wearos.habitica.ui.adapters
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.habitrpg.common.habitica.extensions.layoutInflater
import com.habitrpg.wearos.habitica.databinding.RowRewardBinding
import com.habitrpg.android.habitica.databinding.RowRewardBinding
import com.habitrpg.wearos.habitica.ui.viewHolders.tasks.RewardViewHolder
class RewardListAdapter: TaskListAdapter() {

View file

@ -5,8 +5,8 @@ import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.habitrpg.common.habitica.extensions.layoutInflater
import com.habitrpg.wearos.habitica.R
import com.habitrpg.wearos.habitica.databinding.RowSettingsBinding
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.RowSettingsBinding
import com.habitrpg.wearos.habitica.ui.viewHolders.BindableViewHolder
class SettingsAdapter: RecyclerView.Adapter<SettingsViewHolder>() {

View file

@ -3,7 +3,7 @@ package com.habitrpg.wearos.habitica.ui.adapters
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.habitrpg.common.habitica.extensions.layoutInflater
import com.habitrpg.wearos.habitica.databinding.RowHeaderBinding
import com.habitrpg.android.habitica.databinding.RowHeaderBinding
import com.habitrpg.wearos.habitica.models.tasks.Task
import com.habitrpg.wearos.habitica.ui.viewHolders.HeaderViewHolder
import com.habitrpg.wearos.habitica.ui.viewHolders.tasks.TaskViewHolder

View file

@ -3,7 +3,7 @@ package com.habitrpg.wearos.habitica.ui.adapters
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.habitrpg.common.habitica.extensions.layoutInflater
import com.habitrpg.wearos.habitica.databinding.RowTodoBinding
import com.habitrpg.android.habitica.databinding.RowTodoBinding
import com.habitrpg.wearos.habitica.ui.viewHolders.tasks.ToDoViewHolder
class ToDoListAdapter: TaskListAdapter() {

View file

@ -1,7 +1,7 @@
package com.habitrpg.wearos.habitica.ui.viewHolders
import android.view.View
import com.habitrpg.wearos.habitica.databinding.RowHeaderBinding
import com.habitrpg.android.habitica.databinding.RowHeaderBinding
class HeaderViewHolder(itemView: View): BindableViewHolder<String>(itemView) {
private val binding = RowHeaderBinding.bind(itemView)

View file

@ -3,8 +3,8 @@ package com.habitrpg.wearos.habitica.ui.viewHolders
import android.content.res.ColorStateList
import android.view.View
import androidx.core.content.ContextCompat
import com.habitrpg.wearos.habitica.R
import com.habitrpg.wearos.habitica.databinding.RowHubBinding
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.RowHubBinding
import com.habitrpg.wearos.habitica.models.MenuItem
class HubViewHolder(itemView: View): BindableViewHolder<MenuItem>(itemView) {

View file

@ -4,7 +4,7 @@ import android.content.res.ColorStateList
import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.habitrpg.wearos.habitica.databinding.RowDailyBinding
import com.habitrpg.android.habitica.databinding.RowDailyBinding
import com.habitrpg.wearos.habitica.models.tasks.Task
class DailyViewHolder(itemView: View) : TaskViewHolder(itemView) {

View file

@ -4,7 +4,7 @@ import android.content.res.ColorStateList
import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.habitrpg.wearos.habitica.databinding.RowHabitBinding
import com.habitrpg.android.habitica.databinding.RowHabitBinding
import com.habitrpg.wearos.habitica.models.tasks.Task
class HabitViewHolder(itemView: View) : TaskViewHolder(itemView) {

View file

@ -2,7 +2,7 @@ package com.habitrpg.wearos.habitica.ui.viewHolders.tasks
import android.view.View
import android.widget.TextView
import com.habitrpg.wearos.habitica.databinding.RowRewardBinding
import com.habitrpg.android.habitica.databinding.RowRewardBinding
import com.habitrpg.wearos.habitica.models.tasks.Task
class RewardViewHolder(itemView: View) : TaskViewHolder(itemView) {

View file

@ -4,7 +4,7 @@ import android.content.res.ColorStateList
import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.habitrpg.wearos.habitica.databinding.RowTodoBinding
import com.habitrpg.android.habitica.databinding.RowTodoBinding
import com.habitrpg.wearos.habitica.models.tasks.Task
class ToDoViewHolder(itemView: View) : TaskViewHolder(itemView) {

View file

@ -0,0 +1,69 @@
package com.habitrpg.wearos.habitica.ui.viewmodels
import android.content.SharedPreferences
import androidx.core.content.edit
import androidx.lifecycle.viewModelScope
import com.google.android.gms.wearable.MessageClient
import com.google.android.gms.wearable.MessageEvent
import com.habitrpg.common.habitica.api.HostConfig
import com.habitrpg.common.habitica.helpers.KeyHelper
import com.habitrpg.wearos.habitica.data.ApiClient
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class SplashViewModel @Inject constructor(userRepository: UserRepository,
exceptionBuilder: ExceptionHandlerBuilder,
val hostConfig: HostConfig,
val apiClient: ApiClient,
val sharedPreferences: SharedPreferences,
val keyHelper: KeyHelper?
) : BaseViewModel(userRepository, exceptionBuilder), MessageClient.OnMessageReceivedListener {
lateinit var onLoginCompleted: (Boolean) -> Unit
val hasAuthentication: Boolean
get() {
return hostConfig.hasAuthentication()
}
override fun onMessageReceived(event: MessageEvent) {
when (event.path) {
"/auth" -> authDataReceived(event)
}
}
private fun authDataReceived(event: MessageEvent) {
viewModelScope.launch(exceptionBuilder.silent()) {
val (userID, apiKey) = String(event.data).split(":")
try {
saveTokens(apiKey, userID)
} catch (e: Exception) {
}
retrieveUser()
onLoginCompleted(true)
}
}
@Throws(Exception::class)
private fun saveTokens(api: String, user: String) {
this.apiClient.updateAuthenticationCredentials(user, api)
sharedPreferences.edit {
putString("UserID", user)
val encryptedKey =
try {
keyHelper?.encrypt(api)
} catch (e: Exception) {
null
}
if ((encryptedKey?.length ?: 0) > 5) {
putString(user, encryptedKey)
} else {
// Something might have gone wrong with encryption, so fall back to this.
putString("APIToken", api)
}
}
}
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>