Skip to content

Add keyboard color settings option#63

Merged
ricky9667 merged 6 commits intomasterfrom
copilot/add-settings-option
Feb 25, 2026
Merged

Add keyboard color settings option#63
ricky9667 merged 6 commits intomasterfrom
copilot/add-settings-option

Conversation

Copy link
Contributor

Copilot AI commented Feb 25, 2026

Description

Adds a Keyboard Color setting that lets users pick a seed color for the app's dynamic Material theme, mirroring the ColorSettingsDropdownTile pattern from HushTimer.

Data layer

  • New KeyboardColorOption enum in AppSettings.kt — 8 predefined colors (Neutral Gray, Ocean Blue, Coral Red, Forest Green, Deep Purple, Amber Orange, Teal Blue, Slate Gray), each with color: Color and displayName: String as constructor parameters
  • keyboardColorOption field added to AppSettings (default: NeutralGray)
  • updateKeyboardColorOption() added to SettingsRepository and SettingsViewModel

UI layer

  • DropdownListItem gains an optional optionContent: (@Composable (T) -> Unit)? param — when provided, replaces the default text display with custom content (color circle + label). Fully backwards-compatible
  • SettingsScreen shows the new dropdown with a colored circle preview per option
  • HushKeyboardTheme now accepts a seedColor parameter (defaults to existing neutral blue-gray)
  • MainApp reads keyboardColorOption from settings state and passes its color as seedColor to the theme
  • HushKeyboardView also reads keyboardColorOption from KeyboardState and passes its color as seedColor to HushKeyboardTheme, so the IME keyboard matches the selected color

Keyboard ViewModel

  • keyboardColorOption added to KeyboardState in KeyboardViewModel and mapped from AppSettings

How to verify

  1. Open Settings
  2. Tap Keyboard Color — dropdown shows 8 color options, each with a colored circle
  3. Select any color — both the app theme and the keyboard IME update to use that color as the Material seed color
  4. Re-open settings — selection persists across restarts

Screenshots / Videos


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: ricky9667 <55730003+ricky9667@users.noreply.github.com>
Copilot AI changed the title [WIP] Add settings option for ColorSettingsDropdownTile Add keyboard color settings option Feb 25, 2026
Copilot AI requested a review from ricky9667 February 25, 2026 03:06
@ricky9667
Copy link
Owner

@copilot Also apply the theme seed color to the HushKeyboardTheme in HushKeyboardView.

Co-authored-by: ricky9667 <55730003+ricky9667@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 25, 2026

@copilot Also apply the theme seed color to the HushKeyboardTheme in HushKeyboardView.

Done in ae98f06. Added keyboardColorOption to KeyboardState (via KeyboardViewModel) and updated HushKeyboardView.Content() to compute seedColor from the state and pass it to HushKeyboardTheme — same pattern as MainApp.

@ricky9667 ricky9667 marked this pull request as ready for review February 25, 2026 03:21
Copilot AI review requested due to automatic review settings February 25, 2026 03:21
@codecov
Copy link

codecov bot commented Feb 25, 2026

Codecov Report

❌ Patch coverage is 70.31250% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 54.70%. Comparing base (7f82a1e) to head (8876e53).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
.../rickyhu/hushkeyboard/keyboard/HushKeyboardView.kt 0.00% 7 Missing ⚠️
...main/java/com/rickyhu/hushkeyboard/main/MainApp.kt 0.00% 4 Missing ⚠️
.../main/java/com/rickyhu/hushkeyboard/theme/Theme.kt 0.00% 3 Missing ⚠️
...rickyhu/hushkeyboard/settings/SettingsViewModel.kt 33.33% 2 Missing ⚠️
.../java/com/rickyhu/hushkeyboard/data/AppSettings.kt 92.30% 1 Missing ⚠️
...om/rickyhu/hushkeyboard/data/SettingsRepository.kt 0.00% 1 Missing ⚠️
...om/rickyhu/hushkeyboard/settings/SettingsScreen.kt 95.45% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #63      +/-   ##
==========================================
+ Coverage   53.66%   54.70%   +1.03%     
==========================================
  Files          39       39              
  Lines        1090     1148      +58     
  Branches       79       82       +3     
==========================================
+ Hits          585      628      +43     
- Misses        474      489      +15     
  Partials       31       31              

☔ 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.

Comment on lines +18 to +54
enum class KeyboardColorOption {
NeutralGray,
OceanBlue,
CoralRed,
ForestGreen,
DeepPurple,
AmberOrange,
TealBlue,
SlateGray,
;

val color: Color
get() =
when (this) {
NeutralGray -> Color(0xFF6B6B6B)
OceanBlue -> Color(0xFF0077BE)
CoralRed -> Color(0xFFE53935)
ForestGreen -> Color(0xFF2E7D32)
DeepPurple -> Color(0xFF512DA8)
AmberOrange -> Color(0xFFFF8F00)
TealBlue -> Color(0xFF00695C)
SlateGray -> Color(0xFF455A64)
}

override fun toString() =
when (this) {
NeutralGray -> "Neutral Gray"
OceanBlue -> "Ocean Blue"
CoralRed -> "Coral Red"
ForestGreen -> "Forest Green"
DeepPurple -> "Deep Purple"
AmberOrange -> "Amber Orange"
TealBlue -> "Teal Blue"
SlateGray -> "Slate Gray"
}
}

