Shortcut path input improvements (#3831)

This commit is contained in:
Joris Pelgröm 2023-09-01 01:53:32 +02:00 committed by GitHub
parent 90bf7369e2
commit b6687dc762
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 14 deletions

View file

@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Button
import androidx.compose.material.Divider
import androidx.compose.material.DropdownMenu
@ -31,6 +32,8 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.mikepenz.iconics.compose.IconicsPainter
@ -230,6 +233,7 @@ private fun CreateShortcutView(
value = viewModel.shortcuts[i].path.value,
onValueChange = { viewModel.shortcuts[i].path.value = it },
label = { Text(stringResource(id = R.string.lovelace_view_dashboard)) },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done, autoCorrect = false, keyboardType = KeyboardType.Uri),
modifier = Modifier.fillMaxWidth().padding(bottom = 16.dp)
)
} else {

View file

@ -10,7 +10,7 @@ interface WebView {
TIMEOUT
}
fun loadUrl(url: String, keepHistory: Boolean)
fun loadUrl(url: String, keepHistory: Boolean, openInApp: Boolean)
fun setStatusBarAndNavigationBarColor(statusBarColor: Int, navigationBarColor: Int)

View file

@ -1113,11 +1113,20 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
finish()
}
override fun loadUrl(url: String, keepHistory: Boolean) {
loadedUrl = url
clearHistory = !keepHistory
webView.loadUrl(url)
waitForConnection()
override fun loadUrl(url: String, keepHistory: Boolean, openInApp: Boolean) {
if (openInApp) {
loadedUrl = url
clearHistory = !keepHistory
webView.loadUrl(url)
waitForConnection()
} else {
try {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(browserIntent)
} catch (e: Exception) {
Log.e(TAG, "Unable to view url", e)
}
}
}
override fun setStatusBarAndNavigationBarColor(statusBarColor: Int, navigationBarColor: Int) {

View file

@ -16,6 +16,7 @@ import io.homeassistant.companion.android.matter.MatterFrontendCommissioningStat
import io.homeassistant.companion.android.matter.MatterManager
import io.homeassistant.companion.android.thread.ThreadManager
import io.homeassistant.companion.android.util.UrlUtil
import io.homeassistant.companion.android.util.UrlUtil.baseIsEqual
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -88,6 +89,7 @@ class WebViewPresenterImpl @Inject constructor(
serverConnectionInfo.isInternal() || (serverConnectionInfo.prioritizeInternal && !DisabledLocationHandler.isLocationEnabled(view as Context))
)
urlForServer = server?.id
val baseUrl = url
if (path != null && !path.startsWith("entityId:")) {
url = UrlUtil.handle(url, path)
@ -101,12 +103,13 @@ class WebViewPresenterImpl @Inject constructor(
*/
if (oldUrlForServer != urlForServer || oldUrl?.host != url?.host) {
view.loadUrl(
Uri.parse(url.toString())
url = Uri.parse(url.toString())
.buildUpon()
.appendQueryParameter("external_auth", "1")
.build()
.toString(),
oldUrlForServer == urlForServer
keepHistory = oldUrlForServer == urlForServer,
openInApp = url?.baseIsEqual(baseUrl) ?: false
)
}
}

View file

@ -1,11 +1,13 @@
package io.homeassistant.companion.android.util
import android.net.Uri
import android.util.Log
import io.homeassistant.companion.android.common.data.MalformedHttpUrlException
import io.homeassistant.companion.android.common.data.authentication.impl.AuthenticationService
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import java.net.URI
import java.net.URL
object UrlUtil {
@ -39,15 +41,26 @@ object UrlUtil {
}
fun handle(base: URL?, input: String): URL? {
val asURI = try {
URI(input.removePrefix("homeassistant://navigate/"))
} catch (e: Exception) {
Log.w("UrlUtil", "Invalid input, returning base only")
null
}
return when {
asURI == null -> {
base
}
isAbsoluteUrl(input) -> {
URL(input)
asURI.toURL()
}
input.startsWith("homeassistant://navigate/") -> {
(base.toString() + input.removePrefix("homeassistant://navigate/")).toHttpUrlOrNull()?.toUrl()
}
else -> {
(base.toString() + input.removePrefix("/")).toHttpUrlOrNull()?.toUrl()
else -> { // Input is relative to base URL
val builder = base
?.toHttpUrlOrNull()
?.newBuilder()
if (!asURI.path.isNullOrBlank()) builder?.addPathSegments(asURI.path.trim().removePrefix("/"))
if (!asURI.query.isNullOrBlank()) builder?.query(asURI.query.trim())
builder?.build()?.toUrl()
}
}
}
@ -56,6 +69,17 @@ object UrlUtil {
return Regex("^https?://").containsMatchIn(it.toString())
}
/** @return `true` if both URLs have the same 'base': an equal protocol, host, port and userinfo */
fun URL.baseIsEqual(other: URL?): Boolean =
if (other == null) {
false
} else {
host?.lowercase() == other.host?.lowercase() &&
port.let { if (it == -1) defaultPort else it } == other.port.let { if (it == -1) defaultPort else it } &&
protocol?.lowercase() == other.protocol?.lowercase() &&
userInfo == other.userInfo
}
fun splitNfcTagId(it: Uri?): String? {
val matches =
Regex("^https?://www\\.home-assistant\\.io/tag/(.*)").find(