From 1ee77d8d057c8d868591d6d22a032cdeb3c97514 Mon Sep 17 00:00:00 2001 From: mueller-ma Date: Sun, 26 Nov 2023 14:25:56 +0100 Subject: [PATCH] Custom sitemaps for device control We already have links to Sitemap subpages (NFC tags), so re-use them for the device control. Closes #3140 Signed-off-by: mueller-ma --- .../background/ItemsControlsProviderService.kt | 6 ++++++ .../main/java/org/openhab/habdroid/model/Item.kt | 15 +++++++++++++-- .../java/org/openhab/habdroid/model/LinkedPage.kt | 15 +++++++++++++++ .../org/openhab/habdroid/ui/WidgetListFragment.kt | 14 +++++++++++++- .../org/openhab/habdroid/ui/WriteTagActivity.kt | 15 ++------------- mobile/src/main/res/values/strings.xml | 1 + 6 files changed, 50 insertions(+), 16 deletions(-) diff --git a/mobile/src/main/java/org/openhab/habdroid/background/ItemsControlsProviderService.kt b/mobile/src/main/java/org/openhab/habdroid/background/ItemsControlsProviderService.kt index e0d55112da..1527647734 100644 --- a/mobile/src/main/java/org/openhab/habdroid/background/ItemsControlsProviderService.kt +++ b/mobile/src/main/java/org/openhab/habdroid/background/ItemsControlsProviderService.kt @@ -30,6 +30,7 @@ import android.service.controls.templates.ToggleRangeTemplate import android.service.controls.templates.ToggleTemplate import android.util.Log import androidx.annotation.RequiresApi +import androidx.core.net.toUri import java.util.concurrent.Flow import java.util.function.Consumer import kotlin.math.max @@ -59,6 +60,7 @@ import org.openhab.habdroid.util.getDeviceControlSubtitle import org.openhab.habdroid.util.getPrefs import org.openhab.habdroid.util.getPrimaryServerId import org.openhab.habdroid.util.getSecretPrefs +import org.openhab.habdroid.util.openInBrowser import org.openhab.habdroid.util.orDefaultIfEmpty @RequiresApi(Build.VERSION_CODES.R) @@ -281,6 +283,10 @@ class ItemsControlsProviderService : ControlsProviderService() { } Pair(intent, item.hashCode()) } + item.linkToMore != null -> { + val intent = Intent(Intent.ACTION_VIEW, item.linkToMore) + Pair(intent, item.hashCode()) + } else -> { val intent = Intent(context, MainActivity::class.java).apply { putExtra(MainActivity.EXTRA_SERVER_ID, primaryServerId) diff --git a/mobile/src/main/java/org/openhab/habdroid/model/Item.kt b/mobile/src/main/java/org/openhab/habdroid/model/Item.kt index 869078a9cf..b4dd486bd5 100644 --- a/mobile/src/main/java/org/openhab/habdroid/model/Item.kt +++ b/mobile/src/main/java/org/openhab/habdroid/model/Item.kt @@ -13,7 +13,9 @@ package org.openhab.habdroid.model +import android.net.Uri import android.os.Parcelable +import androidx.core.net.toUri import java.util.Locale import kotlinx.parcelize.Parcelize import org.json.JSONException @@ -43,6 +45,7 @@ data class Item internal constructor( val minimum: Float?, val maximum: Float?, val step: Float?, + val linkToMore: Uri? ) : Parcelable { val label get() = rawLabel?.split("[", "]")?.getOrNull(0)?.trim() @@ -280,7 +283,8 @@ fun Node.toItem(): Item? { groupNames = emptyList(), minimum = null, maximum = null, - step = null + step = null, + linkToMore = null ) } @@ -338,6 +342,12 @@ fun JSONObject.toItem(): Item { emptyList() } + val linkToMore = try { + optJSONObject("metadata")?.optJSONObject("link_to_more")?.optStringOrNull("value")?.toUri() + } catch (e: Exception) { // TODO: Lower exception + null + } + return Item( name = name, rawLabel = optStringOrNull("label"), @@ -353,7 +363,8 @@ fun JSONObject.toItem(): Item { groupNames = groupNames, minimum = stateDescription?.optFloatOrNull("minimum"), maximum = stateDescription?.optFloatOrNull("maximum"), - step = stateDescription?.optFloatOrNull("step") + step = stateDescription?.optFloatOrNull("step"), + linkToMore = linkToMore ) } diff --git a/mobile/src/main/java/org/openhab/habdroid/model/LinkedPage.kt b/mobile/src/main/java/org/openhab/habdroid/model/LinkedPage.kt index 1ec74cbc98..c0fc89b6af 100644 --- a/mobile/src/main/java/org/openhab/habdroid/model/LinkedPage.kt +++ b/mobile/src/main/java/org/openhab/habdroid/model/LinkedPage.kt @@ -13,7 +13,9 @@ package org.openhab.habdroid.model +import android.net.Uri import android.os.Parcelable +import androidx.core.net.toUri import kotlinx.parcelize.Parcelize import org.json.JSONObject @@ -32,6 +34,19 @@ data class LinkedPage( val icon: IconResource?, val link: String ) : Parcelable { + fun createLink(): Uri { + val sitemapUri = link.toUri() + val path = sitemapUri.path.orEmpty() + if (!path.startsWith("/rest/sitemaps")) { + throw IllegalArgumentException("Expected a sitemap URL") + } + return Uri.Builder() + .scheme(NfcTag.SCHEME) + .authority("") + .appendEncodedPath(path.substring(15)) + .build() + } + companion object { internal fun build( id: String, diff --git a/mobile/src/main/java/org/openhab/habdroid/ui/WidgetListFragment.kt b/mobile/src/main/java/org/openhab/habdroid/ui/WidgetListFragment.kt index 4d3ccf39be..2b2388797a 100644 --- a/mobile/src/main/java/org/openhab/habdroid/ui/WidgetListFragment.kt +++ b/mobile/src/main/java/org/openhab/habdroid/ui/WidgetListFragment.kt @@ -250,7 +250,7 @@ class WidgetListFragment : if (widget != null && context != null) { when (item.itemId) { CONTEXT_MENU_ID_WRITE_SITEMAP_TAG -> { - widget.linkedPage?.link?.let { + widget.linkedPage?.createLink()?.let { startActivity(WriteTagActivity.createSitemapNavigationIntent(context, it)) } return true @@ -259,6 +259,14 @@ class WidgetListFragment : widget.item?.state?.asLocation?.toMapsUrl()?.toUri().openInBrowser(context) return true } + CONTEXT_MENU_ID_COPY_SITEMAP_LINK -> { + Log.d(TAG, "Copy sitemap link for ${widget.linkedPage}") + val link = widget.linkedPage?.createLink()?.toString() ?: return true + val clipboardManager = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager + val clipData = ClipData.newPlainText(context.getString(R.string.app_name), link) + clipboardManager.setPrimaryClip(clipData) + return true + } } } return super.onContextItemSelected(item) @@ -358,6 +366,9 @@ class WidgetListFragment : if (widget.linkedPage != null && nfcSupported) { menu.add(Menu.NONE, CONTEXT_MENU_ID_WRITE_SITEMAP_TAG, Menu.NONE, R.string.nfc_action_to_sitemap_page) } + if (widget.linkedPage != null) { + menu.add(Menu.NONE, CONTEXT_MENU_ID_COPY_SITEMAP_LINK, Menu.NONE, R.string.copy_sitemap_link) + } widget.item?.let { menu.add(Menu.NONE, CONTEXT_MENU_ID_COPY_ITEM_NAME, Menu.NONE, R.string.show_and_copy_item_name) @@ -648,6 +659,7 @@ class WidgetListFragment : private const val CONTEXT_MENU_ID_PIN_HOME_BLACK = 1005 private const val CONTEXT_MENU_ID_OPEN_IN_MAPS = 1006 private const val CONTEXT_MENU_ID_COPY_ITEM_NAME = 1007 + private const val CONTEXT_MENU_ID_COPY_SITEMAP_LINK = 1008 private const val CONTEXT_MENU_ID_WRITE_CUSTOM_TAG = 10000 private const val CONTEXT_MENU_ID_WRITE_DEVICE_ID = 10001 diff --git a/mobile/src/main/java/org/openhab/habdroid/ui/WriteTagActivity.kt b/mobile/src/main/java/org/openhab/habdroid/ui/WriteTagActivity.kt index 8da8b2422f..ad267b3d91 100644 --- a/mobile/src/main/java/org/openhab/habdroid/ui/WriteTagActivity.kt +++ b/mobile/src/main/java/org/openhab/habdroid/ui/WriteTagActivity.kt @@ -38,7 +38,6 @@ import android.view.ViewGroup import android.widget.Button import android.widget.TextView import androidx.annotation.DrawableRes -import androidx.core.net.toUri import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.commit @@ -312,19 +311,9 @@ class WriteTagActivity : AbstractBaseActivity(), CoroutineScope { } } - fun createSitemapNavigationIntent(context: Context, sitemapUrl: String): Intent { - val sitemapUri = sitemapUrl.toUri() - val path = sitemapUri.path.orEmpty() - if (!path.startsWith("/rest/sitemaps")) { - throw IllegalArgumentException("Expected a sitemap URL") - } - val longUri = Uri.Builder() - .scheme(NfcTag.SCHEME) - .authority("") - .appendEncodedPath(path.substring(15)) - .build() + fun createSitemapNavigationIntent(context: Context, sitemapLink: Uri): Intent { return Intent(context, WriteTagActivity::class.java) - .putExtra(EXTRA_LONG_URI, longUri) + .putExtra(EXTRA_LONG_URI, sitemapLink) } } diff --git a/mobile/src/main/res/values/strings.xml b/mobile/src/main/res/values/strings.xml index fe38c3d6e5..b985ed8d01 100644 --- a/mobile/src/main/res/values/strings.xml +++ b/mobile/src/main/res/values/strings.xml @@ -169,6 +169,7 @@ Show and copy Item name Copied \"%s\" + Copy link to this subpage openHAB returned empty Sitemap list