Copy link
Owner

Choose a reason for hiding this comment

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

@copilot I think we can move the color and text to the enum class member instead of using a getter function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 51f2a47. color and displayName are now constructor parameters on each enum entry, and toString() delegates to displayName.

Co-authored-by: ricky9667 <55730003+ricky9667@users.noreply.github.com>
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

Adds a new Keyboard Color setting that lets users choose a seed color for the app’s dynamic Material theme, and applies the same seed color to the IME keyboard theme for visual consistency.

Changes:

  • Introduces KeyboardColorOption and persists it via AppSettings/SettingsRepository, exposing updates through SettingsViewModel and KeyboardViewModel.
  • Extends DropdownListItem with optional custom option rendering to show a color swatch + label in the dropdown.
  • Updates theming to accept a configurable seedColor and wires it through MainApp and HushKeyboardView.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
app/src/test/java/com/rickyhu/hushkeyboard/ui/SettingsScreenUiTest.kt Adds UI tests to cover presence and behavior of the new Keyboard Color dropdown.
app/src/main/res/values/strings.xml Adds keyboard_color string resource.
app/src/main/res/drawable/ic_palette.xml Adds palette icon for the new setting.
app/src/main/java/com/rickyhu/hushkeyboard/theme/Theme.kt Adds seedColor parameter and exposes a default seed color constant.
app/src/main/java/com/rickyhu/hushkeyboard/settings/ui/DropdownListItem.kt Adds optional optionContent slot for custom option rendering.
app/src/main/java/com/rickyhu/hushkeyboard/settings/SettingsViewModel.kt Adds state + update method for keyboardColorOption.
app/src/main/java/com/rickyhu/hushkeyboard/settings/SettingsScreen.kt Adds the new Keyboard Color dropdown UI with color preview.
app/src/main/java/com/rickyhu/hushkeyboard/main/MainApp.kt Applies selected seed color to app theme.
app/src/main/java/com/rickyhu/hushkeyboard/keyboard/KeyboardViewModel.kt Includes keyboardColorOption in KeyboardState.
app/src/main/java/com/rickyhu/hushkeyboard/keyboard/HushKeyboardView.kt Applies selected seed color to IME theme.
app/src/main/java/com/rickyhu/hushkeyboard/data/SettingsRepository.kt Persists keyboardColorOption changes in DataStore.
app/src/main/java/com/rickyhu/hushkeyboard/data/AppSettings.kt Adds keyboardColorOption to settings and defines KeyboardColorOption.
Comments suppressed due to low confidence (1)

app/src/main/java/com/rickyhu/hushkeyboard/data/AppSettings.kt:40

  • KeyboardColorOption.NeutralGray is defined as Color(0xFF6B6B6B), but both MainApp and HushKeyboardView special-case NeutralGray to use DefaultSeedColor (0xFF5B7C99). This makes the settings preview circle (which uses option.color) disagree with the actual theme seed color when NeutralGray is selected. Align the enum’s color (and/or its display name) with the default seed color, or remove the special-casing and always use keyboardColorOption.color so the selected option matches what’s applied.
    SlateGray(Color(0xFF455A64), "Slate Gray"),
    ;

    override fun toString() = displayName
}

enum class WideNotationOption {
    WideWithW,
    WideWithLowercase,
    ;

    override fun toString() =

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +34 to +38
val seedColor =
when (state.keyboardColorOption) {
KeyboardColorOption.NeutralGray -> DefaultSeedColor
else -> state.keyboardColorOption.color
}
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

seedColor is being special-cased for KeyboardColorOption.NeutralGray to DefaultSeedColor, while other options use keyboardColorOption.color. This creates inconsistent behavior relative to the option’s own color value (and the UI preview) and also requires duplicating this mapping elsewhere (IME). Consider making the enum’s default option color match the default seed color, then simply pass state.keyboardColorOption.color here without a when.

Copilot uses AI. Check for mistakes.
Comment on lines +63 to +67
val seedColor =
when (state.keyboardColorOption) {
KeyboardColorOption.NeutralGray -> DefaultSeedColor
else -> state.keyboardColorOption.color
}
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The seedColor mapping logic (including the NeutralGray -> DefaultSeedColor special case) is duplicated here and in MainApp. This duplication makes it easy for the app theme and IME theme to drift over time. Once the enum/default color mismatch is resolved, prefer deriving the seed color from a single shared helper (e.g., an extension/property) and reusing it in both places.

Suggested change
val seedColor =
when (state.keyboardColorOption) {
KeyboardColorOption.NeutralGray -> DefaultSeedColor
else -> state.keyboardColorOption.color
}
val seedColor = state.keyboardColorOption.seedColor

Copilot uses AI. Check for mistakes.
@ricky9667 ricky9667 merged commit eebf32e into master Feb 25, 2026
1 check passed
@ricky9667 ricky9667 deleted the copilot/add-settings-option branch February 25, 2026 03:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants