Skip to content

Commit ba8e27f

Browse files
authored
Merge pull request #324 from OpenHub-Store/desktop-key-feat
2 parents f2b45cb + 5fec24a commit ba8e27f

7 files changed

Lines changed: 94 additions & 25 deletions

File tree

-90.9 KB
Binary file not shown.

composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/Main.kt

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,35 @@ import androidx.compose.runtime.Composable
55
import androidx.compose.runtime.LaunchedEffect
66
import androidx.compose.runtime.getValue
77
import androidx.lifecycle.compose.collectAsStateWithLifecycle
8+
import androidx.navigation.compose.currentBackStackEntryAsState
89
import androidx.navigation.compose.rememberNavController
910
import org.koin.compose.viewmodel.koinViewModel
1011
import zed.rainxch.core.presentation.theme.GithubStoreTheme
1112
import zed.rainxch.core.presentation.utils.ApplyAndroidSystemBars
13+
import zed.rainxch.core.presentation.utils.ObserveAsEvents
1214
import zed.rainxch.githubstore.app.components.RateLimitDialog
1315
import zed.rainxch.githubstore.app.components.SessionExpiredDialog
1416
import zed.rainxch.githubstore.app.deeplink.DeepLinkDestination
1517
import zed.rainxch.githubstore.app.deeplink.DeepLinkParser
18+
import zed.rainxch.githubstore.app.desktop.KeyboardNavigation
19+
import zed.rainxch.githubstore.app.desktop.KeyboardNavigationEvent
1620
import zed.rainxch.githubstore.app.navigation.AppNavigation
1721
import zed.rainxch.githubstore.app.navigation.GithubStoreGraph
22+
import zed.rainxch.githubstore.app.navigation.getCurrentScreen
1823

