mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-14 22:17:03 +05:30
feat(android): fully flesh out search screen
This commit is contained in:
parent
082dc9cc82
commit
06edbeb903
4 changed files with 89 additions and 26 deletions
|
@ -14,17 +14,12 @@ import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.SystemBarStyle
|
import androidx.activity.SystemBarStyle
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import com.deliveryhero.whetstone.Whetstone
|
import com.deliveryhero.whetstone.Whetstone
|
||||||
import com.deliveryhero.whetstone.activity.ContributesActivityInjector
|
import com.deliveryhero.whetstone.activity.ContributesActivityInjector
|
||||||
import dev.msfjarvis.claw.android.ui.lists.SearchList
|
import dev.msfjarvis.claw.android.ui.screens.SearchScreen
|
||||||
import dev.msfjarvis.claw.android.ui.rememberPostActions
|
|
||||||
import dev.msfjarvis.claw.android.viewmodel.ClawViewModel
|
import dev.msfjarvis.claw.android.viewmodel.ClawViewModel
|
||||||
|
import dev.msfjarvis.claw.common.comments.HTMLConverter
|
||||||
import dev.msfjarvis.claw.common.theme.LobstersTheme
|
import dev.msfjarvis.claw.common.theme.LobstersTheme
|
||||||
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
|
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -33,7 +28,9 @@ import javax.inject.Inject
|
||||||
class SearchActivity : ComponentActivity() {
|
class SearchActivity : ComponentActivity() {
|
||||||
|
|
||||||
@Inject lateinit var urlLauncher: UrlLauncher
|
@Inject lateinit var urlLauncher: UrlLauncher
|
||||||
|
@Inject lateinit var htmlConverter: HTMLConverter
|
||||||
@Inject lateinit var viewModel: ClawViewModel
|
@Inject lateinit var viewModel: ClawViewModel
|
||||||
|
private var webUri: String? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -55,18 +52,7 @@ class SearchActivity : ComponentActivity() {
|
||||||
dynamicColor = true,
|
dynamicColor = true,
|
||||||
providedValues = arrayOf(LocalUriHandler provides urlLauncher),
|
providedValues = arrayOf(LocalUriHandler provides urlLauncher),
|
||||||
) {
|
) {
|
||||||
val navController = rememberNavController()
|
SearchScreen(urlLauncher, htmlConverter, { webUri = it })
|
||||||
val postActions = rememberPostActions(urlLauncher, navController, viewModel)
|
|
||||||
val listState = rememberLazyListState()
|
|
||||||
SearchList(
|
|
||||||
items = viewModel.searchResults,
|
|
||||||
listState = listState,
|
|
||||||
isPostSaved = viewModel::isPostSaved,
|
|
||||||
postActions = postActions,
|
|
||||||
searchQuery = viewModel.searchQuery,
|
|
||||||
setSearchQuery = { query -> viewModel.searchQuery = query },
|
|
||||||
modifier = Modifier.padding(top = 56.dp),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +60,11 @@ class SearchActivity : ComponentActivity() {
|
||||||
override fun onProvideAssistContent(outContent: AssistContent?) {
|
override fun onProvideAssistContent(outContent: AssistContent?) {
|
||||||
super.onProvideAssistContent(outContent)
|
super.onProvideAssistContent(outContent)
|
||||||
if (outContent != null) {
|
if (outContent != null) {
|
||||||
outContent.webUri = Uri.parse("https://lobste.rs/search")
|
if (webUri != null) {
|
||||||
|
outContent.webUri = Uri.parse(webUri)
|
||||||
|
} else {
|
||||||
|
outContent.webUri = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
@ -54,11 +53,6 @@ fun SearchList(
|
||||||
setSearchQuery(query)
|
setSearchQuery(query)
|
||||||
lazyPagingItems.refresh()
|
lazyPagingItems.refresh()
|
||||||
}
|
}
|
||||||
DisposableEffect(true) {
|
|
||||||
// Clear search field when navigating away
|
|
||||||
onDispose { setSearchQuery("") }
|
|
||||||
}
|
|
||||||
|
|
||||||
var searchActive by remember { mutableStateOf(false) }
|
var searchActive by remember { mutableStateOf(false) }
|
||||||
Column(modifier = modifier.semantics { isTraversalGroup = true }.zIndex(1f).fillMaxWidth()) {
|
Column(modifier = modifier.semantics { isTraversalGroup = true }.zIndex(1f).fillMaxWidth()) {
|
||||||
SearchBar(
|
SearchBar(
|
||||||
|
|
|
@ -35,6 +35,10 @@ sealed class Destinations {
|
||||||
override val route: String = "datatransfer"
|
override val route: String = "datatransfer"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Search : Destinations() {
|
||||||
|
override val route: String = "search"
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val startDestination
|
val startDestination
|
||||||
get() = Hottest
|
get() = Hottest
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2023 Harsh Shandilya.
|
||||||
|
* Use of this source code is governed by an MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT.
|
||||||
|
*/
|
||||||
|
package dev.msfjarvis.claw.android.ui.screens
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.navigation.NavType
|
||||||
|
import androidx.navigation.compose.NavHost
|
||||||
|
import androidx.navigation.compose.composable
|
||||||
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import androidx.navigation.navArgument
|
||||||
|
import com.deliveryhero.whetstone.compose.injectedViewModel
|
||||||
|
import dev.msfjarvis.claw.android.ui.lists.SearchList
|
||||||
|
import dev.msfjarvis.claw.android.ui.navigation.Destinations
|
||||||
|
import dev.msfjarvis.claw.android.ui.rememberPostActions
|
||||||
|
import dev.msfjarvis.claw.android.viewmodel.ClawViewModel
|
||||||
|
import dev.msfjarvis.claw.common.comments.CommentsPage
|
||||||
|
import dev.msfjarvis.claw.common.comments.HTMLConverter
|
||||||
|
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SearchScreen(
|
||||||
|
urlLauncher: UrlLauncher,
|
||||||
|
htmlConverter: HTMLConverter,
|
||||||
|
setWebUri: (String?) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
viewModel: ClawViewModel = injectedViewModel(),
|
||||||
|
) {
|
||||||
|
val navController = rememberNavController()
|
||||||
|
val postActions = rememberPostActions(urlLauncher, navController, viewModel)
|
||||||
|
val listState = rememberLazyListState()
|
||||||
|
Scaffold(modifier = modifier) { paddingValues ->
|
||||||
|
NavHost(
|
||||||
|
navController = navController,
|
||||||
|
startDestination = Destinations.Search.route,
|
||||||
|
modifier = Modifier.padding(paddingValues),
|
||||||
|
) {
|
||||||
|
composable(route = Destinations.Search.route) {
|
||||||
|
setWebUri("https://lobste.rs/search")
|
||||||
|
SearchList(
|
||||||
|
items = viewModel.searchResults,
|
||||||
|
listState = listState,
|
||||||
|
isPostSaved = viewModel::isPostSaved,
|
||||||
|
postActions = postActions,
|
||||||
|
searchQuery = viewModel.searchQuery,
|
||||||
|
setSearchQuery = { query -> viewModel.searchQuery = query },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
composable(
|
||||||
|
route = Destinations.Comments.route,
|
||||||
|
arguments = listOf(navArgument("postId") { type = NavType.StringType }),
|
||||||
|
) { backStackEntry ->
|
||||||
|
val postId =
|
||||||
|
requireNotNull(backStackEntry.arguments?.getString("postId")) {
|
||||||
|
"Navigating to ${Destinations.Comments.route} without necessary 'postId' argument"
|
||||||
|
}
|
||||||
|
setWebUri("https://lobste.rs/s/$postId")
|
||||||
|
CommentsPage(
|
||||||
|
postId = postId,
|
||||||
|
postActions = postActions,
|
||||||
|
htmlConverter = htmlConverter,
|
||||||
|
getSeenComments = viewModel::getSeenComments,
|
||||||
|
markSeenComments = viewModel::markSeenComments,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue