mirror of
https://github.com/home-assistant/android
synced 2024-07-22 10:54:12 +00:00
Improve settings when using Home Assistant Cloud (#2965)
* Save cloud URL separately and add pref - Save the cloud / remote UI url that is received during registration separately, and add a preference to use the cloud url instead of the external url - Save the cloud / remote UI url and cloudhook url received during webhook config updates, to be able to support using cloud after the app was set up - Clean up cloudhook url when logging out * Add UI for "Use Home Assistant Cloud" url * Cleanup * Fix function order
This commit is contained in:
parent
3e72f2719d
commit
acd8d2d660
|
@ -44,6 +44,7 @@ import io.homeassistant.companion.android.settings.sensor.SensorSettingsFragment
|
|||
import io.homeassistant.companion.android.settings.sensor.SensorUpdateFrequencyFragment
|
||||
import io.homeassistant.companion.android.settings.shortcuts.ManageShortcutsSettingsFragment
|
||||
import io.homeassistant.companion.android.settings.ssid.SsidFragment
|
||||
import io.homeassistant.companion.android.settings.url.ExternalUrlFragment
|
||||
import io.homeassistant.companion.android.settings.wear.SettingsWearActivity
|
||||
import io.homeassistant.companion.android.settings.wear.SettingsWearDetection
|
||||
import io.homeassistant.companion.android.settings.websocket.WebsocketSettingFragment
|
||||
|
@ -152,8 +153,14 @@ class SettingsFragment constructor(
|
|||
onChangeUrlValidator
|
||||
}
|
||||
|
||||
findPreference<EditTextPreference>("connection_external")?.onPreferenceChangeListener =
|
||||
onChangeUrlValidator
|
||||
findPreference<Preference>("connection_external")?.setOnPreferenceClickListener {
|
||||
parentFragmentManager
|
||||
.beginTransaction()
|
||||
.replace(R.id.content, ExternalUrlFragment::class.java, null)
|
||||
.addToBackStack(getString(commonR.string.input_url))
|
||||
.commit()
|
||||
return@setOnPreferenceClickListener true
|
||||
}
|
||||
|
||||
findPreference<Preference>("connection_internal_ssids")?.let {
|
||||
it.setOnPreferenceClickListener {
|
||||
|
@ -420,6 +427,14 @@ class SettingsFragment constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun updateExternalUrl(url: String, useCloud: Boolean) {
|
||||
findPreference<Preference>("connection_external")?.let {
|
||||
it.summary =
|
||||
if (useCloud) getString(commonR.string.input_cloud)
|
||||
else url
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateSsids(ssids: Set<String>) {
|
||||
findPreference<Preference>("connection_internal_ssids")?.let {
|
||||
it.summary =
|
||||
|
@ -628,6 +643,7 @@ class SettingsFragment constructor(
|
|||
super.onResume()
|
||||
activity?.title = getString(commonR.string.companion_app)
|
||||
|
||||
presenter.updateExternalUrlStatus()
|
||||
presenter.updateInternalUrlStatus()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ interface SettingsPresenter {
|
|||
fun getPreferenceDataStore(): PreferenceDataStore
|
||||
fun onCreate()
|
||||
fun onFinish()
|
||||
fun updateExternalUrlStatus()
|
||||
fun updateInternalUrlStatus()
|
||||
fun isLockEnabled(): Boolean
|
||||
fun sessionTimeOut(): Int
|
||||
|
|
|
@ -77,8 +77,7 @@ class SettingsPresenterImpl @Inject constructor(
|
|||
override fun getString(key: String, defValue: String?): String? {
|
||||
return runBlocking {
|
||||
when (key) {
|
||||
"connection_internal" -> (urlUseCase.getUrl(true) ?: "").toString()
|
||||
"connection_external" -> (urlUseCase.getUrl(false) ?: "").toString()
|
||||
"connection_internal" -> (urlUseCase.getUrl(isInternal = true, force = true) ?: "").toString()
|
||||
"registration_name" -> integrationUseCase.getRegistration().deviceName
|
||||
"session_timeout" -> integrationUseCase.getSessionTimeOut().toString()
|
||||
"themes" -> themesManager.getCurrentTheme()
|
||||
|
@ -92,7 +91,6 @@ class SettingsPresenterImpl @Inject constructor(
|
|||
mainScope.launch {
|
||||
when (key) {
|
||||
"connection_internal" -> urlUseCase.saveUrl(value ?: "", true)
|
||||
"connection_external" -> urlUseCase.saveUrl(value ?: "", false)
|
||||
"session_timeout" -> {
|
||||
try {
|
||||
integrationUseCase.sessionTimeOut(value.toString().toInt())
|
||||
|
@ -142,6 +140,7 @@ class SettingsPresenterImpl @Inject constructor(
|
|||
override fun onCreate() {
|
||||
mainScope.launch {
|
||||
handleInternalUrlStatus(urlUseCase.getHomeWifiSsids())
|
||||
updateExternalUrlStatus()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,6 +148,15 @@ class SettingsPresenterImpl @Inject constructor(
|
|||
mainScope.cancel()
|
||||
}
|
||||
|
||||
override fun updateExternalUrlStatus() {
|
||||
mainScope.launch {
|
||||
settingsView.updateExternalUrl(
|
||||
urlUseCase.getUrl(false)?.toString() ?: "",
|
||||
urlUseCase.shouldUseCloud() && urlUseCase.canUseCloud()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateInternalUrlStatus() {
|
||||
mainScope.launch {
|
||||
handleInternalUrlStatus(urlUseCase.getHomeWifiSsids())
|
||||
|
|
|
@ -6,6 +6,8 @@ interface SettingsView {
|
|||
|
||||
fun enableInternalConnection()
|
||||
|
||||
fun updateExternalUrl(url: String, useCloud: Boolean)
|
||||
|
||||
fun updateSsids(ssids: Set<String>)
|
||||
|
||||
fun onLangSettingsChanged()
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package io.homeassistant.companion.android.settings.url
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.android.material.composethemeadapter.MdcTheme
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.homeassistant.companion.android.settings.url.views.ExternalUrlView
|
||||
import io.homeassistant.companion.android.common.R as commonR
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ExternalUrlFragment : Fragment() {
|
||||
|
||||
val viewModel by viewModels<ExternalUrlViewModel>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setHasOptionsMenu(false)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
return ComposeView(requireContext()).apply {
|
||||
setContent {
|
||||
MdcTheme {
|
||||
ExternalUrlView(
|
||||
canUseCloud = viewModel.canUseCloud,
|
||||
useCloud = viewModel.useCloud,
|
||||
externalUrl = viewModel.externalUrl,
|
||||
onUseCloudToggle = { viewModel.toggleCloud(it) },
|
||||
onExternalUrlSaved = { viewModel.updateExternalUrl(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
activity?.title = getString(commonR.string.input_url)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package io.homeassistant.companion.android.settings.url
|
||||
|
||||
import android.app.Application
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import io.homeassistant.companion.android.common.data.url.UrlRepository
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ExternalUrlViewModel @Inject constructor(
|
||||
private val urlRepository: UrlRepository,
|
||||
application: Application
|
||||
) : AndroidViewModel(application) {
|
||||
|
||||
var canUseCloud by mutableStateOf(false)
|
||||
private set
|
||||
|
||||
var useCloud by mutableStateOf(false)
|
||||
private set
|
||||
|
||||
var externalUrl by mutableStateOf("")
|
||||
private set
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
canUseCloud = urlRepository.canUseCloud()
|
||||
useCloud = urlRepository.shouldUseCloud()
|
||||
externalUrl = urlRepository.getUrl(isInternal = false, force = true).toString()
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleCloud(use: Boolean) {
|
||||
viewModelScope.launch {
|
||||
useCloud = if (use && canUseCloud) {
|
||||
urlRepository.setUseCloud(true)
|
||||
true
|
||||
} else {
|
||||
urlRepository.setUseCloud(false)
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateExternalUrl(url: String) {
|
||||
viewModelScope.launch {
|
||||
urlRepository.saveUrl(url, false)
|
||||
externalUrl = urlRepository.getUrl(isInternal = false, force = true)?.toString() ?: ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
package io.homeassistant.companion.android.settings.url.views
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.OutlinedTextField
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Error
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.unit.dp
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import io.homeassistant.companion.android.common.R as commonR
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
fun ExternalUrlInputView(
|
||||
url: String?,
|
||||
focusRequester: FocusRequester,
|
||||
onSaveUrl: (String) -> Unit
|
||||
) {
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
|
||||
var urlInput by remember(url) { mutableStateOf(url) }
|
||||
var urlError by remember { mutableStateOf(false) }
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = 16.dp)
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = urlInput ?: "",
|
||||
singleLine = true,
|
||||
onValueChange = {
|
||||
urlInput = it
|
||||
urlError = false
|
||||
},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = {
|
||||
urlError = !performUrlUpdate(urlInput?.trim(), url, onSaveUrl)
|
||||
if (!urlError) {
|
||||
keyboardController?.hide()
|
||||
focusManager.clearFocus()
|
||||
}
|
||||
}
|
||||
),
|
||||
placeholder = { Text(stringResource(commonR.string.input_url)) },
|
||||
isError = urlError,
|
||||
trailingIcon = if (urlError) {
|
||||
{
|
||||
Icon(
|
||||
imageVector = Icons.Default.Error,
|
||||
contentDescription = stringResource(commonR.string.url_invalid)
|
||||
)
|
||||
}
|
||||
} else null,
|
||||
modifier = Modifier
|
||||
.focusRequester(focusRequester)
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp)
|
||||
)
|
||||
|
||||
if (urlError) {
|
||||
Text(
|
||||
text = stringResource(commonR.string.url_parse_error),
|
||||
color = MaterialTheme.colors.error,
|
||||
style = MaterialTheme.typography.caption,
|
||||
modifier = Modifier.padding(start = 16.dp)
|
||||
)
|
||||
}
|
||||
|
||||
if (urlInput != url && urlInput?.trim()?.toHttpUrlOrNull()?.toString() != url) {
|
||||
TextButton(
|
||||
modifier = Modifier.align(Alignment.End),
|
||||
onClick = {
|
||||
urlError = !performUrlUpdate(urlInput?.trim(), url, onSaveUrl)
|
||||
if (!urlError) {
|
||||
keyboardController?.hide()
|
||||
focusManager.clearFocus()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(stringResource(commonR.string.update))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try saving the url with the value of the input.
|
||||
* @return boolean indicating if the url was saved successfully
|
||||
*/
|
||||
private fun performUrlUpdate(
|
||||
input: String?,
|
||||
current: String?,
|
||||
onSaveUrl: (String) -> Unit
|
||||
): Boolean {
|
||||
return if (input != current && input?.toHttpUrlOrNull()?.toString() != current) {
|
||||
val urlValue = input?.toHttpUrlOrNull()
|
||||
val isValid = urlValue != null
|
||||
if (isValid) {
|
||||
onSaveUrl(urlValue.toString())
|
||||
}
|
||||
isValid
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package io.homeassistant.companion.android.settings.url.views
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Switch
|
||||
import androidx.compose.material.SwitchDefaults
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.homeassistant.companion.android.common.R as commonR
|
||||
|
||||
@Composable
|
||||
fun ExternalUrlView(
|
||||
canUseCloud: Boolean,
|
||||
useCloud: Boolean,
|
||||
externalUrl: String?,
|
||||
onUseCloudToggle: (Boolean) -> Unit,
|
||||
onExternalUrlSaved: (String) -> Unit
|
||||
) {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = 16.dp)
|
||||
) {
|
||||
if (canUseCloud) {
|
||||
ExternalUrlCloudView(
|
||||
useCloud = useCloud,
|
||||
onUseCloudToggle = onUseCloudToggle
|
||||
)
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
}
|
||||
|
||||
if (!canUseCloud || !useCloud) {
|
||||
ExternalUrlInputView(
|
||||
url = externalUrl,
|
||||
focusRequester = focusRequester,
|
||||
onSaveUrl = onExternalUrlSaved
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
if (!canUseCloud) focusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ExternalUrlCloudView(
|
||||
useCloud: Boolean,
|
||||
onUseCloudToggle: (Boolean) -> Unit
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clickable { onUseCloudToggle(!useCloud) }
|
||||
.heightIn(min = 56.dp)
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(commonR.string.input_cloud),
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(end = 16.dp)
|
||||
)
|
||||
Switch(
|
||||
checked = useCloud,
|
||||
onCheckedChange = null,
|
||||
colors = SwitchDefaults.colors(uncheckedThumbColor = colorResource(commonR.color.colorSwitchUncheckedThumb))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewExternalUrlViewCloudOn() {
|
||||
ExternalUrlView(
|
||||
canUseCloud = true,
|
||||
useCloud = true,
|
||||
externalUrl = "https://home.example.com:8123/",
|
||||
onUseCloudToggle = {},
|
||||
onExternalUrlSaved = {}
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewExternalUrlViewCloudOff() {
|
||||
ExternalUrlView(
|
||||
canUseCloud = true,
|
||||
useCloud = false,
|
||||
externalUrl = "https://home.example.com:8123/",
|
||||
onUseCloudToggle = {},
|
||||
onExternalUrlSaved = {}
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewExternalUrlViewCloudNone() {
|
||||
ExternalUrlView(
|
||||
canUseCloud = false,
|
||||
useCloud = false,
|
||||
externalUrl = "https://home.example.com:8123/",
|
||||
onUseCloudToggle = {},
|
||||
onExternalUrlSaved = {}
|
||||
)
|
||||
}
|
|
@ -129,6 +129,7 @@ class WebViewPresenterImpl @Inject constructor(
|
|||
mainScope.launch {
|
||||
urlUseCase.saveUrl("", true)
|
||||
urlUseCase.saveUrl("", false)
|
||||
urlUseCase.updateCloudUrls(null, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,10 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_connection_title">
|
||||
<EditTextPreference
|
||||
<Preference
|
||||
android:key="connection_external"
|
||||
android:icon="@drawable/ic_globe"
|
||||
android:title="@string/pref_connection_url"
|
||||
app:useSimpleSummaryProvider="true"/>
|
||||
android:title="@string/pref_connection_url"/>
|
||||
<Preference
|
||||
android:key="connection_internal_ssids"
|
||||
android:icon="@drawable/ic_wifi"
|
||||
|
|
|
@ -77,6 +77,7 @@ class AuthenticationRepositoryImpl @Inject constructor(
|
|||
saveSession(null)
|
||||
urlRepository.saveUrl("", true)
|
||||
urlRepository.saveUrl("", false)
|
||||
urlRepository.updateCloudUrls(null, null)
|
||||
urlRepository.saveHomeWifiSsids(emptySet())
|
||||
}
|
||||
|
||||
|
|
|
@ -540,6 +540,7 @@ class IntegrationRepositoryImpl @Inject constructor(
|
|||
PREF_CHECK_SENSOR_REGISTRATION_NEXT,
|
||||
System.currentTimeMillis() + TimeUnit.HOURS.toMillis(4)
|
||||
)
|
||||
urlRepository.updateCloudUrls(response.cloudhookUrl, response.remoteUiUrl)
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,18 @@ interface UrlRepository {
|
|||
|
||||
suspend fun saveRegistrationUrls(cloudHookUrl: String?, remoteUiUrl: String?, webhookId: String)
|
||||
|
||||
suspend fun getUrl(isInternal: Boolean? = null): URL?
|
||||
suspend fun updateCloudUrls(cloudhookUrl: String?, remoteUiUrl: String?)
|
||||
|
||||
suspend fun getUrl(isInternal: Boolean? = null, force: Boolean = false): URL?
|
||||
|
||||
suspend fun saveUrl(url: String, isInternal: Boolean? = null)
|
||||
|
||||
suspend fun canUseCloud(): Boolean
|
||||
|
||||
suspend fun shouldUseCloud(): Boolean
|
||||
|
||||
suspend fun setUseCloud(use: Boolean)
|
||||
|
||||
suspend fun getHomeWifiSsids(): Set<String>
|
||||
|
||||
suspend fun saveHomeWifiSsids(ssid: Set<String>)
|
||||
|
|
|
@ -20,9 +20,11 @@ class UrlRepositoryImpl @Inject constructor(
|
|||
|
||||
companion object {
|
||||
private const val PREF_CLOUDHOOK_URL = "cloudhook_url"
|
||||
private const val PREF_CLOUD_UI_URL = "remote_ui_url"
|
||||
private const val PREF_REMOTE_URL = "remote_url"
|
||||
private const val PREF_WEBHOOK_ID = "webhook_id"
|
||||
private const val PREF_LOCAL_URL = "local_url"
|
||||
private const val PREF_USE_CLOUD = "use_cloud"
|
||||
private const val PREF_WIFI_SSIDS = "wifi_ssids"
|
||||
private const val PREF_PRIORITIZE_INTERNAL = "prioritize_internal"
|
||||
private const val TAG = "UrlRepository"
|
||||
|
@ -76,18 +78,29 @@ class UrlRepositoryImpl @Inject constructor(
|
|||
) {
|
||||
localStorage.putString(PREF_CLOUDHOOK_URL, cloudHookUrl)
|
||||
localStorage.putString(PREF_WEBHOOK_ID, webhookId)
|
||||
remoteUiUrl?.let {
|
||||
localStorage.putString(PREF_REMOTE_URL, it)
|
||||
}
|
||||
localStorage.putString(PREF_CLOUD_UI_URL, remoteUiUrl)
|
||||
localStorage.putBoolean(PREF_USE_CLOUD, remoteUiUrl != null)
|
||||
}
|
||||
|
||||
override suspend fun getUrl(isInternal: Boolean?): URL? {
|
||||
override suspend fun updateCloudUrls(
|
||||
cloudhookUrl: String?,
|
||||
remoteUiUrl: String?
|
||||
) {
|
||||
localStorage.putString(PREF_CLOUDHOOK_URL, cloudhookUrl)
|
||||
localStorage.putString(PREF_CLOUD_UI_URL, remoteUiUrl)
|
||||
}
|
||||
|
||||
override suspend fun getUrl(isInternal: Boolean?, force: Boolean): URL? {
|
||||
val internal = localStorage.getString(PREF_LOCAL_URL)?.toHttpUrlOrNull()?.toUrl()
|
||||
val external = localStorage.getString(PREF_REMOTE_URL)?.toHttpUrlOrNull()?.toUrl()
|
||||
val cloud = localStorage.getString(PREF_CLOUD_UI_URL)?.toHttpUrlOrNull()?.toUrl()
|
||||
|
||||
return if (isInternal ?: isInternal() && internal != null) {
|
||||
return if (isInternal ?: isInternal() && (internal != null || force)) {
|
||||
Log.d(TAG, "Using internal URL")
|
||||
internal
|
||||
} else if (!force && shouldUseCloud() && cloud != null) {
|
||||
Log.d(TAG, "Using cloud / remote UI URL")
|
||||
cloud
|
||||
} else {
|
||||
Log.d(TAG, "Using external URL")
|
||||
external
|
||||
|
@ -110,6 +123,18 @@ class UrlRepositoryImpl @Inject constructor(
|
|||
localStorage.putString(if (isInternal ?: isInternal()) PREF_LOCAL_URL else PREF_REMOTE_URL, trimUrl)
|
||||
}
|
||||
|
||||
override suspend fun canUseCloud(): Boolean {
|
||||
return !localStorage.getString(PREF_CLOUD_UI_URL).isNullOrBlank()
|
||||
}
|
||||
|
||||
override suspend fun shouldUseCloud(): Boolean {
|
||||
return localStorage.getBoolean(PREF_USE_CLOUD)
|
||||
}
|
||||
|
||||
override suspend fun setUseCloud(use: Boolean) {
|
||||
localStorage.putBoolean(PREF_USE_CLOUD, use)
|
||||
}
|
||||
|
||||
override suspend fun getHomeWifiSsids(): Set<String> {
|
||||
return localStorage.getStringSet(PREF_WIFI_SSIDS) ?: emptySet()
|
||||
}
|
||||
|
|
|
@ -12,5 +12,7 @@ data class GetConfigResponse(
|
|||
val timeZone: String,
|
||||
val components: List<String>,
|
||||
val version: String,
|
||||
var cloudhookUrl: String?, // only when using webhook
|
||||
var remoteUiUrl: String?, // only when using webhook
|
||||
val entities: Map<String, Map<String, Any>>? // only on core >= 2022.6 when using webhook
|
||||
)
|
||||
|
|
|
@ -242,6 +242,7 @@
|
|||
<string name="icon">Icon</string>
|
||||
<string name="input_booleans">Input Booleans</string>
|
||||
<string name="input_buttons">Input Buttons</string>
|
||||
<string name="input_cloud">Use Home Assistant Cloud</string>
|
||||
<string name="input_url_hint">https://example.duckdns.org:8123</string>
|
||||
<string name="input_url">Home Assistant URL</string>
|
||||
<string name="install_app">Install App on Wear Device</string>
|
||||
|
@ -758,7 +759,7 @@
|
|||
<string name="update_widget">Update Widget</string>
|
||||
<string name="updating_sensors">Updating Sensors</string>
|
||||
<string name="url_invalid">Url Invalid</string>
|
||||
<string name="url_parse_error">Unable to parse your Home Assistant URL. It should look like https://example.com</string>
|
||||
<string name="url_parse_error">Unable to parse your URL. It should look like this: https://example.com.</string>
|
||||
<string name="username">Username</string>
|
||||
<string name="version">Version: %s</string>
|
||||
<string name="view_password">View Password</string>
|
||||
|
|
Loading…
Reference in a new issue