Skip to content

Feat: Add voice support check for UI elements#112

Merged
mshdabiola merged 4 commits into
developfrom
102-bug-app-crashes-when-adding-voice-recording-due-to-missing-speech-recognition-activity
Jun 10, 2025
Merged

Feat: Add voice support check for UI elements#112
mshdabiola merged 4 commits into
developfrom
102-bug-app-crashes-when-adding-voice-recording-due-to-missing-speech-recognition-activity

Conversation

@mshdabiola
Copy link
Copy Markdown
Owner

@mshdabiola mshdabiola commented Jun 10, 2025

PR Type

Enhancement


Description

  • Added voice support check.

  • Updated UI for voice input.

  • Improved UI consistency.

  • Enhanced user experience.


Changes walkthrough 📝

Relevant files
Enhancement
NoteApp.kt
UI Enhancement: Conditional Voice Input Rendering               

app/src/main/java/com/mshdabiola/playnotepad/ui/NoteApp.kt

  • Added isVoiceSupport parameter to NoteBottomBar.
  • Conditionally renders voice input option based on isVoiceSupport.
  • Updated NoteApp composable to pass isVoiceSupport to NoteBottomBar.
  • Improved UI consistency and user experience.
  • +14/-8   
    AddDetailBottomSheet2.kt
    UI Enhancement: Conditional Voice Recording Option             

    feature/detail/src/main/kotlin/com/mshdabiola/detail/AddDetailBottomSheet2.kt

  • Added isVoiceSupport parameter to AddBottomSheet2.
  • Conditionally renders voice recording option.
  • Improved UI consistency and user experience.
  • Updated composable to handle voice support check.
  • +37/-34 
    DetailScreen.kt
    UI Enhancement: Pass Voice Support to DetailScreen             

    feature/detail/src/main/kotlin/com/mshdabiola/detail/DetailScreen.kt

  • Added isVoiceSupport parameter to DetailRoute.
  • Updated composable to handle voice support check.
  • Improved UI consistency and user experience.
  • No functional changes.
  • +2/-0     
    MainActions.kt
    Added Voice Support Check Function                                             

    modules/ui/src/main/kotlin/com/mshdabiola/ui/MainActions.kt

  • Added supportVoice() function to check for voice recognition support.
  • Improved code clarity and readability.
  • Added necessary imports.
  • No functional changes.
  • +11/-0   

    Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • This commit introduces a check for voice recognition support and updates the UI accordingly.
    
    - Added a new composable function `supportVoice()` in `MainActions.kt` to determine if the device supports speech recognition.
    - In `DetailScreen.kt` and `NoteApp.kt`, the `AddDetailBottomSheet2` and `MainBottomBar` composables now conditionally display voice input options based on the result of `supportVoice()`.
    - The `AddDetailBottomSheet2.kt` composable now accepts an `isVoiceSupport` parameter to control the visibility of the recording option.
    @github-actions
    Copy link
    Copy Markdown
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    UI Consistency

    The addition of voice support check in NoteBottomBar might affect the UI consistency across different screen sizes or orientations. Ensure the new voice button integrates seamlessly and doesn't cause layout issues.

        isVoiceSupport: Boolean = false,
    ) {
        BottomAppBar(
            modifier = modifier,
            actions = {
                IconButton(
                    modifier = Modifier.testTag("main:check"),
                    onClick = onAddCheckNote,
                ) {
                    Icon(
                        imageVector = NoteIcon.CheckBox,
                        contentDescription = "add note check",
                    )
                }
    
                IconButton(
                    modifier = Modifier.testTag("main:draw"),
                    onClick = onAddDrawNote,
                ) {
                    Icon(
                        imageVector = NoteIcon.Brush,
                        contentDescription = "add note drawing",
                    )
                }
    
                if (isVoiceSupport) {
                    IconButton(
                        modifier = Modifier.testTag("main:voice"),
                        onClick = onAddVoiceNote,
                    ) {
                        Icon(
                            imageVector = NoteIcon.KeyboardVoice,
                            contentDescription = "add note voice",
                        )
                    }
                }
    Permission Handling

    The voice recording functionality requests permission within the onClick handler. Consider moving the permission check to a higher level to avoid redundant checks and improve user experience.

    if (context.checkSelfPermission(Manifest.permission.RECORD_AUDIO) ==
        PackageManager.PERMISSION_GRANTED
    ) {
        voiceLauncher.launch(
            Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
                putExtra(
                    RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                    RecognizerIntent.LANGUAGE_MODEL_FREE_FORM,
                )
                putExtra(RecognizerIntent.EXTRA_PROMPT, "Speck Now Now")
                putExtra(
                    "android.speech.extra.GET_AUDIO_FORMAT",
                    "audio/AMR",
                )
                putExtra("android.speech.extra.GET_AUDIO", true)
            },
        )
    } else {
        audioPermission.launch(Manifest.permission.RECORD_AUDIO)
    }

    @github-actions
    Copy link
    Copy Markdown
    Contributor

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    General
    Cache voice support check result

    The supportVoice function uses queryIntentActivities which can be slow and
    inefficient. Consider caching the result to avoid redundant checks. This will
    improve the app's performance, especially on devices with slower processors. The
    cache should be invalidated only when there's a system change that might affect
    voice recognition availability.

    modules/ui/src/main/kotlin/com/mshdabiola/ui/MainActions.kt [107-113]

     @SuppressLint("QueryPermissionsNeeded")
     @Composable
     fun supportVoice(): Boolean {
    -    val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
         val context = LocalContext.current
    -    val pm = context.packageManager
    -    val activities = pm.queryIntentActivities(intent, 0)
    -    return activities.isNotEmpty()
    +    val key = "voice_support_available"
    +    val cachedValue = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE).getBoolean(key, false)
    +    return if (cachedValue) {
    +        true
    +    } else {
    +        val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
    +        val pm = context.packageManager
    +        val activities = pm.queryIntentActivities(intent, 0)
    +        val isSupported = activities.isNotEmpty()
    +        context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE).edit().putBoolean(key, isSupported).apply()
    +        isSupported
    +    }
     }
    Suggestion importance[1-10]: 7

    __

    Why: Caching the result of the voice support check improves performance by avoiding redundant checks. The suggested implementation using SharedPreferences is a reasonable approach, although more sophisticated caching mechanisms might be considered for larger-scale applications.

    Medium
    Improve voice button feedback

    The conditional rendering of the voice button based on isVoiceSupport is good for
    handling cases where voice input isn't available. However, consider adding a visual
    cue (e.g., a disabled state or a tooltip) to inform the user why the button is
    missing, rather than just silently omitting it. This improves user experience and
    understanding.

    app/src/main/java/com/mshdabiola/playnotepad/ui/NoteApp.kt [276-286]

    -if (isVoiceSupport) {
    +val voiceButtonEnabled = isVoiceSupport
    +        if (voiceButtonEnabled) {
                 IconButton(
                     modifier = Modifier.testTag("main:voice"),
                     onClick = onAddVoiceNote,
                 ) {
                     Icon(
                         imageVector = NoteIcon.KeyboardVoice,
                         contentDescription = "add note voice",
                     )
                 }
    +        } else {
    +            IconButton(
    +                modifier = Modifier.testTag("main:voice").indication(indication = null),
    +                onClick = {},
    +                enabled = false
    +            ) {
    +                Icon(
    +                    imageVector = NoteIcon.KeyboardVoice,
    +                    contentDescription = "add note voice",
    +                    tint = Color.Gray
    +                )
    +            }
             }
    Suggestion importance[1-10]: 5

    __

    Why: The suggestion to add visual feedback when the voice button is disabled improves the user experience. However, the provided improved_code is not a direct replacement for the existing_code and requires additional imports and context. A simpler solution might be to just gray out the button when it's disabled.

    Low

    @mshdabiola
    Copy link
    Copy Markdown
    Owner Author

    /improve --pr_code_suggestions.commitable_code_suggestions=true

    Comment thread modules/ui/src/main/kotlin/com/mshdabiola/ui/MainActions.kt
    Comment thread app/src/main/java/com/mshdabiola/playnotepad/ui/NoteApp.kt
    mshdabiola and others added 3 commits June 10, 2025 20:05
    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    This commit introduces an optimization in the `supportVoice` composable function and applies code formatting changes.
    
    - In `MainActions.kt`, the `LocalContext.current` is now fetched outside the `remember` block within `supportVoice()`. This prevents redundant lookups of the context on recomposition.
    - In `NoteApp.kt`, the code for navigating to the drawing screen after inserting a new drawing and the code for the voice note IconButton has been reformatted for better readability. No functional changes were made in `NoteApp.kt`.
    @mshdabiola mshdabiola linked an issue Jun 10, 2025 that may be closed by this pull request
    @github-actions
    Copy link
    Copy Markdown
    Contributor

    Test results

    27 tests   - 1   27 ✅  - 1   18s ⏱️ -1s
    18 suites  - 1    0 💤 ±0 
    18 files    - 1    0 ❌ ±0 

    Results for commit 9ed9cb1. ± Comparison against base commit 06dd48e.

    This pull request removes 1 test.
    com.mshdabiola.datastore.IntToStringIdsMigrationTest ‑ IntToStringIdsMigration_should_migrate_topic_ids
    

    @codecov-commenter
    Copy link
    Copy Markdown

    codecov-commenter commented Jun 10, 2025

    Codecov Report

    ❌ Patch coverage is 0% with 52 lines in your changes missing coverage. Please review.
    ✅ Project coverage is 0.88%. Comparing base (06dd48e) to head (9ed9cb1).
    ⚠️ Report is 799 commits behind head on develop.

    Files with missing lines Patch % Lines
    ...lin/com/mshdabiola/detail/AddDetailBottomSheet2.kt 0.00% 26 Missing ⚠️
    ...main/java/com/mshdabiola/playnotepad/ui/NoteApp.kt 0.00% 19 Missing ⚠️
    ...i/src/main/kotlin/com/mshdabiola/ui/MainActions.kt 0.00% 6 Missing ⚠️
    .../main/kotlin/com/mshdabiola/detail/DetailScreen.kt 0.00% 1 Missing ⚠️
    Additional details and impacted files
    @@            Coverage Diff             @@
    ##           develop    #112      +/-   ##
    ==========================================
    + Coverage     0.86%   0.88%   +0.02%     
    ==========================================
      Files          158     156       -2     
      Lines         6840    6868      +28     
      Branches       537     540       +3     
    ==========================================
    + Hits            59      61       +2     
    - Misses        6772    6794      +22     
    - Partials         9      13       +4     

    ☔ View full report in Codecov by Sentry.
    📢 Have feedback on the report? Share it here.

    🚀 New features to boost your workflow:
    • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

    @mshdabiola mshdabiola merged commit 9db04f8 into develop Jun 10, 2025
    7 checks passed
    @mshdabiola mshdabiola deleted the 102-bug-app-crashes-when-adding-voice-recording-due-to-missing-speech-recognition-activity branch June 10, 2025 20:11
    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.

    [Bug]: App crashes when adding voice recording due to missing speech recognition activity app crash on voice note startup

    2 participants