11package com.texthip.thip.ui.booksearch.screen
22
33import androidx.compose.foundation.layout.Box
4+ import androidx.compose.foundation.layout.Column
5+ import androidx.compose.foundation.layout.Spacer
46import androidx.compose.foundation.layout.fillMaxSize
5- import androidx.compose.material3.Text
7+ import androidx.compose.foundation.layout.fillMaxWidth
8+ import androidx.compose.foundation.layout.height
9+ import androidx.compose.foundation.layout.padding
610import androidx.compose.runtime.Composable
7- import androidx.compose.ui.Alignment
11+ import androidx.compose.runtime.LaunchedEffect
12+ import androidx.compose.runtime.derivedStateOf
13+ import androidx.compose.runtime.getValue
14+ import androidx.compose.runtime.mutableStateOf
15+ import androidx.compose.runtime.remember
16+ import androidx.compose.runtime.saveable.rememberSaveable
17+ import androidx.compose.runtime.setValue
818import androidx.compose.ui.Modifier
9- import androidx.navigation.NavController
19+ import androidx.compose.ui.focus.FocusRequester
20+ import androidx.compose.ui.focus.focusRequester
21+ import androidx.compose.ui.platform.LocalFocusManager
22+ import androidx.compose.ui.res.stringResource
23+ import androidx.compose.ui.tooling.preview.Preview
24+ import androidx.compose.ui.unit.dp
25+ import androidx.navigation.NavHostController
26+ import com.texthip.thip.R
27+ import com.texthip.thip.ui.common.forms.SearchBookTextField
28+ import com.texthip.thip.ui.common.topappbar.DefaultTopAppBar
29+ import com.texthip.thip.ui.booksearch.component.BookEmptyResult
30+ import com.texthip.thip.ui.booksearch.component.BookFilteredSearchResult
31+ import com.texthip.thip.ui.booksearch.component.BookLiveSearchResult
32+ import com.texthip.thip.ui.booksearch.component.BookRecentSearch
33+ import com.texthip.thip.ui.booksearch.mock.BookData
34+ import com.texthip.thip.ui.theme.ThipTheme
1035
1136@Composable
12- fun BookSearchScreen (navController : NavController ) {
37+ fun BookSearchScreen (
38+ modifier : Modifier = Modifier ,
39+ navController : NavHostController ? = null,
40+ bookList : List <BookData > = emptyList(),
41+ popularBooks : List <BookData > = emptyList()
42+ ) {
43+ var recentSearches by rememberSaveable {
44+ mutableStateOf(listOf (" asd" , " qwe" , " xcv" , " dfggfd" , " asdasd" , " gfhjghj" ))
45+ }
46+ var searchText by rememberSaveable { mutableStateOf(" " ) }
47+ var isSearched by rememberSaveable { mutableStateOf(false ) }
48+ val focusRequester = remember { FocusRequester () }
49+ val focusManager = LocalFocusManager .current
50+
51+ val liveFilteredBookList by remember(searchText) {
52+ derivedStateOf {
53+ if (searchText.isBlank()) emptyList() else
54+ bookList.filter { book ->
55+ book.title.contains(searchText, ignoreCase = true ) ||
56+ book.author.contains(searchText, ignoreCase = true ) ||
57+ book.publisher.contains(searchText, ignoreCase = true )
58+ }
59+ }
60+ }
61+
62+ val filteredBookList by remember(searchText, isSearched) {
63+ derivedStateOf {
64+ if (! isSearched) emptyList()
65+ else {
66+ bookList.filter { book ->
67+ searchText.isBlank() ||
68+ book.title.contains(searchText, ignoreCase = true ) ||
69+ book.author.contains(searchText, ignoreCase = true ) ||
70+ book.publisher.contains(searchText, ignoreCase = true )
71+ }
72+ }
73+ }
74+ }
75+
76+ LaunchedEffect (isSearched) {
77+ if (isSearched) {
78+ focusManager.clearFocus()
79+ }
80+ }
81+
1382 Box (
14- modifier = Modifier .fillMaxSize(),
15- contentAlignment = Alignment .Center
83+ modifier = modifier.fillMaxSize()
1684 ) {
17- Text (text = " Book Search Screen" )
85+ Column (
86+ modifier = Modifier .fillMaxSize()
87+ ) {
88+ DefaultTopAppBar (
89+ title = stringResource(R .string.book_search_topappbar),
90+ onLeftClick = {},
91+ )
92+ Column (
93+ modifier = Modifier
94+ .fillMaxSize()
95+ .padding(horizontal = 20 .dp)
96+ ) {
97+ Spacer (modifier = Modifier .height(16 .dp))
98+
99+ SearchBookTextField (
100+ modifier = Modifier
101+ .fillMaxWidth()
102+ .focusRequester(focusRequester),
103+ hint = stringResource(R .string.book_search_hint),
104+ text = searchText,
105+ onValueChange = {
106+ searchText = it
107+ isSearched = false
108+ },
109+ onSearch = { query ->
110+ if (query.isNotBlank() && ! recentSearches.contains(query)) {
111+ recentSearches = listOf (query) + recentSearches
112+ }
113+ isSearched = true
114+ }
115+ )
116+ Spacer (modifier = Modifier .height(16 .dp))
117+
118+ when {
119+ searchText.isBlank() && ! isSearched -> {
120+ BookRecentSearch (
121+ recentSearches = recentSearches,
122+ popularBooks = popularBooks,
123+ popularBookDate = " 01.12" , // TODO: 서버로 날짜를 받아 오게 수정
124+ onSearchClick = { keyword ->
125+ searchText = keyword
126+ isSearched = true
127+ },
128+ onRemove = { keyword ->
129+ recentSearches = recentSearches.filterNot { it == keyword }
130+ },
131+ onBookClick = { book ->
132+ // 책 클릭 시 처리
133+ }
134+ )
135+ }
136+
137+ searchText.isNotBlank() && ! isSearched -> {
138+ if (liveFilteredBookList.isEmpty()) {
139+ BookEmptyResult (
140+ mainText = stringResource(R .string.book_no_search_result1),
141+ subText = stringResource(R .string.book_no_search_result2),
142+ onRequestBook = { /* 책 요청 처리*/ }
143+ )
144+ } else {
145+ BookLiveSearchResult (
146+ bookList = liveFilteredBookList
147+ )
148+ }
149+ }
150+
151+ isSearched -> {
152+ BookFilteredSearchResult (
153+ resultCount = filteredBookList.size,
154+ bookList = filteredBookList,
155+ )
156+ }
157+ }
158+ }
159+ }
160+ }
161+ }
162+
163+
164+ @Preview(showBackground = true )
165+ @Composable
166+ fun PreviewBookSearchScreen_Default () {
167+ ThipTheme {
168+ BookSearchScreen (
169+ bookList = listOf (
170+ BookData (" aaa" , " 리처드 도킨스" , " 을유문화사" , R .drawable.bookcover_sample),
171+ BookData (" abc" , " 마틴 셀리그만" , " 물푸레" , R .drawable.bookcover_sample),
172+ BookData (" abcd" , " 빅터 프랭클" , " 청림출판" , R .drawable.bookcover_sample),
173+ BookData (" abcde" , " 칼 융" , " 문학과지성사" , R .drawable.bookcover_sample),
174+ BookData (" abcdef" , " 에릭 프롬" , " 까치글방" , R .drawable.bookcover_sample),
175+ BookData (" abcedfg" , " 알베르 카뮈" , " 민음사" , R .drawable.bookcover_sample),
176+ BookData (" abcdefgh" , " 장 폴 사르트르" , " 문학동네" , R .drawable.bookcover_sample),
177+ ),
178+ popularBooks = listOf (
179+ BookData (" 단 한번의 삶" , " 리처드 도킨스" , " 을유문화사" , R .drawable.bookcover_sample),
180+ BookData (" 사랑" , " 마틴 셀리그만" , " 물푸레" , R .drawable.bookcover_sample),
181+ BookData (" 호모 사피엔스" , " 빅터 프랭클" , " 청림출판" , R .drawable.bookcover_sample),
182+ BookData (" 코스모스 실버" , " 칼 융" , " 문학과지성사" , R .drawable.bookcover_sample),
183+ BookData (" 오만과 편견" , " 에릭 프롬" , " 까치글방" , R .drawable.bookcover_sample),
184+ )
185+ )
186+ }
187+ }
188+
189+ @Preview(showBackground = true )
190+ @Composable
191+ fun PreviewBookSearchScreen_EmptyPopular () {
192+ ThipTheme {
193+ BookSearchScreen (
194+ bookList = listOf (
195+ BookData (" aaa" , " 리처드 도킨스" , " 을유문화사" , R .drawable.bookcover_sample),
196+ BookData (" abc" , " 마틴 셀리그만" , " 물푸레" , R .drawable.bookcover_sample),
197+ BookData (" abcd" , " 빅터 프랭클" , " 청림출판" , R .drawable.bookcover_sample),
198+ BookData (" abcde" , " 칼 융" , " 문학과지성사" , R .drawable.bookcover_sample),
199+ BookData (" abcdef" , " 에릭 프롬" , " 까치글방" , R .drawable.bookcover_sample),
200+ BookData (" abcedfg" , " 알베르 카뮈" , " 민음사" , R .drawable.bookcover_sample),
201+ BookData (" abcdefgh" , " 장 폴 사르트르" , " 문학동네" , R .drawable.bookcover_sample),
202+ ),
203+ popularBooks = emptyList()
204+ )
18205 }
19- }
206+ }
0 commit comments