From 24c3cdbb9435609da900daebf8f6cd88a65081ea Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Thu, 18 Sep 2025 14:09:30 +0200 Subject: [PATCH] reactivate widgets --- app/android/app/build.gradle | 7 +- app/android/app/src/main/AndroidManifest.xml | 29 ++--- .../weblibre/gecko/CompactWidgetProvider.kt | 59 ---------- .../eu/weblibre/gecko/FullWidgetProvider.kt | 59 ---------- .../weblibre/gecko/SearchBarWidgetProvider.kt | 110 +++++++++++------- .../src/main/res/layout/compact_widget.xml | 45 ------- .../app/src/main/res/layout/full_widget.xml | 55 --------- .../src/main/res/layout/search_bar_widget.xml | 13 --- .../src/main/res/xml/compact_widget_info.xml | 8 -- .../app/src/main/res/xml/full_widget_info.xml | 8 -- .../main/res/xml/search_bar_widget_info.xml | 5 +- .../browser/domain/providers/intent.dart | 3 + 12 files changed, 89 insertions(+), 312 deletions(-) delete mode 100644 app/android/app/src/main/kotlin/eu/weblibre/gecko/CompactWidgetProvider.kt delete mode 100644 app/android/app/src/main/kotlin/eu/weblibre/gecko/FullWidgetProvider.kt delete mode 100644 app/android/app/src/main/res/layout/compact_widget.xml delete mode 100644 app/android/app/src/main/res/layout/full_widget.xml delete mode 100644 app/android/app/src/main/res/layout/search_bar_widget.xml delete mode 100644 app/android/app/src/main/res/xml/compact_widget_info.xml delete mode 100644 app/android/app/src/main/res/xml/full_widget_info.xml diff --git a/app/android/app/build.gradle b/app/android/app/build.gradle index 68f0bffa..13c9f317 100644 --- a/app/android/app/build.gradle +++ b/app/android/app/build.gradle @@ -1,6 +1,7 @@ plugins { id "com.android.application" id "kotlin-android" + id "org.jetbrains.kotlin.plugin.compose" version "2.1.20" // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. id "dev.flutter.flutter-gradle-plugin" } @@ -49,10 +50,14 @@ android { dependencies { // implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - // implementation 'androidx.glance:glance-appwidget:1.0.0' + implementation 'androidx.glance:glance-appwidget:1.1.1' implementation 'com.google.android.material:material:1.12.0' } + buildFeatures { + compose true + } + signingConfigs { release { keyAlias System.getenv("KEY_ALIAS") diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml index e51e2308..a3e6341c 100644 --- a/app/android/app/src/main/AndroidManifest.xml +++ b/app/android/app/src/main/AndroidManifest.xml @@ -88,7 +88,7 @@ - + @@ -176,32 +176,17 @@ android:label="@string/mozac_feature_addons_addons" android:theme="@style/Theme.AppCompat.Light"/> - + - - + - - - - - - - - - - - - - - - . - */ -package eu.weblibre.gecko - -import android.appwidget.AppWidgetManager -import android.content.Context -import android.content.SharedPreferences -import android.graphics.BitmapFactory -import android.net.Uri -import android.view.View -import android.widget.RemoteViews -import es.antonborri.home_widget.HomeWidgetBackgroundIntent -import es.antonborri.home_widget.HomeWidgetLaunchIntent -import es.antonborri.home_widget.HomeWidgetProvider - -class CompactWidgetProvider : HomeWidgetProvider() { - override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray, widgetData: SharedPreferences) { - appWidgetIds.forEach { widgetId -> - val views = RemoteViews(context.packageName, R.layout.compact_widget).apply { - val searchIntent = HomeWidgetLaunchIntent.getActivity( - context, - MainActivity::class.java, - Uri.parse("widget://search")) - setOnClickPendingIntent(R.id.search_button, searchIntent) - - val assistantIntent = HomeWidgetLaunchIntent.getActivity( - context, - MainActivity::class.java, - Uri.parse("widget://assistant")) - setOnClickPendingIntent(R.id.assistant_button, assistantIntent) - - val summarizerIntent = HomeWidgetLaunchIntent.getActivity( - context, - MainActivity::class.java, - Uri.parse("widget://summarizer")) - setOnClickPendingIntent(R.id.summarizer_button, summarizerIntent) - } - - appWidgetManager.updateAppWidget(widgetId, views) - } - } -} \ No newline at end of file diff --git a/app/android/app/src/main/kotlin/eu/weblibre/gecko/FullWidgetProvider.kt b/app/android/app/src/main/kotlin/eu/weblibre/gecko/FullWidgetProvider.kt deleted file mode 100644 index afde5820..00000000 --- a/app/android/app/src/main/kotlin/eu/weblibre/gecko/FullWidgetProvider.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2024-2025 Fabian Freund. - * - * This file is part of WebLibre - * (see https://weblibre.eu). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package eu.weblibre.gecko - -import android.appwidget.AppWidgetManager -import android.content.Context -import android.content.SharedPreferences -import android.graphics.BitmapFactory -import android.net.Uri -import android.view.View -import android.widget.RemoteViews -import es.antonborri.home_widget.HomeWidgetBackgroundIntent -import es.antonborri.home_widget.HomeWidgetLaunchIntent -import es.antonborri.home_widget.HomeWidgetProvider - -class FullWidgetProvider : HomeWidgetProvider() { - override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray, widgetData: SharedPreferences) { - appWidgetIds.forEach { widgetId -> - val views = RemoteViews(context.packageName, R.layout.full_widget).apply { - val searchIntent = HomeWidgetLaunchIntent.getActivity( - context, - MainActivity::class.java, - Uri.parse("widget://search")) - setOnClickPendingIntent(R.id.search_button, searchIntent) - - val assistantIntent = HomeWidgetLaunchIntent.getActivity( - context, - MainActivity::class.java, - Uri.parse("widget://assistant")) - setOnClickPendingIntent(R.id.assistant_button, assistantIntent) - - val summarizerIntent = HomeWidgetLaunchIntent.getActivity( - context, - MainActivity::class.java, - Uri.parse("widget://summarizer")) - setOnClickPendingIntent(R.id.summarizer_button, summarizerIntent) - } - - appWidgetManager.updateAppWidget(widgetId, views) - } - } -} \ No newline at end of file diff --git a/app/android/app/src/main/kotlin/eu/weblibre/gecko/SearchBarWidgetProvider.kt b/app/android/app/src/main/kotlin/eu/weblibre/gecko/SearchBarWidgetProvider.kt index 9bdd308e..d40f2720 100644 --- a/app/android/app/src/main/kotlin/eu/weblibre/gecko/SearchBarWidgetProvider.kt +++ b/app/android/app/src/main/kotlin/eu/weblibre/gecko/SearchBarWidgetProvider.kt @@ -1,47 +1,79 @@ -/* - * Copyright (c) 2024-2025 Fabian Freund. - * - * This file is part of WebLibre - * (see https://weblibre.eu). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ package eu.weblibre.gecko -import android.appwidget.AppWidgetManager import android.content.Context -import android.content.SharedPreferences -import android.graphics.BitmapFactory -import android.net.Uri -import android.view.View -import android.widget.RemoteViews -import es.antonborri.home_widget.HomeWidgetBackgroundIntent +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.glance.GlanceId +import androidx.glance.GlanceModifier +import androidx.glance.Image +import androidx.glance.ImageProvider +import androidx.glance.action.clickable +import androidx.glance.appwidget.GlanceAppWidget +import androidx.glance.appwidget.GlanceAppWidgetReceiver +import androidx.glance.appwidget.provideContent +import androidx.glance.background +import androidx.glance.layout.Alignment +import androidx.glance.layout.Row +import androidx.glance.layout.fillMaxWidth +import androidx.glance.layout.padding +import androidx.glance.layout.wrapContentHeight +import androidx.glance.text.Text +import androidx.glance.text.TextStyle +import androidx.glance.unit.ColorProvider import es.antonborri.home_widget.HomeWidgetLaunchIntent -import es.antonborri.home_widget.HomeWidgetProvider +import android.net.Uri +import es.antonborri.home_widget.actionStartActivity +import androidx.core.net.toUri -class SearchBarWidgetProvider : HomeWidgetProvider() { - override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray, widgetData: SharedPreferences) { - appWidgetIds.forEach { widgetId -> - val views = RemoteViews(context.packageName, R.layout.search_bar_widget).apply { - val searchIntent = HomeWidgetLaunchIntent.getActivity( - context, - MainActivity::class.java, - Uri.parse("widget://search")) - setOnClickPendingIntent(R.id.search_button, searchIntent) - } +class SearchBarGlanceWidget : GlanceAppWidget() { - appWidgetManager.updateAppWidget(widgetId, views) + override suspend fun provideGlance(context: Context, id: GlanceId) { + provideContent { + SearchBarContent(context) } } -} \ No newline at end of file +} + +@Composable +private fun SearchBarContent(context: Context) { + Row( + modifier = GlanceModifier + .fillMaxWidth() + .wrapContentHeight() + .background(ImageProvider(R.drawable.search_text_field)) + .padding(12.dp) + .clickable(onClick = actionStartActivity(context, + "widget://search".toUri())), + verticalAlignment = Alignment.CenterVertically + ) { + // Start icon + Image( + provider = ImageProvider(R.drawable.icon_with_size), + contentDescription = "Search icon", + modifier = GlanceModifier.padding(end = 8.dp) + ) + + // Search text + Text( + text = "Search with WebLibre...", + style = TextStyle( + color = ColorProvider(Color(0xFF848388)), + fontSize = 16.sp + ), + modifier = GlanceModifier.defaultWeight() + ) + + // End icon (microphone) + Image( + provider = ImageProvider(R.drawable.mdi_icon_microphone_tint), + contentDescription = "Microphone icon", + modifier = GlanceModifier.padding(start = 8.dp) + ) + } +} + +class SearchBarWidgetReceiver : GlanceAppWidgetReceiver() { + override val glanceAppWidget: GlanceAppWidget = SearchBarGlanceWidget() +} diff --git a/app/android/app/src/main/res/layout/compact_widget.xml b/app/android/app/src/main/res/layout/compact_widget.xml deleted file mode 100644 index 0cceeca4..00000000 --- a/app/android/app/src/main/res/layout/compact_widget.xml +++ /dev/null @@ -1,45 +0,0 @@ - - -