feat(shortcuts): add app shortcuts and pin-to-home-screen#79
feat(shortcuts): add app shortcuts and pin-to-home-screen#79
Conversation
Long-pressing on the app icon now shows your 3 most important cards as shortcuts. These can be placed on your homescreen. When opening a shortcut an overlay shows your card without the whole app being started.
There was a problem hiding this comment.
Pull request overview
This PR adds comprehensive app shortcuts functionality to CardStore, enabling users to quickly access their most-used loyalty cards directly from the launcher. The implementation includes dynamic shortcuts (top-3 cards based on user sort preference), a transparent overlay activity for viewing cards from shortcuts, pin-to-home-screen functionality, and biometric authentication support.
Changes:
- Added dynamic app shortcuts that display the top 3 cards in the launcher long-press menu, updated automatically based on usage and sort preferences
- Created CardOverlayActivity as a transparent bottom-sheet overlay for viewing cards from shortcuts with optional biometric authentication
- Added "Add to home screen" option to card long-press menu for pinning individual cards as launcher shortcuts
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| app/src/main/java/de/pawcode/cardstore/CardOverlayActivity.kt | New transparent overlay activity with bottom-sheet UI, biometric guard, and onNewIntent support for singleTask relaunch |
| app/src/main/java/de/pawcode/cardstore/data/utils/ShortcutUpdater.kt | Utility for managing dynamic shortcuts with adaptive bitmap icons and sort-based card ranking |
| app/src/main/java/de/pawcode/cardstore/ui/viewmodels/CardViewModel.kt | Added pinShortcut method and integrated shortcut updates into addUsage |
| app/src/main/java/de/pawcode/cardstore/ui/screens/CardListScreen.kt | Added "Add to home screen" option to card long-press menu |
| app/src/main/java/de/pawcode/cardstore/MainActivity.kt | Added shortcut updates on app startup |
| app/src/main/java/de/pawcode/cardstore/data/services/BiometricAuthService.kt | Fixed authentication flow by removing error callback from onAuthenticationFailed |
| app/src/main/AndroidManifest.xml | Registered CardOverlayActivity with transparent overlay theme |
| app/src/main/res/values/themes.xml | Added transparent overlay theme for CardOverlayActivity |
| app/src/main/res/values/strings.xml | Added shortcut-related string resources (EN) |
| app/src/main/res/values-de/strings.xml | Added shortcut-related string resources (DE) |
| app/src/main/res/drawable/keep_solid.xml | Added pin icon for "Add to home screen" option |
| docs/plans/*.md | Implementation and design documentation |
Comments suppressed due to low confidence (3)
app/src/main/AndroidManifest.xml:52
- The launchMode should be "singleInstance" instead of "singleTask" according to the design documents. "singleInstance" ensures the activity runs in its own isolated task and doesn't pollute the main app's back stack, which is the intended behavior for this overlay activity. "singleTask" would allow other activities to be added to the same task, which could cause unexpected navigation behavior.
android:launchMode="singleTask"
app/src/main/java/de/pawcode/cardstore/ui/viewmodels/CardViewModel.kt:85
- The pinShortcut method is not wrapped in a coroutine scope but calls createShortcutIcon which may perform bitmap operations. While ShortcutManagerCompat.requestPinShortcut is typically fast, the bitmap creation in createShortcutIcon could block the main thread. Consider wrapping the entire method body in viewModelScope.launch to ensure UI responsiveness, similar to other methods in this ViewModel.
fun pinShortcut(card: CardEntity) {
val context = getApplication<Application>()
if (!ShortcutManagerCompat.isRequestPinShortcutSupported(context)) return
val shortcutId = cardShortcutId(card.cardId)
val icon = createShortcutIcon(card)
val intent =
Intent(context, CardOverlayActivity::class.java).apply {
action = SHORTCUT_ACTION
putExtra(CardOverlayActivity.EXTRA_CARD_ID, card.cardId)
}
val shortcut =
ShortcutInfoCompat.Builder(context, shortcutId)
.setShortLabel(card.storeName.take(25))
.setLongLabel(card.storeName)
.setIcon(icon)
.setIntent(intent)
.build()
ShortcutManagerCompat.requestPinShortcut(context, shortcut, null)
}
app/src/main/java/de/pawcode/cardstore/ui/viewmodels/CardViewModel.kt:62
- Calling updateShortcuts on every card usage may impact performance, as it reads all cards from the database, sorts them, and updates shortcuts even when the top-3 cards haven't changed. Consider optimizing by only updating shortcuts when the usage actually affects the top-3 ranking, or debouncing updates to avoid excessive database queries and shortcut API calls during rapid card usage.
fun addUsage(card: CardEntity) =
viewModelScope.launch {
val updatedCard =
card.copy(useCount = card.useCount + 1, lastUsed = System.currentTimeMillis())
cardRepository.updateCard(updatedCard)
updateShortcuts(getApplication())
}
This adds the option to add a shortcut for any card to your homescreen. Then behavior using this shortcut is the same as for dynamic shortcuts. But instead of only being available for your most used cards, you can now add shortcuts for any card.
cf2d48d to
fe75a7c
Compare
|
🎉 This PR is included in version 1.5.0-staging.2 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 1.5.0 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
Summary
CardOverlayActivity— a transparent bottom-sheet overlay that opens a specific card directly from a launcher shortcut, with biometric auth supportShortcutUpdaterShortcutManagerCompat.requestPinShortcutKey implementation details
ACTION_VIEW_CARDaction andcard_idextra;CardOverlayActivityhandles bothonCreateandonNewIntent(forsingleTaskre-launch)createShortcutIcon(adaptive bitmap with card color + first letter); text contrast determined byisLightColorutilitycardShortcutId(cardId)helper ensures dynamic and pinned shortcuts for the same card share an IDChanges
CardOverlayActivity.kt— new transparent Activity with bottom-sheet UI and biometric guardShortcutUpdater.kt— utility to push/remove dynamic shortcuts and create adaptive bitmap iconsCardViewModel.kt—pinShortcut(card)method;addUsagenow triggers shortcut refreshCardListScreen.kt— "Add to home screen" option in card long-press menustrings.xml/strings-de/strings.xml— new shortcut and overlay string resourcesAndroidManifest.xml/ themes — overlay Activity registration and transparent themeTest plan
CardOverlayActivityopens correct card as bottom sheetonNewIntentloads correct card