Skip to content

feat(shortcuts): add app shortcuts and pin-to-home-screen#79

Merged
pawcoding merged 5 commits intostagingfrom
feat/app-shortcuts
Feb 22, 2026
Merged

feat(shortcuts): add app shortcuts and pin-to-home-screen#79
pawcoding merged 5 commits intostagingfrom
feat/app-shortcuts

Conversation

@pawcoding
Copy link
Owner

Summary

  • Add CardOverlayActivity — a transparent bottom-sheet overlay that opens a specific card directly from a launcher shortcut, with biometric auth support
  • Wire dynamic shortcuts (top-3 cards by score) to app startup and card usage events via ShortcutUpdater
  • Add "Add to home screen" option to the card long-press menu that pins a launcher shortcut for that card using ShortcutManagerCompat.requestPinShortcut

Key implementation details

  • Shortcut intent uses a dedicated ACTION_VIEW_CARD action and card_id extra; CardOverlayActivity handles both onCreate and onNewIntent (for singleTask re-launch)
  • Shortcut icon reuses createShortcutIcon (adaptive bitmap with card color + first letter); text contrast determined by isLightColor utility
  • Shared cardShortcutId(cardId) helper ensures dynamic and pinned shortcuts for the same card share an ID

Changes

  • CardOverlayActivity.kt — new transparent Activity with bottom-sheet UI and biometric guard
  • ShortcutUpdater.kt — utility to push/remove dynamic shortcuts and create adaptive bitmap icons
  • CardViewModel.ktpinShortcut(card) method; addUsage now triggers shortcut refresh
  • CardListScreen.kt — "Add to home screen" option in card long-press menu
  • strings.xml / strings-de/strings.xml — new shortcut and overlay string resources
  • AndroidManifest.xml / themes — overlay Activity registration and transparent theme

Test plan

  • Launch app — dynamic shortcuts for top cards appear in launcher long-press
  • Use a card — shortcut list updates to reflect new usage ranking
  • Long-press a card → "Add to home screen" → shortcut pinned to launcher
  • Tap pinned shortcut — CardOverlayActivity opens correct card as bottom sheet
  • Tap pinned shortcut while app already open — onNewIntent loads correct card
  • Enable biometric lock — overlay prompts for biometric before showing card
  • Tap outside bottom sheet — overlay dismisses

Copilot AI review requested due to automatic review settings February 22, 2026 07:52
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.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@pawcoding pawcoding merged commit 85bdccd into staging Feb 22, 2026
1 check passed
@pawcoding pawcoding deleted the feat/app-shortcuts branch February 22, 2026 08:14
@pawcoding pawcoding mentioned this pull request Feb 22, 2026
@pawcode-development-releaser
Copy link

🎉 This PR is included in version 1.5.0-staging.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

@pawcode-development-releaser
Copy link

🎉 This PR is included in version 1.5.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants