diff --git a/composeApp/src/commonMain/composeResources/drawable/mouse_left_button_16.svg b/composeApp/src/commonMain/composeResources/drawable/mouse_left_button_16.svg new file mode 100644 index 000000000..2f58c2f8a --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/mouse_left_button_16.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/drawable/mouse_m4_button_16.svg b/composeApp/src/commonMain/composeResources/drawable/mouse_m4_button_16.svg new file mode 100644 index 000000000..4e418198b --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/mouse_m4_button_16.svg @@ -0,0 +1 @@ + diff --git a/composeApp/src/commonMain/composeResources/drawable/mouse_m5_button_16.svg b/composeApp/src/commonMain/composeResources/drawable/mouse_m5_button_16.svg new file mode 100644 index 000000000..aa9be7f4f --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/mouse_m5_button_16.svg @@ -0,0 +1 @@ + diff --git a/composeApp/src/commonMain/composeResources/drawable/mouse_middle_button_16.svg b/composeApp/src/commonMain/composeResources/drawable/mouse_middle_button_16.svg new file mode 100644 index 000000000..37eab1d78 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/mouse_middle_button_16.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/drawable/mouse_right_button_16.svg b/composeApp/src/commonMain/composeResources/drawable/mouse_right_button_16.svg new file mode 100644 index 000000000..e48d5def4 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/mouse_right_button_16.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml index d5262ee13..092944f4c 100644 --- a/composeApp/src/commonMain/composeResources/values/strings.xml +++ b/composeApp/src/commonMain/composeResources/values/strings.xml @@ -1,9 +1,4 @@ - Gold - Jade - Rose Gold - Arctic Blue - Graphite Choose Profile Background Custom background URLs can be configured from the Nuvio web panel. Normal @@ -1391,6 +1386,23 @@ Rose Violet White + Custom + Your custom gradient + Choose three colors for your theme. Select a color to edit it. + Edit custom theme + Your custom color + Choose a color for your theme. + Gradient + Single color + Color %1$d + Hue + Saturation + Brightness + Hex color + Enter six characters (0–9, A–F), with or without #. + Save theme + Preview + Your accent Next Episode Finding source… Playing via %1$s in %2$d… @@ -1675,6 +1687,51 @@ Downloading update... No updates found. A new version is ready to install. + Shortcuts + Keyboard and mouse shortcuts. + GENERAL & NAVIGATION + PLAYER – PLAYBACK + Go back / previous screen + Show options + Switch to home + Switch to search + Switch to library + Switch to settings + Activate search box + Play / Pause + Sequential switch audio track + Toggle enable / disable subtitle + Toggle mute state + Seek forward or backward + Volume up / down + Toggle app fullscreen + Skip intro + Open audio selector window + Open subtitle selector window + Open source list window + Open episode list window + Move focus and options + Play next episode + Hold to speed up playback + Open playback speed panel + Playback speed control + Reset playback speed to 1x + Decrease / increase subtitle delay + Turn on / off sub opacity + Increase / reduce opacity of subs + or + Esc + Space + Enter + Shift + Hold Space + Left + Hold Left + Right + Forward + Backward + Scroll Up + Scroll Down In-app updates are not available on this build. No release notes were provided. Preparing download diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsModels.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsModels.kt index c0061f999..f9bd976e1 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsModels.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsModels.kt @@ -4,6 +4,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.AccountCircle import androidx.compose.material.icons.rounded.Info import androidx.compose.material.icons.rounded.Notifications +import androidx.compose.material.icons.rounded.Keyboard import androidx.compose.material.icons.rounded.Settings import androidx.compose.material.icons.rounded.Tune import androidx.compose.ui.graphics.vector.ImageVector @@ -28,6 +29,7 @@ import nuvio.composeapp.generated.resources.compose_settings_page_playback import nuvio.composeapp.generated.resources.compose_settings_page_plugins import nuvio.composeapp.generated.resources.compose_settings_page_poster_customization import nuvio.composeapp.generated.resources.compose_settings_page_root +import nuvio.composeapp.generated.resources.compose_settings_page_shortcuts import nuvio.composeapp.generated.resources.compose_settings_page_streams import nuvio.composeapp.generated.resources.compose_settings_page_supporters_contributors import nuvio.composeapp.generated.resources.compose_settings_page_tmdb_enrichment @@ -43,6 +45,7 @@ internal enum class SettingsCategory( Account(Res.string.settings_account, Icons.Rounded.AccountCircle), General(Res.string.compose_settings_category_general, Icons.Rounded.Settings), About(Res.string.compose_settings_category_about, Icons.Rounded.Info), + Shortcuts(Res.string.compose_settings_page_shortcuts, Icons.Rounded.Keyboard), Advanced(Res.string.compose_settings_page_advanced, Icons.Rounded.Tune), } @@ -162,6 +165,11 @@ internal enum class SettingsPage( category = SettingsCategory.Account, parentPage = Root, ), + Shortcuts( + titleRes = Res.string.compose_settings_page_shortcuts, + category = SettingsCategory.Shortcuts, + parentPage = Root, + ), } internal val SettingsPage.opensInlineOnTablet: Boolean diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsRootPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsRootPage.kt index d6d5dcc1d..282237ec4 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsRootPage.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsRootPage.kt @@ -12,6 +12,7 @@ import androidx.compose.material.icons.rounded.CloudDownload import androidx.compose.material.icons.rounded.Extension import androidx.compose.material.icons.rounded.Favorite import androidx.compose.material.icons.rounded.Info +import androidx.compose.material.icons.rounded.Keyboard import androidx.compose.material.icons.rounded.Link import androidx.compose.material.icons.rounded.Notifications import androidx.compose.material.icons.rounded.Palette @@ -39,8 +40,10 @@ import nuvio.composeapp.generated.resources.compose_settings_page_licenses_attri import nuvio.composeapp.generated.resources.compose_settings_page_notifications import nuvio.composeapp.generated.resources.compose_settings_page_playback import nuvio.composeapp.generated.resources.compose_settings_page_privacy_policy +import nuvio.composeapp.generated.resources.compose_settings_page_shortcuts import nuvio.composeapp.generated.resources.compose_settings_page_supporters_contributors import nuvio.composeapp.generated.resources.compose_settings_root_account_description +import nuvio.composeapp.generated.resources.compose_settings_root_shortcuts_description import nuvio.composeapp.generated.resources.compose_settings_root_appearance_description import nuvio.composeapp.generated.resources.compose_settings_root_check_updates_description import nuvio.composeapp.generated.resources.compose_settings_root_check_updates_title @@ -74,6 +77,7 @@ internal fun LazyListScope.settingsRootContent( onPlaybackClick: () -> Unit, onAppearanceClick: () -> Unit, onAdvancedClick: () -> Unit, + onShortcutsClick: () -> Unit, onNotificationsClick: () -> Unit, onContentDiscoveryClick: () -> Unit, onIntegrationsClick: () -> Unit, @@ -91,6 +95,7 @@ internal fun LazyListScope.settingsRootContent( showGeneralSection: Boolean = true, showAboutSection: Boolean = true, showAdvancedSection: Boolean = true, + showShortcutsSection: Boolean = true, showSupportersContributorsPage: Boolean = true, ) { if (showAccountSection) { @@ -266,6 +271,24 @@ internal fun LazyListScope.settingsRootContent( } } } + if (showShortcutsSection) { + item { + SettingsSection( + title = stringResource(Res.string.compose_settings_page_shortcuts), + isTablet = isTablet, + ) { + SettingsGroup(isTablet = isTablet) { + SettingsNavigationRow( + title = stringResource(Res.string.compose_settings_page_shortcuts), + description = stringResource(Res.string.compose_settings_root_shortcuts_description), + icon = Icons.Rounded.Keyboard, + isTablet = isTablet, + onClick = onShortcutsClick, + ) + } + } + } + } item { androidx.compose.foundation.layout.Column( modifier = Modifier diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsScreen.kt index 31ee628e1..2bf62c53d 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsScreen.kt @@ -614,6 +614,7 @@ private fun MobileSettingsScreen( onPlaybackClick = { onPageChange(SettingsPage.Playback) }, onAppearanceClick = { onPageChange(SettingsPage.Appearance) }, onAdvancedClick = { onPageChange(SettingsPage.Advanced) }, + onShortcutsClick = { onPageChange(SettingsPage.Shortcuts) }, onNotificationsClick = { onPageChange(SettingsPage.Notifications) }, onContentDiscoveryClick = { onPageChange(SettingsPage.ContentDiscovery) }, onIntegrationsClick = { onPageChange(SettingsPage.Integrations) }, @@ -699,6 +700,9 @@ private fun MobileSettingsScreen( isTablet = false, rememberLastProfileEnabled = rememberLastProfileEnabled, ) + SettingsPage.Shortcuts -> shortcutsSettingsContent( + isTablet = false, + ) SettingsPage.Notifications -> if (AppFeaturePolicy.notificationsEnabled) { notificationsSettingsContent( isTablet = false, @@ -930,10 +934,12 @@ private fun TabletSettingsScreen( icon = category.icon, selected = category == activeCategory, onClick = { - if (category != activeCategory || page != SettingsPage.Root) { + if (category != activeCategory || (category != SettingsCategory.Shortcuts && page != SettingsPage.Root) || (category == SettingsCategory.Shortcuts && page != SettingsPage.Shortcuts)) { selectedCategory = category.name navBarScrollState?.expand() - if (page != SettingsPage.Root) { + if (category == SettingsCategory.Shortcuts) { + onPageChange(SettingsPage.Shortcuts) + } else { onPageChange(SettingsPage.Root) } } @@ -1042,7 +1048,7 @@ private fun TabletSettingsScreen( } else { stringResource(page.titleRes) }, - showBack = previousPage != null, + showBack = previousPage != null && page != SettingsPage.Shortcuts, onBack = { previousPage?.let(onPageChange) }, ) } @@ -1063,6 +1069,7 @@ private fun TabletSettingsScreen( onPlaybackClick = { openInlinePage(SettingsPage.Playback) }, onAppearanceClick = { openInlinePage(SettingsPage.Appearance) }, onAdvancedClick = { openInlinePage(SettingsPage.Advanced) }, + onShortcutsClick = { openInlinePage(SettingsPage.Shortcuts) }, onNotificationsClick = { openInlinePage(SettingsPage.Notifications) }, onContentDiscoveryClick = { openInlinePage(SettingsPage.ContentDiscovery) }, onIntegrationsClick = { openInlinePage(SettingsPage.Integrations) }, @@ -1080,10 +1087,14 @@ private fun TabletSettingsScreen( showGeneralSection = activeCategory == SettingsCategory.General, showAboutSection = activeCategory == SettingsCategory.About, showAdvancedSection = activeCategory == SettingsCategory.Advanced, + showShortcutsSection = activeCategory == SettingsCategory.Shortcuts, showSupportersContributorsPage = AppFeaturePolicy.supportersContributorsPageEnabled, ) } } + SettingsPage.Shortcuts -> shortcutsSettingsContent( + isTablet = true, + ) SettingsPage.Account -> accountSettingsContent( isTablet = true, ) diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/ShortcutsSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/ShortcutsSettingsPage.kt new file mode 100644 index 000000000..96f707048 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/ShortcutsSettingsPage.kt @@ -0,0 +1,365 @@ +package com.nuvio.app.features.settings + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.KeyboardArrowDown +import androidx.compose.material.icons.filled.KeyboardArrowLeft +import androidx.compose.material.icons.filled.KeyboardArrowRight +import androidx.compose.material.icons.filled.KeyboardArrowUp +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import com.nuvio.app.core.ui.nuvio +import nuvio.composeapp.generated.resources.* +import org.jetbrains.compose.resources.stringResource + +internal fun LazyListScope.shortcutsSettingsContent( + isTablet: Boolean, +) { + item { + SettingsSection( + title = stringResource(Res.string.compose_settings_shortcuts_section_general), + isTablet = isTablet, + ) { + SettingsGroup(isTablet = isTablet) { + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_back), isTablet) { + ShortcutKey(stringResource(Res.string.compose_settings_shortcuts_key_esc)) + ShortcutOrText() + ShortcutMouseKey(MouseButton.Backward, stringResource(Res.string.compose_settings_shortcuts_mouse_backward)) + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_options), isTablet) { + ShortcutMouseKey(MouseButton.Right, stringResource(Res.string.compose_settings_shortcuts_mouse_right)) + ShortcutOrText() + ShortcutMouseKey(MouseButton.Left, stringResource(Res.string.compose_settings_shortcuts_mouse_hold_left)) + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_home), isTablet) { + ShortcutKey("1") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_search), isTablet) { + ShortcutKey("2") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_library), isTablet) { + ShortcutKey("3") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_settings), isTablet) { + ShortcutKey("4") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_search_box), isTablet) { + ShortcutKey("/") + ShortcutOrText() + ShortcutKey("0") + } + } + } + } + + item { + SettingsSection( + title = stringResource(Res.string.compose_settings_shortcuts_section_player), + isTablet = isTablet, + ) { + SettingsGroup(isTablet = isTablet) { + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_play_pause), isTablet) { + ShortcutKey(stringResource(Res.string.compose_settings_shortcuts_key_space)) + ShortcutOrText() + ShortcutKey("K") + ShortcutOrText() + ShortcutMouseKey(MouseButton.Left, stringResource(Res.string.compose_settings_shortcuts_mouse_left)) + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_audio_track), isTablet) { + ShortcutKey("B") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_subtitle_toggle), isTablet) { + ShortcutKey("V") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_mute), isTablet) { + ShortcutKey("M") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_seek), isTablet) { + ShortcutIconKey(Icons.Default.KeyboardArrowLeft) + ShortcutOrText() + ShortcutIconKey(Icons.Default.KeyboardArrowRight) + ShortcutOrText() + ShortcutMouseKey(MouseButton.Forward, stringResource(Res.string.compose_settings_shortcuts_mouse_forward)) + ShortcutOrText() + ShortcutMouseKey(MouseButton.Backward, stringResource(Res.string.compose_settings_shortcuts_mouse_backward)) + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_volume), isTablet) { + ShortcutIconKey(Icons.Default.KeyboardArrowUp) + ShortcutOrText() + ShortcutIconKey(Icons.Default.KeyboardArrowDown) + ShortcutOrText() + ShortcutMouseKey(MouseButton.ScrollUp, stringResource(Res.string.compose_settings_shortcuts_mouse_scroll_up)) + ShortcutOrText() + ShortcutMouseKey(MouseButton.ScrollDown, stringResource(Res.string.compose_settings_shortcuts_mouse_scroll_down)) + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_fullscreen), isTablet) { + ShortcutKey("F11") + ShortcutOrText() + ShortcutKey("F") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_skip_intro), isTablet) { + ShortcutKey(stringResource(Res.string.compose_settings_shortcuts_key_enter)) + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_audio_selector), isTablet) { + ShortcutKey("A") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_subtitle_selector), isTablet) { + ShortcutKey("S") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_source_list), isTablet) { + ShortcutKey("Q") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_episode_list), isTablet) { + ShortcutKey("E") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_focus_options), isTablet) { + ShortcutIconKey(Icons.Default.KeyboardArrowUp) + ShortcutOrText() + ShortcutIconKey(Icons.Default.KeyboardArrowDown) + ShortcutOrText() + ShortcutIconKey(Icons.Default.KeyboardArrowLeft) + ShortcutOrText() + ShortcutIconKey(Icons.Default.KeyboardArrowRight) + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_next_episode), isTablet) { + ShortcutKey(stringResource(Res.string.compose_settings_shortcuts_key_shift)) + ShortcutPlusText() + ShortcutKey("N") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_speed_hold), isTablet) { + ShortcutKey(stringResource(Res.string.compose_settings_shortcuts_key_hold_space)) + ShortcutOrText() + ShortcutMouseKey(MouseButton.Left, stringResource(Res.string.compose_settings_shortcuts_mouse_hold_left)) + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_speed_panel), isTablet) { + ShortcutKey("`") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_speed_control), isTablet) { + ShortcutKey(stringResource(Res.string.compose_settings_shortcuts_key_shift)) + ShortcutPlusText() + ShortcutKey("<") + ShortcutOrText() + ShortcutKey(stringResource(Res.string.compose_settings_shortcuts_key_shift)) + ShortcutPlusText() + ShortcutKey(">") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_speed_reset), isTablet) { + ShortcutKey("/") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_subtitle_delay), isTablet) { + ShortcutKey("G") + ShortcutOrText() + ShortcutKey("H") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_sub_opacity_toggle), isTablet) { + ShortcutKey("O") + } + SettingsGroupDivider(isTablet = isTablet) + ShortcutRow(stringResource(Res.string.compose_settings_shortcuts_row_sub_opacity_adjust), isTablet) { + ShortcutKey("I") + ShortcutOrText() + ShortcutKey("P") + } + } + } + } +} + +@Composable +private fun ShortcutRow( + title: String, + isTablet: Boolean, + keys: @Composable RowScope.() -> Unit, +) { + val tokens = MaterialTheme.nuvio + val verticalPadding = if (isTablet) 16.dp else 14.dp + val horizontalPadding = if (isTablet) 20.dp else 16.dp + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = horizontalPadding, vertical = verticalPadding), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Text( + text = title, + style = MaterialTheme.typography.bodyLarge, + color = tokens.colors.textPrimary, + ) + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp), + ) { + keys() + } + } +} + +@Composable +private fun ShortcutKey(label: String) { + val tokens = MaterialTheme.nuvio + Box( + modifier = Modifier + .background( + color = tokens.colors.surfaceCard, + shape = RoundedCornerShape(6.dp) + ) + .border( + width = 1.dp, + color = tokens.colors.borderSubtle, + shape = RoundedCornerShape(6.dp) + ) + .padding(horizontal = 8.dp, vertical = 4.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = label, + style = MaterialTheme.typography.labelLarge, + color = tokens.colors.textPrimary, + fontWeight = FontWeight.Bold, + fontFamily = FontFamily.Monospace, + ) + } +} + +@Composable +private fun ShortcutIconKey(icon: androidx.compose.ui.graphics.vector.ImageVector) { + val tokens = MaterialTheme.nuvio + Box( + modifier = Modifier + .background( + color = tokens.colors.surfaceCard, + shape = RoundedCornerShape(6.dp) + ) + .border( + width = 1.dp, + color = tokens.colors.borderSubtle, + shape = RoundedCornerShape(6.dp) + ) + .padding(horizontal = 4.dp, vertical = 2.dp), + contentAlignment = Alignment.Center, + ) { + Icon( + imageVector = icon, + contentDescription = null, + tint = tokens.colors.textPrimary, + modifier = Modifier.size(18.dp) + ) + } +} + +enum class MouseButton { Left, Right, Middle, ScrollUp, ScrollDown, Forward, Backward, None } + +@Composable +private fun ShortcutMouseKey(button: MouseButton, label: String, modifier: Modifier = Modifier) { + Box( + modifier = modifier + .border( + width = 1.dp, + color = MaterialTheme.nuvio.colors.borderSubtle, + shape = RoundedCornerShape(6.dp) + ) + .background( + color = MaterialTheme.nuvio.colors.surfaceCard, + shape = RoundedCornerShape(6.dp) + ) + .padding(horizontal = 6.dp, vertical = 4.dp), + contentAlignment = Alignment.Center + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(6.dp) + ) { + val iconRes = when (button) { + MouseButton.Left -> Res.drawable.mouse_left_button_16 + MouseButton.Right -> Res.drawable.mouse_right_button_16 + MouseButton.Middle, MouseButton.ScrollUp, MouseButton.ScrollDown -> Res.drawable.mouse_middle_button_16 + MouseButton.Forward -> Res.drawable.mouse_m4_button_16 + MouseButton.Backward -> Res.drawable.mouse_m5_button_16 + MouseButton.None -> null + } + + if (iconRes != null) { + Icon( + painter = org.jetbrains.compose.resources.painterResource(iconRes), + contentDescription = null, + tint = MaterialTheme.nuvio.colors.textPrimary, + modifier = Modifier.size(16.dp) + ) + } else { + Box(modifier = Modifier.size(16.dp)) + } + + Text( + text = label, + color = MaterialTheme.nuvio.colors.textPrimary, + fontFamily = FontFamily.Monospace, + style = MaterialTheme.typography.bodyMedium, + fontWeight = FontWeight.Bold + ) + } + } +} + +@Composable +private fun ShortcutOrText() { + Text( + text = stringResource(Res.string.compose_settings_shortcuts_or), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.nuvio.colors.textSecondary, + modifier = Modifier.padding(horizontal = 2.dp) + ) +} + +@Composable +private fun ShortcutPlusText() { + Text( + text = "+", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.nuvio.colors.textSecondary, + modifier = Modifier.padding(horizontal = 2.dp) + ) +}