From 721c8cc3d4fb27accbd8f08e513257406ecbf7e7 Mon Sep 17 00:00:00 2001 From: mueller-ma Date: Thu, 18 Jul 2024 23:01:43 +0200 Subject: [PATCH] Screensaver: Ensure text is always full visible Signed-off-by: mueller-ma --- mobile/src/main/AndroidManifest.xml | 1 + .../java/org/openhab/habdroid/ui/DayDream.kt | 42 ++++++++++++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml index 99e8e836ee..ce433aacb6 100644 --- a/mobile/src/main/AndroidManifest.xml +++ b/mobile/src/main/AndroidManifest.xml @@ -334,6 +334,7 @@ android:exported="true" android:label="@string/app_name" android:icon="@drawable/ic_openhab_appicon_24dp" + android:configChanges="orientation|screenSize" android:permission="android.permission.BIND_DREAM_SERVICE"> diff --git a/mobile/src/main/java/org/openhab/habdroid/ui/DayDream.kt b/mobile/src/main/java/org/openhab/habdroid/ui/DayDream.kt index 86ff3e7c3a..58d23e1670 100644 --- a/mobile/src/main/java/org/openhab/habdroid/ui/DayDream.kt +++ b/mobile/src/main/java/org/openhab/habdroid/ui/DayDream.kt @@ -14,6 +14,10 @@ package org.openhab.habdroid.ui import android.animation.ObjectAnimator +import android.content.res.Configuration +import android.graphics.Rect +import android.os.Handler +import android.os.Looper import android.service.dreams.DreamService import android.util.Log import android.view.View @@ -41,6 +45,7 @@ import org.openhab.habdroid.util.getStringOrNull class DayDream : DreamService(), CoroutineScope { private val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job + private var moveTextJob: Job? = null private lateinit var textView: TextView private lateinit var wrapper: LinearLayout private lateinit var container: FrameLayout @@ -64,34 +69,50 @@ class DayDream : DreamService(), CoroutineScope { launch { item?.let { listenForTextItem(it) } } - launch { - moveText() - } + } + + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + moveTextIfRequired() } private suspend fun listenForTextItem(item: String) { ConnectionFactory.waitForInitialization() val connection = ConnectionFactory.primaryUsableConnection?.connection ?: return + moveText() textView.text = try { ItemClient.loadItem(connection, item)?.state?.asString.orEmpty() } catch (e: HttpClient.HttpException) { getString(R.string.screensaver_error_loading_item, item) } + moveTextIfRequired() ItemClient.listenForItemChange(this, connection, item) { _, payload -> val state = payload.getString("value") Log.d(TAG, "Got state by event: $state") textView.text = state + moveTextIfRequired() } } - private suspend fun moveText() { + private fun moveText() { + moveTextJob?.cancel() wrapper.fadeOut() wrapper.moveViewToRandomPosition(container) wrapper.fadeIn() - delay(if (BuildConfig.DEBUG) 10.seconds else 1.minutes) - moveText() + moveTextJob = launch { + delay(if (BuildConfig.DEBUG) 10.seconds else 1.minutes) + moveText() + } + } + + private fun moveTextIfRequired() { + Handler(Looper.getMainLooper()).post { + if (!textView.isFullyVisible()) { + moveText() + } + } } private fun View.moveViewToRandomPosition(container: FrameLayout) { @@ -122,6 +143,15 @@ class DayDream : DreamService(), CoroutineScope { animator.start() } + private fun View.isFullyVisible(): Boolean { + val rect = Rect() + val isVisible = this.getGlobalVisibleRect(rect) + val viewHeight = this.height + val viewWidth = this.width + + return isVisible && rect.height() == viewHeight && rect.width() == viewWidth + } + override fun onDetachedFromWindow() { super.onDetachedFromWindow() job.cancel()