mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-21 05:09:00 +00:00
fix wearos issues
This commit is contained in:
parent
1c71109ece
commit
02ae67be48
12 changed files with 103 additions and 30 deletions
53
Habitica/res/layout/preference_child_summary_disabled.xml
Normal file
53
Habitica/res/layout/preference_child_summary_disabled.xml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Layout for a visually child-like Preference in a PreferenceActivity. -->
|
||||
<!--suppress AndroidDomInspection -->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:paddingEnd="16dip"
|
||||
android:paddingStart="16dip"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="6dip"
|
||||
android:layout_marginStart="16dip"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_marginTop="6dip"
|
||||
android:layout_weight="1" >
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="@color/text_dimmed"
|
||||
tools:text="Title"/>
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignStart="@android:id/title"
|
||||
android:layout_below="@android:id/title"
|
||||
android:maxLines="4"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="@color/text_dimmed"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
<LinearLayout android:id="@android:id/widget_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="@dimen/spacing_large"/>
|
||||
</LinearLayout>
|
||||
|
|
@ -7,7 +7,9 @@ import android.os.Build
|
|||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.CheckBoxPreference
|
||||
import androidx.preference.ListPreference
|
||||
|
|
@ -95,6 +97,7 @@ class PreferencesFragment :
|
|||
timePreference = findPreference("reminder_time") as? TimePreference
|
||||
val useReminder = preferenceManager.sharedPreferences?.getBoolean("use_reminder", false)
|
||||
timePreference?.isEnabled = useReminder ?: false
|
||||
timePreference?.let { updatePreferenceEnabledView(it) }
|
||||
|
||||
classSelectionPreference = findPreference("choose_class")
|
||||
|
||||
|
|
@ -123,6 +126,11 @@ class PreferencesFragment :
|
|||
}
|
||||
}
|
||||
|
||||
private fun updatePreferenceEnabledView(preference: Preference) {
|
||||
val isEnabled = preference.isEnabled
|
||||
preference.layoutResource = if (isEnabled) R.layout.preference_child_summary else R.layout.preference_child_summary_disabled
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
preferenceManager.sharedPreferences?.registerOnSharedPreferenceChangeListener(this)
|
||||
|
|
@ -262,6 +270,7 @@ class PreferencesFragment :
|
|||
"use_reminder" -> {
|
||||
val useReminder = sharedPreferences.getBoolean(key, false)
|
||||
timePreference?.isEnabled = useReminder
|
||||
timePreference?.let { updatePreferenceEnabledView(it) }
|
||||
if (useReminder) {
|
||||
TaskAlarmManager.scheduleDailyReminder(context)
|
||||
} else {
|
||||
|
|
@ -279,6 +288,7 @@ class PreferencesFragment :
|
|||
pushNotificationManager.notificationPermissionEnabled()
|
||||
val usePushNotifications = sharedPreferences.getBoolean(key, true)
|
||||
pushNotificationsPreference?.isEnabled = usePushNotifications
|
||||
pushNotificationsPreference?.let { updatePreferenceEnabledView(it) }
|
||||
lifecycleScope.launchCatching {
|
||||
userRepository.updateUser(
|
||||
"preferences.pushNotifications.unsubscribeFromAll",
|
||||
|
|
@ -301,6 +311,7 @@ class PreferencesFragment :
|
|||
"useEmails" -> {
|
||||
val useEmailNotifications = sharedPreferences.getBoolean(key, true)
|
||||
emailNotificationsPreference?.isEnabled = useEmailNotifications
|
||||
emailNotificationsPreference?.let { updatePreferenceEnabledView(it) }
|
||||
lifecycleScope.launchCatching {
|
||||
userRepository.updateUser(
|
||||
"preferences.emailNotifications.unsubscribeFromAll",
|
||||
|
|
@ -490,6 +501,7 @@ class PreferencesFragment :
|
|||
val usePushNotifications =
|
||||
!(user?.preferences?.pushNotifications?.unsubscribeFromAll ?: false)
|
||||
pushNotificationsPreference?.isEnabled = usePushNotifications
|
||||
pushNotificationsPreference?.let { updatePreferenceEnabledView(it) }
|
||||
usePushPreference?.isChecked = (usePushNotifications && notifPermissionEnabled)
|
||||
if (!notifPermissionEnabled) {
|
||||
usePushPreference?.summary =
|
||||
|
|
@ -502,6 +514,7 @@ class PreferencesFragment :
|
|||
val useEmailNotifications =
|
||||
!(user?.preferences?.emailNotifications?.unsubscribeFromAll ?: false)
|
||||
emailNotificationsPreference?.isEnabled = useEmailNotifications
|
||||
emailNotificationsPreference?.let { updatePreferenceEnabledView(it) }
|
||||
useEmailPreference?.isChecked = useEmailNotifications
|
||||
|
||||
lifecycleScope.launch {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import com.jaredrummler.android.device.DeviceName
|
|||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
@AndroidEntryPoint
|
||||
|
|
@ -144,7 +145,7 @@ class FAQOverviewFragment : BaseMainFragment<FragmentFaqOverviewBinding>() {
|
|||
ds.isUnderlineText = false
|
||||
}
|
||||
}
|
||||
val startIndex = min(0, fullText.indexOf(clickableText))
|
||||
val startIndex = max(0, fullText.indexOf(clickableText))
|
||||
val endIndex = startIndex + clickableText.length
|
||||
spannableString.setSpan(clickableSpan, startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import android.widget.TextView
|
|||
import androidx.preference.ListPreference
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.common.habitica.extensions.setScaledPadding
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class HabiticaListPreference : ListPreference {
|
||||
|
|
@ -24,10 +25,8 @@ class HabiticaListPreference : ListPreference {
|
|||
val subtitleText = TextView(context)
|
||||
subtitleText.setText(R.string.cds_subtitle)
|
||||
val builder = AlertDialog.Builder(context).setSingleChoiceItems(entries, getValueIndex() + 1) { dialog, index ->
|
||||
val actualIndex = min(0, index - 1)
|
||||
if (callChangeListener(entryValues[actualIndex].toString())) {
|
||||
setValueIndex(actualIndex)
|
||||
}
|
||||
val actualIndex = max(0, index - 1)
|
||||
setValueIndex(actualIndex)
|
||||
dialog.dismiss()
|
||||
}
|
||||
.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() }
|
||||
|
|
|
|||
12
build.gradle
12
build.gradle
|
|
@ -13,7 +13,7 @@ buildscript {
|
|||
amplitude_version = '1.6.1'
|
||||
appcompat_version = '1.6.1'
|
||||
coil_version = '2.4.0'
|
||||
compose_version = '1.5.4'
|
||||
compose_version = '1.6.2'
|
||||
core_ktx_version = '1.12.0'
|
||||
coroutines_version = '1.7.3'
|
||||
daggerhilt_version = '2.47'
|
||||
|
|
@ -21,15 +21,15 @@ buildscript {
|
|||
kotest_version = '5.6.2'
|
||||
kotlin_version = '1.9.10'
|
||||
ktlint_version = '0.50.0'
|
||||
lifecycle_version = '2.6.2'
|
||||
lifecycle_version = '2.7.0'
|
||||
markwon_version = '4.6.2'
|
||||
mockk_version = '1.13.4'
|
||||
moshi_version = '1.15.0'
|
||||
navigation_version = '2.7.5'
|
||||
okhttp_version = '4.11.0'
|
||||
navigation_version = '2.7.7'
|
||||
okhttp_version = '4.12.0'
|
||||
paging_version = '3.2.1'
|
||||
play_wearables_version = '18.1.0'
|
||||
play_auth_version = '20.7.0'
|
||||
play_auth_version = '21.0.0'
|
||||
preferences_version = '1.2.1'
|
||||
realm_version = '1.0.2'
|
||||
retrofit_version = '2.9.0'
|
||||
|
|
@ -44,7 +44,7 @@ buildscript {
|
|||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.1.4'
|
||||
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
||||
classpath 'com.google.gms:google-services:4.4.0'
|
||||
classpath 'com.google.gms:google-services:4.4.1'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
|
||||
classpath "io.realm:realm-gradle-plugin:10.13.2-transformer-api"
|
||||
classpath("io.realm.kotlin:gradle-plugin:$realm_version")
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ dependencies {
|
|||
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
||||
implementation("androidx.navigation:navigation-common-ktx:$navigation_version")
|
||||
implementation("androidx.navigation:navigation-runtime-ktx:$navigation_version")
|
||||
implementation("com.google.android.material:material:1.10.0")
|
||||
implementation("com.google.android.material:material:1.11.0")
|
||||
|
||||
testImplementation("io.mockk:mockk:$mockk_version")
|
||||
testImplementation("io.mockk:mockk-android:$mockk_version")
|
||||
|
|
@ -131,13 +131,13 @@ dependencies {
|
|||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||
androidTestImplementation("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version")
|
||||
|
||||
implementation("androidx.activity:activity-compose:1.8.1")
|
||||
implementation("androidx.activity:activity-compose:1.8.2")
|
||||
implementation("androidx.compose.runtime:runtime-livedata:$compose_version")
|
||||
implementation("androidx.compose.material:material:$compose_version")
|
||||
implementation("androidx.compose.animation:animation:$compose_version")
|
||||
implementation("androidx.compose.ui:ui-text-google-fonts:$compose_version")
|
||||
implementation("androidx.compose.ui:ui-tooling:$compose_version")
|
||||
implementation("androidx.compose.material3:material3:1.1.2")
|
||||
implementation("androidx.compose.material3:material3:1.2.0")
|
||||
implementation("com.google.accompanist:accompanist-themeadapter-material:$accompanist_version")
|
||||
|
||||
implementation(project(":shared"))
|
||||
|
|
|
|||
|
|
@ -6,8 +6,11 @@ import com.habitrpg.common.habitica.BuildConfig
|
|||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.IOException
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
|
||||
class ExceptionHandler {
|
||||
private var exceptionLogger: ((Throwable) -> Unit)? = null
|
||||
|
|
@ -41,13 +44,11 @@ class ExceptionHandler {
|
|||
}
|
||||
}
|
||||
|
||||
fun CoroutineScope.launchCatching(errorHandler: ((Throwable) -> Unit)? = null, function: suspend CoroutineScope.() -> Unit) {
|
||||
fun CoroutineScope.launchCatching(errorHandler: ((Throwable) -> Unit)? = null, context: CoroutineContext = EmptyCoroutineContext, function: suspend CoroutineScope.() -> Unit) {
|
||||
launch(
|
||||
(
|
||||
ExceptionHandler.coroutine {
|
||||
errorHandler?.invoke(it)
|
||||
}
|
||||
),
|
||||
ExceptionHandler.coroutine {
|
||||
errorHandler?.invoke(it)
|
||||
} + context,
|
||||
block = function
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
NAME=4.3.5
|
||||
CODE=7061
|
||||
NAME=4.3.6
|
||||
CODE=7071
|
||||
|
|
@ -151,7 +151,7 @@ dependencies {
|
|||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
||||
implementation "androidx.preference:preference-ktx:$preferences_version"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:2.7.6"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:2.7.7"
|
||||
|
||||
implementation "com.google.android.gms:play-services-auth:$play_auth_version"
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.habitrpg.wearos.habitica.ui.activities
|
|||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.activity.ComponentActivity
|
||||
|
|
@ -18,6 +19,7 @@ import com.habitrpg.common.habitica.helpers.launchCatching
|
|||
import com.habitrpg.wearos.habitica.managers.AppStateManager
|
||||
import com.habitrpg.wearos.habitica.ui.viewmodels.BaseViewModel
|
||||
import com.habitrpg.wearos.habitica.ui.views.IndeterminateProgressView
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -95,7 +97,7 @@ abstract class BaseActivity<B : ViewBinding, VM : BaseViewModel> : ComponentActi
|
|||
}
|
||||
|
||||
internal fun openRemoteActivity(url: String, keepActive: Boolean = false) {
|
||||
sendMessage("open_activity", url, null)
|
||||
sendMessage("open_activity", url, null) {}
|
||||
startActivity(
|
||||
Intent(this, ContinuePhoneActivity::class.java)
|
||||
.apply {
|
||||
|
|
@ -108,9 +110,12 @@ abstract class BaseActivity<B : ViewBinding, VM : BaseViewModel> : ComponentActi
|
|||
permission: String,
|
||||
url: String,
|
||||
data: ByteArray?,
|
||||
function: ((Boolean) -> Unit)? = null
|
||||
function: ((Boolean) -> Unit)
|
||||
) {
|
||||
lifecycleScope.launchCatching {
|
||||
lifecycleScope.launchCatching({
|
||||
Log.e("BaseActivity", "Error sending message", it)
|
||||
function(false)
|
||||
}, Dispatchers.IO) {
|
||||
val info = Tasks.await(
|
||||
capabilityClient.getCapability(
|
||||
permission,
|
||||
|
|
@ -119,7 +124,7 @@ abstract class BaseActivity<B : ViewBinding, VM : BaseViewModel> : ComponentActi
|
|||
)
|
||||
val nodeID = info.nodes.firstOrNull()
|
||||
if (nodeID != null) {
|
||||
function?.invoke(true)
|
||||
function(true)
|
||||
try {
|
||||
Tasks.await(
|
||||
messageClient.sendMessage(
|
||||
|
|
@ -130,9 +135,10 @@ abstract class BaseActivity<B : ViewBinding, VM : BaseViewModel> : ComponentActi
|
|||
)
|
||||
} catch (_: ApiException) {
|
||||
// It's not connected
|
||||
function(false)
|
||||
}
|
||||
} else {
|
||||
function?.invoke(false)
|
||||
function(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class SplashActivity : BaseActivity<ActivitySplashBinding, SplashViewModel>() {
|
|||
} else {
|
||||
stopAnimatingProgress()
|
||||
}
|
||||
delay(90.toDuration(DurationUnit.SECONDS))
|
||||
delay(40.toDuration(DurationUnit.SECONDS))
|
||||
if (isActive) {
|
||||
// the sync attempt has timed out
|
||||
startLoginActivity()
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class TaskDetailActivity : BaseActivity<ActivityTaskDetailBinding, TaskDetailVie
|
|||
}
|
||||
|
||||
private fun openEditFormOnPhone() {
|
||||
sendMessage("edit_task", "/tasks/edit", viewModel.taskID?.toByteArray())
|
||||
sendMessage("edit_task", "/tasks/edit", viewModel.taskID?.toByteArray()) {}
|
||||
startActivity(
|
||||
Intent(this, ContinuePhoneActivity::class.java)
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue