diff --git a/.gitignore b/.gitignore
index 85c770f4..18ac284a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,4 +60,5 @@ Jenkinsfile
/encrypt.txt
-google-play-api.json
\ No newline at end of file
+google-play-api.json
+/api-*.json
\ No newline at end of file
diff --git a/app/src/main/java/de/psdev/devdrawer/analytics/AnalyticsOptInCard.kt b/app/src/main/java/de/psdev/devdrawer/analytics/AnalyticsOptInCard.kt
index 8c766c7b..b1bae0b9 100644
--- a/app/src/main/java/de/psdev/devdrawer/analytics/AnalyticsOptInCard.kt
+++ b/app/src/main/java/de/psdev/devdrawer/analytics/AnalyticsOptInCard.kt
@@ -36,7 +36,7 @@ fun AnalyticsOptInCard(
modifier = modifier
.fillMaxWidth()
.padding(8.dp),
- colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.secondaryContainer)
+ colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainerHighest)
) {
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
Text(text = stringResource(R.string.analytics_opt_in_title), style = MaterialTheme.typography.titleMedium)
diff --git a/app/src/main/java/de/psdev/devdrawer/appwidget/glance/DevDrawerWidgetContent.kt b/app/src/main/java/de/psdev/devdrawer/appwidget/glance/DevDrawerWidgetContent.kt
index 378d8f56..18dd98e6 100644
--- a/app/src/main/java/de/psdev/devdrawer/appwidget/glance/DevDrawerWidgetContent.kt
+++ b/app/src/main/java/de/psdev/devdrawer/appwidget/glance/DevDrawerWidgetContent.kt
@@ -56,7 +56,8 @@ fun DevDrawerWidgetContent(state: WidgetUiState) {
val background = GlanceModifier
.fillMaxSize()
.appWidgetBackground()
- .background(GlanceTheme.colors.widgetBackground)
+ // Glance's widgetBackground derives from secondaryContainer, which is deep orange in DevDrawer's scheme.
+ .background(GlanceTheme.colors.background)
val rounded = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
background.cornerRadius(android.R.dimen.system_app_widget_background_radius)
} else {
@@ -76,7 +77,7 @@ fun DevDrawerWidgetContent(state: WidgetUiState) {
}
Header(state, showDetails = true)
if (state.apps.isEmpty()) {
- EmptyState(context, state.appWidgetId)
+ EmptyState(context, state.appWidgetId, compact = size.height < ROOMY_EMPTY_HEIGHT)
} else {
val compact = size.width < NARROW_WIDTH
LazyColumn(modifier = GlanceModifier.fillMaxSize()) {
@@ -100,6 +101,9 @@ fun DevDrawerWidgetContent(state: WidgetUiState) {
/** Below this the widget shows its apps as a strip of icons. */
private val SHORT_HEIGHT = 130.dp
+/** Below this the empty state leaves out its explanation so the button still fits. */
+private val ROOMY_EMPTY_HEIGHT = 240.dp
+
/** Below this rows drop the package name and the actions. */
private val NARROW_WIDTH = 250.dp
@@ -170,9 +174,9 @@ private fun Header(state: WidgetUiState, showDetails: Boolean) {
}
@Composable
-private fun EmptyState(context: Context, appWidgetId: Int) {
+private fun EmptyState(context: Context, appWidgetId: Int, compact: Boolean) {
Column(
- modifier = GlanceModifier.fillMaxSize().padding(24.dp),
+ modifier = GlanceModifier.fillMaxSize().padding(if (compact) 12.dp else 24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalAlignment = Alignment.CenterVertically
) {
@@ -180,12 +184,14 @@ private fun EmptyState(context: Context, appWidgetId: Int) {
text = context.getString(R.string.widget_empty_title),
style = TextStyle(color = GlanceTheme.colors.onSurface, fontSize = 16.sp, fontWeight = FontWeight.Medium)
)
- Spacer(GlanceModifier.height(4.dp))
- Text(
- text = context.getString(R.string.widget_empty_text),
- style = TextStyle(color = GlanceTheme.colors.onSurfaceVariant, fontSize = 14.sp)
- )
- Spacer(GlanceModifier.height(12.dp))
+ if (!compact) {
+ Spacer(GlanceModifier.height(4.dp))
+ Text(
+ text = context.getString(R.string.widget_empty_text),
+ style = TextStyle(color = GlanceTheme.colors.onSurfaceVariant, fontSize = 14.sp)
+ )
+ }
+ Spacer(GlanceModifier.height(if (compact) 8.dp else 12.dp))
ChooseAppsButton(context, appWidgetId)
}
}
diff --git a/app/src/main/java/de/psdev/devdrawer/profiles/ui/editor/PackagePatternSheet.kt b/app/src/main/java/de/psdev/devdrawer/profiles/ui/editor/PackagePatternSheet.kt
index 1d1bd396..cdb54989 100644
--- a/app/src/main/java/de/psdev/devdrawer/profiles/ui/editor/PackagePatternSheet.kt
+++ b/app/src/main/java/de/psdev/devdrawer/profiles/ui/editor/PackagePatternSheet.kt
@@ -13,6 +13,10 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.pluralStringResource
@@ -51,11 +55,18 @@ fun PackagePatternSheet(
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
- val invalid = preview.pattern.isNotBlank() && !preview.isValid
+ // The field keeps its own text: the preview is computed asynchronously, and feeding it back into the
+ // field would drop or reorder characters typed quickly. It only describes the text once it caught up.
+ var text by rememberSaveable { mutableStateOf(preview.pattern) }
+ val upToDate = preview.pattern == text
+ val invalid = upToDate && text.isNotBlank() && !preview.isValid
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
- value = preview.pattern,
- onValueChange = onPatternChange,
+ value = text,
+ onValueChange = {
+ text = it
+ onPatternChange(it)
+ },
singleLine = true,
isError = invalid,
label = { Text(stringResource(R.string.packagefilter)) },
@@ -64,7 +75,7 @@ fun PackagePatternSheet(
invalid -> {
{ Text(stringResource(R.string.pattern_invalid)) }
}
- preview.pattern.isNotBlank() -> {
+ upToDate && text.isNotBlank() -> {
{ Text(pluralStringResource(R.plurals.pattern_match_count, preview.matchCount, preview.matchCount)) }
}
else -> null
@@ -82,8 +93,8 @@ fun PackagePatternSheet(
}
Button(
modifier = Modifier.align(Alignment.End),
- enabled = preview.isValid,
- onClick = { onAdd(preview.pattern.trim()) }
+ enabled = upToDate && preview.isValid,
+ onClick = { onAdd(text.trim()) }
) {
Text(stringResource(R.string.add))
}
diff --git a/app/src/main/java/de/psdev/devdrawer/profiles/ui/editor/WidgetProfileEditor.kt b/app/src/main/java/de/psdev/devdrawer/profiles/ui/editor/WidgetProfileEditor.kt
index 9e6fa1c7..d3c114fc 100644
--- a/app/src/main/java/de/psdev/devdrawer/profiles/ui/editor/WidgetProfileEditor.kt
+++ b/app/src/main/java/de/psdev/devdrawer/profiles/ui/editor/WidgetProfileEditor.kt
@@ -194,11 +194,17 @@ internal fun WidgetProfileEditor(
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
+ // The field keeps its own text: the view state echoes the name back asynchronously, and feeding that into
+ // the field would drop or reorder characters typed quickly.
+ var name by rememberSaveable(widgetProfile.id) { mutableStateOf(viewState.widgetName ?: widgetProfile.name) }
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
singleLine = true,
- value = viewState.widgetName ?: widgetProfile.name,
- onValueChange = onNameChange,
+ value = name,
+ onValueChange = {
+ name = it
+ onNameChange(it)
+ },
label = { Text(text = stringResource(id = R.string.name)) },
// Every edit here changes these widgets, so say which they are.
supportingText = {
diff --git a/app/src/main/java/de/psdev/devdrawer/ui/theme/Shape.kt b/app/src/main/java/de/psdev/devdrawer/ui/theme/Shape.kt
deleted file mode 100644
index 8d22d415..00000000
--- a/app/src/main/java/de/psdev/devdrawer/ui/theme/Shape.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package de.psdev.devdrawer.ui.theme
-
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material3.Shapes
-import androidx.compose.ui.unit.dp
-
-val Shapes = Shapes(
- small = RoundedCornerShape(4.dp),
- medium = RoundedCornerShape(4.dp),
- large = RoundedCornerShape(0.dp)
-)
\ No newline at end of file
diff --git a/app/src/main/java/de/psdev/devdrawer/ui/theme/Theme.kt b/app/src/main/java/de/psdev/devdrawer/ui/theme/Theme.kt
index c8ab5046..0ff6f4d2 100644
--- a/app/src/main/java/de/psdev/devdrawer/ui/theme/Theme.kt
+++ b/app/src/main/java/de/psdev/devdrawer/ui/theme/Theme.kt
@@ -77,7 +77,6 @@ fun DevDrawerTheme(
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
- shapes = Shapes,
content = content
)
}
diff --git a/app/src/main/play/contact-email.txt b/app/src/main/play/contact-email.txt
new file mode 100644
index 00000000..f3c18fe7
--- /dev/null
+++ b/app/src/main/play/contact-email.txt
@@ -0,0 +1 @@
+admin@psdev.de
diff --git a/app/src/main/play/contact-website.txt b/app/src/main/play/contact-website.txt
new file mode 100644
index 00000000..69f769bc
--- /dev/null
+++ b/app/src/main/play/contact-website.txt
@@ -0,0 +1 @@
+https://psdev.de
diff --git a/app/src/main/play/default-language.txt b/app/src/main/play/default-language.txt
new file mode 100644
index 00000000..beb9970b
--- /dev/null
+++ b/app/src/main/play/default-language.txt
@@ -0,0 +1 @@
+en-US
diff --git a/app/src/main/play/listings/de-DE/full-description.txt b/app/src/main/play/listings/de-DE/full-description.txt
new file mode 100644
index 00000000..6048ea17
--- /dev/null
+++ b/app/src/main/play/listings/de-DE/full-description.txt
@@ -0,0 +1,27 @@
+DevDrawer2 bringt die Apps, die du entwickelst, auf deinen Startbildschirm. Ein Widget listet jeden installierten Build, damit du ihn mit einem Tipp starten, seine App-Info öffnen oder ihn deinstallieren kannst.
+
+SO FUNKTIONIERT ES
+• Füge das Widget hinzu und wähle eine deiner Apps. Jede App, die mit demselben Schlüssel signiert ist, erscheint, auch solche, die du später installierst.
+• Oder filtere Paketnamen mit einem Muster wie com.mycompany.*
+• Fasse Filter in Profilen zusammen und nutze sie in mehreren Widgets.
+
+GEMACHT FÜR DEN ENTWICKLERALLTAG
+• Debug-, Beta- und Release-Builds nebeneinander
+• Deinstallieren und App-Info direkt im Widget
+• Sortierung nach zuletzt aktualisiert, zuerst installiert, Name oder Paketname
+• Auf Wunsch wählen, welcher Bildschirm einer App geöffnet wird
+
+DEIN WIDGET, WIE DU ES WILLST
+• Neun Kopfzeilenfarben, auch die Farben deines Hintergrundbilds
+• Heller und dunkler Modus
+• Passt sich seiner Größe an: eine Symbolleiste, wenn es klein ist, ganze Zeilen, wenn es groß ist
+• Beliebig viele Widgets, jedes mit eigenen Apps
+
+PRIVAT UND OPEN SOURCE
+• Keine Werbung, kein Konto
+• Nutzungsanalyse nur, wenn du sie erlaubst (Firebase Analytics, keine personenbezogenen Daten). Absturzberichte werden über Firebase Crashlytics gesendet.
+• Quellcode: https://github.com/PSDev/DevDrawer
+
+Verfügbar auf Deutsch und Englisch.
+
+Basiert auf dem ursprünglichen DevDrawer von Tony Owen, neu geschrieben in Kotlin.
diff --git a/app/src/main/play/listings/de-DE/graphics/feature-graphic/1.png b/app/src/main/play/listings/de-DE/graphics/feature-graphic/1.png
new file mode 100644
index 00000000..1ed21d41
Binary files /dev/null and b/app/src/main/play/listings/de-DE/graphics/feature-graphic/1.png differ
diff --git a/app/src/main/play/listings/de-DE/graphics/phone-screenshots/1.png b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/1.png
new file mode 100644
index 00000000..fba45865
Binary files /dev/null and b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/1.png differ
diff --git a/app/src/main/play/listings/de-DE/graphics/phone-screenshots/2.png b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/2.png
new file mode 100644
index 00000000..24031df7
Binary files /dev/null and b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/2.png differ
diff --git a/app/src/main/play/listings/de-DE/graphics/phone-screenshots/3.png b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/3.png
new file mode 100644
index 00000000..0f019f96
Binary files /dev/null and b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/3.png differ
diff --git a/app/src/main/play/listings/de-DE/graphics/phone-screenshots/4.png b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/4.png
new file mode 100644
index 00000000..3b0652f5
Binary files /dev/null and b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/4.png differ
diff --git a/app/src/main/play/listings/de-DE/graphics/phone-screenshots/5.png b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/5.png
new file mode 100644
index 00000000..ee0d8f1f
Binary files /dev/null and b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/5.png differ
diff --git a/app/src/main/play/listings/de-DE/graphics/phone-screenshots/6.png b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/6.png
new file mode 100644
index 00000000..89d73b71
Binary files /dev/null and b/app/src/main/play/listings/de-DE/graphics/phone-screenshots/6.png differ
diff --git a/app/src/main/play/listings/de-DE/short-description.txt b/app/src/main/play/listings/de-DE/short-description.txt
new file mode 100644
index 00000000..95cbe549
--- /dev/null
+++ b/app/src/main/play/listings/de-DE/short-description.txt
@@ -0,0 +1 @@
+Ein Widget für deine eigenen Apps: mit einem Tipp starten oder deinstallieren.
\ No newline at end of file
diff --git a/app/src/main/play/listings/de-DE/title.txt b/app/src/main/play/listings/de-DE/title.txt
new file mode 100644
index 00000000..82ff4e93
--- /dev/null
+++ b/app/src/main/play/listings/de-DE/title.txt
@@ -0,0 +1 @@
+DevDrawer2
\ No newline at end of file
diff --git a/app/src/main/play/listings/en-US/full-description.txt b/app/src/main/play/listings/en-US/full-description.txt
new file mode 100644
index 00000000..1141246d
--- /dev/null
+++ b/app/src/main/play/listings/en-US/full-description.txt
@@ -0,0 +1,27 @@
+DevDrawer2 puts the apps you are developing on your home screen. One widget lists every build you have installed, so you can launch it, open its app info or uninstall it with a single tap.
+
+HOW IT WORKS
+• Add the widget and pick one of your apps. Every app signed with the same key appears, including ones you install later.
+• Or match package names with a pattern like com.mycompany.*
+• Combine filters in profiles and reuse them across widgets.
+
+MADE FOR EVERYDAY DEVELOPMENT
+• Debug, beta and release builds side by side
+• Uninstall and app info right in the widget
+• Sort by last updated, first installed, name or package name
+• Optionally choose which screen of an app to open
+
+YOUR WIDGET, YOUR WAY
+• Nine header colours, including your wallpaper colours
+• Light and dark mode
+• Adapts to its size: a strip of icons when small, full rows when large
+• As many widgets as you like, each with its own apps
+
+PRIVATE AND OPEN SOURCE
+• No ads, no account
+• Usage analytics only if you allow them (Firebase Analytics, no personal data). Crash reports are sent via Firebase Crashlytics.
+• Source code: https://github.com/PSDev/DevDrawer
+
+Available in English and German.
+
+Based on the original DevDrawer by Tony Owen, rewritten in Kotlin.
diff --git a/app/src/main/play/listings/en-US/graphics/feature-graphic/1.png b/app/src/main/play/listings/en-US/graphics/feature-graphic/1.png
new file mode 100644
index 00000000..3b2159a1
Binary files /dev/null and b/app/src/main/play/listings/en-US/graphics/feature-graphic/1.png differ
diff --git a/app/src/main/play/listings/en-US/graphics/phone-screenshots/1.png b/app/src/main/play/listings/en-US/graphics/phone-screenshots/1.png
new file mode 100644
index 00000000..ac211b6c
Binary files /dev/null and b/app/src/main/play/listings/en-US/graphics/phone-screenshots/1.png differ
diff --git a/app/src/main/play/listings/en-US/graphics/phone-screenshots/2.png b/app/src/main/play/listings/en-US/graphics/phone-screenshots/2.png
new file mode 100644
index 00000000..c751c27d
Binary files /dev/null and b/app/src/main/play/listings/en-US/graphics/phone-screenshots/2.png differ
diff --git a/app/src/main/play/listings/en-US/graphics/phone-screenshots/3.png b/app/src/main/play/listings/en-US/graphics/phone-screenshots/3.png
new file mode 100644
index 00000000..f921b3dd
Binary files /dev/null and b/app/src/main/play/listings/en-US/graphics/phone-screenshots/3.png differ
diff --git a/app/src/main/play/listings/en-US/graphics/phone-screenshots/4.png b/app/src/main/play/listings/en-US/graphics/phone-screenshots/4.png
new file mode 100644
index 00000000..c9cc26ec
Binary files /dev/null and b/app/src/main/play/listings/en-US/graphics/phone-screenshots/4.png differ
diff --git a/app/src/main/play/listings/en-US/graphics/phone-screenshots/5.png b/app/src/main/play/listings/en-US/graphics/phone-screenshots/5.png
new file mode 100644
index 00000000..c65ebd68
Binary files /dev/null and b/app/src/main/play/listings/en-US/graphics/phone-screenshots/5.png differ
diff --git a/app/src/main/play/listings/en-US/graphics/phone-screenshots/6.png b/app/src/main/play/listings/en-US/graphics/phone-screenshots/6.png
new file mode 100644
index 00000000..1091d21f
Binary files /dev/null and b/app/src/main/play/listings/en-US/graphics/phone-screenshots/6.png differ
diff --git a/app/src/main/play/listings/en-US/short-description.txt b/app/src/main/play/listings/en-US/short-description.txt
new file mode 100644
index 00000000..4be5add9
--- /dev/null
+++ b/app/src/main/play/listings/en-US/short-description.txt
@@ -0,0 +1 @@
+A home-screen widget for your own apps: launch, inspect or uninstall in one tap.
\ No newline at end of file
diff --git a/app/src/main/play/listings/en-US/title.txt b/app/src/main/play/listings/en-US/title.txt
new file mode 100644
index 00000000..82ff4e93
--- /dev/null
+++ b/app/src/main/play/listings/en-US/title.txt
@@ -0,0 +1 @@
+DevDrawer2
\ No newline at end of file
diff --git a/app/src/main/play/release-notes/de-DE/default.txt b/app/src/main/play/release-notes/de-DE/default.txt
new file mode 100644
index 00000000..e70f0222
--- /dev/null
+++ b/app/src/main/play/release-notes/de-DE/default.txt
@@ -0,0 +1,7 @@
+Komplett neu gestaltet:
+• Ein neues Widget, das sich seiner Größe anpasst, mit neun Kopfzeilenfarben und dunklem Modus
+• Geführte Einrichtung beim Hinzufügen eines Widgets
+• Filter in verständlicher Sprache, mit Live-Vorschau der passenden Apps
+• Änderungen werden automatisch gespeichert, gelöschte Profile lassen sich wiederherstellen
+• Übersichtliche Auswahl, welcher Bildschirm einer App geöffnet wird
+• Deutsche Übersetzung
diff --git a/app/src/main/play/release-notes/en-US/default.txt b/app/src/main/play/release-notes/en-US/default.txt
new file mode 100644
index 00000000..f8cd70d8
--- /dev/null
+++ b/app/src/main/play/release-notes/en-US/default.txt
@@ -0,0 +1,7 @@
+A complete redesign:
+• A new widget that adapts to its size, with nine header colours and dark mode
+• Guided setup when you add a widget
+• Filters in plain language, with a live preview of the apps they match
+• Edits save automatically, and deleted profiles can be restored
+• Pick which screen of an app to open from a clear list
+• German translation
diff --git a/app/src/main/res/drawable-de-night-nodpi/devdrawer_widget_preview.png b/app/src/main/res/drawable-de-night-nodpi/devdrawer_widget_preview.png
new file mode 100644
index 00000000..721e37bc
Binary files /dev/null and b/app/src/main/res/drawable-de-night-nodpi/devdrawer_widget_preview.png differ
diff --git a/app/src/main/res/drawable-de-nodpi/devdrawer_widget_preview.png b/app/src/main/res/drawable-de-nodpi/devdrawer_widget_preview.png
new file mode 100644
index 00000000..1c91c3da
Binary files /dev/null and b/app/src/main/res/drawable-de-nodpi/devdrawer_widget_preview.png differ
diff --git a/app/src/main/res/drawable-night-nodpi/devdrawer_widget_preview.png b/app/src/main/res/drawable-night-nodpi/devdrawer_widget_preview.png
index 08859544..3f9efe53 100644
Binary files a/app/src/main/res/drawable-night-nodpi/devdrawer_widget_preview.png and b/app/src/main/res/drawable-night-nodpi/devdrawer_widget_preview.png differ
diff --git a/app/src/main/res/drawable-nodpi/devdrawer_widget_preview.png b/app/src/main/res/drawable-nodpi/devdrawer_widget_preview.png
index 94de0d5f..12b7ce3b 100644
Binary files a/app/src/main/res/drawable-nodpi/devdrawer_widget_preview.png and b/app/src/main/res/drawable-nodpi/devdrawer_widget_preview.png differ
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 227bf33c..20642c94 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -44,7 +44,7 @@
Material-You-Farben
Farben aus deinem Hintergrundbild verwenden
Nutzungsanalyse teilen
- Welche Bildschirme du öffnest und Absturzberichte, über Firebase. Keine personenbezogenen Daten.
+ Welche Bildschirme du öffnest, über Firebase Analytics. Keine personenbezogenen Daten. Absturzberichte werden immer gesendet.
Keine Apps verfügbar oder alle bereits als Filter hinzugefügt
Mehr
System-Apps einbeziehen
@@ -63,7 +63,7 @@
Option auswählen
Nutzungsanalyse
- Hilf, DevDrawer zu verbessern, indem du teilst, welche Bildschirme du öffnest, und Absturzberichte sendest (über Firebase). Keine personenbezogenen Daten. Du kannst das jederzeit in den Einstellungen ändern.
+ Hilf, DevDrawer zu verbessern, indem du teilst, welche Bildschirme du öffnest (über Firebase Analytics). Keine personenbezogenen Daten. Du kannst das jederzeit in den Einstellungen ändern.
Erlauben
Nein danke
Danke! Du kannst deine Entscheidung jederzeit im Einstellungen-Tab ändern.
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 82b68974..9428c5cc 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -93,7 +93,7 @@
Material You colors
Use colors generated from your wallpaper
Share usage analytics
- Which screens you open and crash reports, via Firebase. No personal data.
+ Which screens you open, via Firebase Analytics. No personal data. Crash reports are sent either way.
No apps available or all already added as filter
More
@@ -103,7 +103,7 @@
Select option
Usage analytics
- Help improve DevDrawer by sharing which screens you open and crash reports, via Firebase. No personal data. You can change this anytime in Settings.
+ Help improve DevDrawer by sharing which screens you open, via Firebase Analytics. No personal data. You can change this anytime in Settings.
Allow
No thanks
Thank you! You can change your decision anytime on the settings tab.
diff --git a/app/src/test/java/de/psdev/devdrawer/analytics/AnalyticsOptInCardTest.kt b/app/src/test/java/de/psdev/devdrawer/analytics/AnalyticsOptInCardTest.kt
index 5e5b296e..b8543580 100644
--- a/app/src/test/java/de/psdev/devdrawer/analytics/AnalyticsOptInCardTest.kt
+++ b/app/src/test/java/de/psdev/devdrawer/analytics/AnalyticsOptInCardTest.kt
@@ -54,6 +54,8 @@ class AnalyticsOptInCardTest {
// When
composeTestRule.onNodeWithText("Usage analytics").assertExists()
composeTestRule.onNodeWithText("No personal data", substring = true).assertExists()
+ // Crash reports are sent regardless of this choice, so the card must not offer them.
+ composeTestRule.onNodeWithText("crash", substring = true, ignoreCase = true).assertDoesNotExist()
composeTestRule.onNodeWithText("No thanks").assertIsEnabled().performClick()
composeTestRule.onNodeWithText("Allow").assertIsEnabled().performClick()
diff --git a/app/src/test/java/de/psdev/devdrawer/appwidget/glance/DevDrawerWidgetContentTest.kt b/app/src/test/java/de/psdev/devdrawer/appwidget/glance/DevDrawerWidgetContentTest.kt
index 0a1cdd9d..8401fcae 100644
--- a/app/src/test/java/de/psdev/devdrawer/appwidget/glance/DevDrawerWidgetContentTest.kt
+++ b/app/src/test/java/de/psdev/devdrawer/appwidget/glance/DevDrawerWidgetContentTest.kt
@@ -149,4 +149,20 @@ class DevDrawerWidgetContentTest {
// Then
onNode(hasText("Choose apps")).assertExists()
}
+
+ @Test
+ fun `given a two-row widget without apps, when rendered, then the empty state drops its explanation so the button fits`() =
+ runGlanceAppWidgetUnitTest {
+ // Given
+ setContext(ApplicationProvider.getApplicationContext())
+ setAppWidgetSize(DpSize(300.dp, 180.dp))
+
+ // When
+ provideComposable { DevDrawerWidgetContent(state(emptyList())) }
+
+ // Then
+ onNode(hasText("No apps match this widget")).assertExists()
+ onNode(hasText("Choose apps")).assertExists()
+ onNode(hasText("Choose which of your apps it should list.")).assertDoesNotExist()
+ }
}
diff --git a/app/src/test/java/de/psdev/devdrawer/profiles/ui/editor/PackagePatternSheetTest.kt b/app/src/test/java/de/psdev/devdrawer/profiles/ui/editor/PackagePatternSheetTest.kt
index 629e6fc0..52ea5ec9 100644
--- a/app/src/test/java/de/psdev/devdrawer/profiles/ui/editor/PackagePatternSheetTest.kt
+++ b/app/src/test/java/de/psdev/devdrawer/profiles/ui/editor/PackagePatternSheetTest.kt
@@ -85,4 +85,30 @@ class PackagePatternSheetTest {
// Then
assertEquals("com.", typed.last())
}
+
+ @Test
+ fun `given a preview that lags behind, when typing, then the field still shows exactly what was typed`() {
+ // Given: the preview never catches up, like a slow recomputation
+ show(PatternPreview())
+
+ // When
+ composeTestRule.onNodeWithText("Package filter").performTextInput("com.example.*")
+
+ // Then
+ composeTestRule.onNodeWithText("com.example.*").assertExists()
+ }
+
+ @Test
+ fun `given a valid pattern that matches no app yet, when shown, then it can still be added`() {
+ // Given: e.g. a company prefix before any of its apps is installed
+ var added: String? = null
+ show(PatternPreview(pattern = "com.mycompany.*", isValid = true, matchCount = 0, apps = emptyList()), onAdd = { added = it })
+
+ // When
+ composeTestRule.onNodeWithText("0 apps match").assertExists()
+ composeTestRule.onNodeWithText("Add").assertIsEnabled().performClick()
+
+ // Then
+ assertEquals("com.mycompany.*", added)
+ }
}
diff --git a/app/src/test/java/de/psdev/devdrawer/profiles/ui/editor/WidgetProfileEditorScreenTest.kt b/app/src/test/java/de/psdev/devdrawer/profiles/ui/editor/WidgetProfileEditorScreenTest.kt
index 9cff2808..bae51506 100644
--- a/app/src/test/java/de/psdev/devdrawer/profiles/ui/editor/WidgetProfileEditorScreenTest.kt
+++ b/app/src/test/java/de/psdev/devdrawer/profiles/ui/editor/WidgetProfileEditorScreenTest.kt
@@ -2,6 +2,7 @@ package de.psdev.devdrawer.profiles.ui.editor
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.performTextReplacement
import de.psdev.devdrawer.database.WidgetProfile
import de.psdev.devdrawer.ui.theme.DevDrawerTheme
import org.junit.Rule
@@ -43,4 +44,16 @@ class WidgetProfileEditorScreenTest {
composeTestRule.onNodeWithText("Not used by any widget").assertExists()
}
+
+ @Test
+ fun `given a name update that lags behind, when typing, then the field still shows exactly what was typed`() {
+ // Given: the view state never reflects the typed name, like a slow combined flow
+ show(emptyList())
+
+ // When
+ composeTestRule.onNodeWithText("Signed like DevDrawer2").performTextReplacement("Work apps")
+
+ // Then
+ composeTestRule.onNodeWithText("Work apps").assertExists()
+ }
}
diff --git a/app/src/test/java/de/psdev/devdrawer/settings/SettingsScreenTest.kt b/app/src/test/java/de/psdev/devdrawer/settings/SettingsScreenTest.kt
index 294cea5e..c86b143a 100644
--- a/app/src/test/java/de/psdev/devdrawer/settings/SettingsScreenTest.kt
+++ b/app/src/test/java/de/psdev/devdrawer/settings/SettingsScreenTest.kt
@@ -68,6 +68,6 @@ class SettingsScreenTest {
// Then
composeTestRule.onNodeWithText("Share usage analytics").assertExists()
- composeTestRule.onNodeWithText("Which screens you open and crash reports, via Firebase. No personal data.").assertExists()
+ composeTestRule.onNodeWithText("Which screens you open, via Firebase Analytics. No personal data. Crash reports are sent either way.").assertExists()
}
}
diff --git a/app/src/test/java/de/psdev/devdrawer/ui/theme/ShapeTest.kt b/app/src/test/java/de/psdev/devdrawer/ui/theme/ShapeTest.kt
new file mode 100644
index 00000000..126689a7
--- /dev/null
+++ b/app/src/test/java/de/psdev/devdrawer/ui/theme/ShapeTest.kt
@@ -0,0 +1,34 @@
+package de.psdev.devdrawer.ui.theme
+
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Shapes
+import androidx.compose.ui.test.junit4.createComposeRule
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.annotation.Config
+
+@RunWith(RobolectricTestRunner::class)
+// SDK 36 requires Java 21; use SDK 33 which is compatible with the project's Java 17 toolchain.
+@Config(sdk = [33])
+class ShapeTest {
+
+ @get:Rule
+ val composeTestRule = createComposeRule()
+
+ @Test
+ fun `given the app theme, when reading its shapes, then they are the Material 3 corner scale`() {
+ // Given
+ var shapes: Shapes? = null
+
+ // When
+ composeTestRule.setContent {
+ DevDrawerTheme { shapes = MaterialTheme.shapes }
+ }
+
+ // Then: FAB 16dp, cards 12dp, small surfaces 8dp instead of the old 0/4/4dp
+ assertEquals(Shapes(), shapes)
+ }
+}