1924
@Composable
2025
fun App(deepLinkUri: String? = null) {
2126
val viewModel: MainViewModel = koinViewModel()
2227
val state by viewModel.state.collectAsStateWithLifecycle()
2328

24-
val navBackStack = rememberNavController()
29+
val navController = rememberNavController()
30+
val currentScreen = navController.currentBackStackEntryAsState().value.getCurrentScreen()
2531

2632
LaunchedEffect(deepLinkUri) {
2733
deepLinkUri?.let { uri ->
2834
when (val destination = DeepLinkParser.parse(uri)) {
2935
is DeepLinkDestination.Repository -> {
30-
navBackStack.navigate(
36+
navController.navigate(
3137
GithubStoreGraph.DetailsScreen(
3238
owner = destination.owner,
3339
repo = destination.repo,
@@ -42,6 +48,23 @@ fun App(deepLinkUri: String? = null) {
4248
}
4349
}
4450

51+
ObserveAsEvents(KeyboardNavigation.events) { event ->
52+
when (event) {
53+
KeyboardNavigationEvent.OnCtrlFClick -> {
54+
if (currentScreen !is GithubStoreGraph.SearchScreen) {
55+
navController.navigate(GithubStoreGraph.SearchScreen) {
56+
popUpTo(GithubStoreGraph.HomeScreen) {
57+
saveState = true
58+
}
59+
60+
launchSingleTop = true
61+
restoreState = true
62+
}
63+
}
64+
}
65+
}
66+
}
67+
4568
GithubStoreTheme(
4669
fontTheme = state.currentFontTheme,
4770
appTheme = state.currentColorTheme,
@@ -50,21 +73,19 @@ fun App(deepLinkUri: String? = null) {
5073
) {
5174
ApplyAndroidSystemBars(state.isDarkTheme)
5275

53-
if (state.showRateLimitDialog) {
54-
state.rateLimitInfo?.let {
55-
RateLimitDialog(
56-
rateLimitInfo = it,
57-
isAuthenticated = state.isLoggedIn,
58-
onDismiss = {
59-
viewModel.onAction(MainAction.DismissRateLimitDialog)
60-
},
61-
onSignIn = {
62-
viewModel.onAction(MainAction.DismissRateLimitDialog)
76+
if (state.showRateLimitDialog && state.rateLimitInfo != null) {
77+
RateLimitDialog(
78+
rateLimitInfo = state.rateLimitInfo!!,
79+
isAuthenticated = state.isLoggedIn,
80+
onDismiss = {
81+
viewModel.onAction(MainAction.DismissRateLimitDialog)
82+
},
83+
onSignIn = {
84+
viewModel.onAction(MainAction.DismissRateLimitDialog)
6385

64-
navBackStack.navigate(GithubStoreGraph.AuthenticationScreen)
65-
},
66-
)
67-
}
86+
navController.navigate(GithubStoreGraph.AuthenticationScreen)
87+
},
88+
)
6889
}
6990

7091
if (state.showSessionExpiredDialog) {
@@ -74,13 +95,13 @@ fun App(deepLinkUri: String? = null) {
7495
},
7596
onSignIn = {
7697
viewModel.onAction(MainAction.DismissSessionExpiredDialog)
77-
navBackStack.navigate(GithubStoreGraph.AuthenticationScreen)
98+
navController.navigate(GithubStoreGraph.AuthenticationScreen)
7899
},
79100
)
80101
}
81102

82103
AppNavigation(
83-
navController = navBackStack,
104+
navController = navController,
84105
)
85106
}
86107
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package zed.rainxch.githubstore.app.desktop
2+
3+
import kotlinx.coroutines.channels.Channel
4+
import kotlinx.coroutines.flow.receiveAsFlow
5+
6+
object KeyboardNavigation {
7+
private val _events = Channel<KeyboardNavigationEvent>()
8+
val events = _events.receiveAsFlow()
9+
10+
fun onKeyClicked(event: KeyboardNavigationEvent) {
11+
_events.trySend(event)
12+
}
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package zed.rainxch.githubstore.app.desktop
2+
3+
sealed interface KeyboardNavigationEvent {
4+
data object OnCtrlFClick : KeyboardNavigationEvent
5+
}

composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/navigation/AppNavigation.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,12 @@ fun AppNavigation(navController: NavHostController) {
140140
},
141141
viewModel =
142142
koinViewModel {
143-
parametersOf(args.repositoryId, args.owner, args.repo, args.isComingFromUpdate)
143+
parametersOf(
144+
args.repositoryId,
145+
args.owner,
146+
args.repo,
147+
args.isComingFromUpdate,
148+
)
144149
},
145150
)
146151
}
@@ -272,7 +277,8 @@ fun AppNavigation(navController: NavHostController) {
272277
}
273278
}
274279

275-
val currentScreen = navController.currentBackStackEntryAsState().value.getCurrentScreen()
280+
val currentScreen =
281+
navController.currentBackStackEntryAsState().value.getCurrentScreen()
276282

277283
currentScreen?.let {
278284
BottomNavigation(
@@ -294,7 +300,8 @@ fun AppNavigation(navController: NavHostController) {
294300
.navigationBarsPadding()
295301
.padding(bottom = 24.dp)
296302
.onGloballyPositioned { coordinates ->
297-
bottomNavigationHeight = with(density) { coordinates.size.height.toDp() }
303+
bottomNavigationHeight =
304+
with(density) { coordinates.size.height.toDp() }
298305
},
299306
)
300307
}

composeApp/src/jvmMain/kotlin/zed/rainxch/githubstore/DesktopApp.kt

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,35 @@ import androidx.compose.runtime.LaunchedEffect
44
import androidx.compose.runtime.getValue
55
import androidx.compose.runtime.mutableStateOf
66
import androidx.compose.runtime.setValue
7+
import androidx.compose.ui.input.key.Key
8+
import androidx.compose.ui.input.key.KeyEventType
9+
import androidx.compose.ui.input.key.isCtrlPressed
10+
import androidx.compose.ui.input.key.isMetaPressed
11+
import androidx.compose.ui.input.key.key
12+
import androidx.compose.ui.input.key.type
713
import androidx.compose.ui.window.Window
814
import androidx.compose.ui.window.application
9-
import githubstore.composeapp.generated.resources.Res
10-
import githubstore.composeapp.generated.resources.app_icon
1115
import org.jetbrains.compose.resources.painterResource
16+
import org.jetbrains.compose.resources.stringResource
17+
import zed.rainxch.githubstore.app.desktop.KeyboardNavigation
18+
import zed.rainxch.githubstore.app.desktop.KeyboardNavigationEvent
1219
import zed.rainxch.githubstore.app.di.initKoin
20+
import zed.rainxch.githubstore.core.presentation.res.Res
21+
import zed.rainxch.githubstore.core.presentation.res.app_icon
22+
import zed.rainxch.githubstore.core.presentation.res.app_name
1323
import java.awt.Desktop
1424
import kotlin.system.exitProcess
1525

1626
fun main(args: Array<String>) {
27+
initKoin()
28+
1729
val deepLinkArg = args.firstOrNull()
1830

1931
if (deepLinkArg != null && DesktopDeepLink.tryForwardToRunningInstance(deepLinkArg)) {
2032
exitProcess(0)
2133
}
2234

2335
DesktopDeepLink.registerUriSchemeIfNeeded()
24-
initKoin()
2536

2637
application {
2738
var deepLinkUri by mutableStateOf(deepLinkArg)
@@ -44,8 +55,20 @@ fun main(args: Array<String>) {
4455

4556
Window(
4657
onCloseRequest = ::exitApplication,
47-
title = "GitHub Store",
58+
title = stringResource(Res.string.app_name),
4859
icon = painterResource(Res.drawable.app_icon),
60+
onKeyEvent = { keyEvent ->
61+
if (keyEvent.key == Key.F && keyEvent.type == KeyEventType.KeyDown) {
62+
if (keyEvent.isCtrlPressed || keyEvent.isMetaPressed) {
63+
KeyboardNavigation.onKeyClicked(KeyboardNavigationEvent.OnCtrlFClick)
64+
true
65+
} else {
66+
false
67+
}
68+
} else {
69+
false
70+
}
71+
},
4972
) {
5073
App(deepLinkUri = deepLinkUri)
5174
}
-4.03 KB
Loading

0 commit comments

Comments
 (0)