Skip to content

Commit 61f22d7

Browse files
committed
update
1 parent 894e1e7 commit 61f22d7

File tree

12 files changed

+247
-66
lines changed

12 files changed

+247
-66
lines changed

app/src/main/java/com/wzq/jd/compose/app/data/NetworkUtil.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import okhttp3.logging.HttpLoggingInterceptor
1212
*
1313
*/
1414
object NetworkUtil {
15+
private const val BASE_URL = "https://www.wanandroid.com/"
1516

16-
val client by lazy {
17+
private val client by lazy {
1718
HttpClient(OkHttp) {
1819
engine {
1920
config {
@@ -34,4 +35,7 @@ object NetworkUtil {
3435
}
3536
}
3637
}
38+
39+
val remoteRepo by lazy { RemoteDataRepo(client, BASE_URL) }
40+
3741
}
Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,46 @@
11
package com.wzq.jd.compose.app.data
22

3+
import com.wzq.jd.compose.app.data.model.ArticleItem
4+
import com.wzq.jd.compose.app.data.model.KnowledgeCategories
5+
import com.wzq.jd.compose.app.data.model.NetResult
6+
import com.wzq.jd.compose.app.data.model.PagingResult
7+
import com.wzq.jd.compose.app.data.model.SearchHotWords
8+
import io.ktor.client.HttpClient
39
import io.ktor.client.call.body
10+
import io.ktor.client.request.forms.submitForm
411
import io.ktor.client.request.get
12+
import io.ktor.http.parametersOf
513

614
/**
715
* create by wzq on 2023/12/1
816
*
917
*/
10-
object RemoteDataRepo {
11-
12-
private const val BASE_URL = "https://www.wanandroid.com/"
13-
private const val HOME_ARTICLE_LIST = "${BASE_URL}article/list/0/json"
14-
private const val KNOWLEDGE_CATEGORIES = "${BASE_URL}tree/json"
15-
private const val PROJECT_LIST = "${BASE_URL}article/listproject/0/json"
16-
17-
private val httpClient get() = NetworkUtil.client
18+
class RemoteDataRepo(private val httpClient: HttpClient, private val baseUrl: String) {
1819

1920
private val defaultErrorHandler = fun(exception: Throwable) {
2021
exception.printStackTrace()
2122
}
2223

23-
suspend fun getHomeArticleList() = httpClient.runCatching {
24-
get(HOME_ARTICLE_LIST).body<NetResultList<ArticleItem>>()
24+
suspend fun getHomeArticleList(pageNum: Int = 0) = httpClient.runCatching {
25+
get("${baseUrl}article/list/${pageNum}/json").body<NetResult<PagingResult<ArticleItem>>>()
2526
}.onFailure(defaultErrorHandler)
2627

27-
suspend fun getProjectList() = httpClient.runCatching {
28-
get(PROJECT_LIST).body<NetResultList<ArticleItem>>()
28+
suspend fun getProjectList(pageNum: Int = 0) = httpClient.runCatching {
29+
get("${baseUrl}article/listproject/$pageNum/json").body<NetResult<PagingResult<ArticleItem>>>()
2930
}.onFailure(defaultErrorHandler)
3031

3132
suspend fun getKnowledgeCategories() = runCatching {
32-
httpClient.get(KNOWLEDGE_CATEGORIES).body<NetResultList<KnowledgeCategories>>()
33+
httpClient.get("${baseUrl}tree/json")
34+
.body<NetResult<List<KnowledgeCategories>>>()
35+
}.onFailure(defaultErrorHandler)
36+
37+
suspend fun getHotWords() = runCatching {
38+
httpClient.get("${baseUrl}hotkey/json").body<NetResult<List<SearchHotWords>>>()
39+
}
40+
41+
suspend fun getSearchResult(keywords: String) = runCatching {
42+
httpClient.submitForm(url = "${baseUrl}article/query/0/json", parametersOf("k", keywords))
43+
.body<NetResult<PagingResult<ArticleItem>>>()
44+
3345
}.onFailure(defaultErrorHandler)
3446
}

app/src/main/java/com/wzq/jd/compose/app/data/ArticleItem.kt renamed to app/src/main/java/com/wzq/jd/compose/app/data/model/ArticleItem.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.wzq.jd.compose.app.data
1+
package com.wzq.jd.compose.app.data.model
22

33
import kotlinx.serialization.Serializable
44

@@ -29,7 +29,7 @@ data class ArticleItem(
2929
val publishTime: Long,
3030
val realSuperChapterId: Int,
3131
val selfVisible: Int,
32-
val shareDate: Long,
32+
val shareDate: Long?,
3333
val shareUser: String,
3434
val superChapterId: Int,
3535
val superChapterName: String,

app/src/main/java/com/wzq/jd/compose/app/data/KnowledgeCategories.kt renamed to app/src/main/java/com/wzq/jd/compose/app/data/model/KnowledgeCategories.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.wzq.jd.compose.app.data
1+
package com.wzq.jd.compose.app.data.model
22

33
import kotlinx.serialization.Serializable
44

app/src/main/java/com/wzq/jd/compose/app/data/NetResult.kt renamed to app/src/main/java/com/wzq/jd/compose/app/data/model/NetResult.kt

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.wzq.jd.compose.app.data
1+
package com.wzq.jd.compose.app.data.model
22

33
import kotlinx.serialization.SerialName
44
import kotlinx.serialization.Serializable
@@ -15,14 +15,7 @@ data class NetResult<T>(
1515
)
1616

1717
@Serializable
18-
data class NetResultList<T>(
19-
val data: ResultList<T>,
20-
val errorCode: Int,
21-
val errorMsg: String
22-
)
23-
24-
@Serializable
25-
data class ResultList<T>(
18+
data class PagingResult<T>(
2619
val curPage: Int,
2720
@SerialName("datas")
2821
val listData: List<T>,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.wzq.jd.compose.app.data.model
2+
3+
import kotlinx.serialization.Serializable
4+
5+
/**
6+
* create by wzq on 2023/12/5
7+
*
8+
*/
9+
@Serializable
10+
data class SearchHotWords(
11+
val id: Int,
12+
val link: String,
13+
val name: String,
14+
val order: Int,
15+
val visible: Int
16+
)

app/src/main/java/com/wzq/jd/compose/app/page/main/HomePage.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import androidx.compose.runtime.Composable
1313
import androidx.compose.ui.Modifier
1414
import androidx.compose.ui.unit.dp
1515
import androidx.navigation.NavHostController
16-
import com.wzq.jd.compose.app.data.ArticleItem
16+
import com.wzq.jd.compose.app.data.model.ArticleItem
1717

1818
/**
1919
* create by wzq on 2023/11/27

app/src/main/java/com/wzq/jd/compose/app/page/main/MainViewModel.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ package com.wzq.jd.compose.app.page.main
33
import androidx.compose.runtime.mutableStateListOf
44
import androidx.lifecycle.ViewModel
55
import androidx.lifecycle.viewModelScope
6-
import com.wzq.jd.compose.app.data.ArticleItem
7-
import com.wzq.jd.compose.app.data.RemoteDataRepo
6+
import com.wzq.jd.compose.app.data.model.ArticleItem
7+
import com.wzq.jd.compose.app.data.NetworkUtil
88
import kotlinx.coroutines.launch
99

1010
/**
1111
* create by wzq on 2023/12/4
1212
*
1313
*/
14-
class MainViewModel: ViewModel() {
14+
class MainViewModel : ViewModel() {
1515

1616
val homeList = mutableStateListOf<ArticleItem>()
1717
val projectList = mutableStateListOf<ArticleItem>()
@@ -24,16 +24,16 @@ class MainViewModel: ViewModel() {
2424

2525
private fun getHomeArticleList() {
2626
viewModelScope.launch {
27-
RemoteDataRepo.getHomeArticleList().onSuccess {
27+
NetworkUtil.remoteRepo.getHomeArticleList().onSuccess {
2828
homeList.clear()
2929
homeList.addAll(it.data.listData)
3030
}
3131
}
3232
}
3333

34-
private fun getProjectList(){
34+
private fun getProjectList() {
3535
viewModelScope.launch {
36-
RemoteDataRepo.getProjectList().onSuccess {
36+
NetworkUtil.remoteRepo.getProjectList().onSuccess {
3737
projectList.clear()
3838
projectList.addAll(it.data.listData)
3939
}

app/src/main/java/com/wzq/jd/compose/app/page/main/ProjectPage.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import androidx.compose.ui.layout.ContentScale
2222
import androidx.compose.ui.unit.dp
2323
import androidx.navigation.NavController
2424
import coil.compose.AsyncImage
25-
import com.wzq.jd.compose.app.data.ArticleItem
25+
import com.wzq.jd.compose.app.data.model.ArticleItem
2626
import io.ktor.http.encodeURLPath
2727

2828
/**
Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,41 @@
11
package com.wzq.jd.compose.app.page.search
22

33
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Arrangement
45
import androidx.compose.foundation.layout.Box
5-
import androidx.compose.foundation.layout.WindowInsets
6+
import androidx.compose.foundation.layout.ExperimentalLayoutApi
7+
import androidx.compose.foundation.layout.FlowRow
68
import androidx.compose.foundation.layout.fillMaxSize
79
import androidx.compose.foundation.layout.fillMaxWidth
810
import androidx.compose.foundation.layout.padding
11+
import androidx.compose.foundation.lazy.LazyColumn
12+
import androidx.compose.foundation.lazy.items
913
import androidx.compose.material.icons.Icons
10-
import androidx.compose.material.icons.filled.ArrowBack
14+
import androidx.compose.material.icons.filled.Check
15+
import androidx.compose.material3.ElevatedFilterChip
1116
import androidx.compose.material3.ExperimentalMaterial3Api
1217
import androidx.compose.material3.Icon
13-
import androidx.compose.material3.IconButton
1418
import androidx.compose.material3.MaterialTheme
1519
import androidx.compose.material3.Scaffold
16-
import androidx.compose.material3.SearchBar
20+
import androidx.compose.material3.Text
1721
import androidx.compose.runtime.Composable
18-
import androidx.compose.runtime.mutableStateOf
22+
import androidx.compose.runtime.mutableStateMapOf
1923
import androidx.compose.runtime.remember
2024
import androidx.compose.ui.Modifier
2125
import androidx.compose.ui.unit.dp
2226
import androidx.navigation.NavController
27+
import com.wzq.jd.compose.app.data.model.SearchHotWords
28+
import com.wzq.jd.compose.app.page.main.ArticleItemPage
2329

2430
/**
2531
* create by wzq on 2023/11/24
2632
*
2733
*/
2834
@Composable
29-
fun SearchPage(navController: NavController) {
35+
fun SearchPage(
36+
navController: NavController,
37+
viewModel: SearchViewModel = androidx.lifecycle.viewmodel.compose.viewModel()
38+
) {
3039
Scaffold(
3140
topBar = {
3241
Box(
@@ -36,42 +45,51 @@ fun SearchPage(navController: NavController) {
3645
MaterialTheme.colorScheme.primaryContainer
3746
)
3847
) {
39-
SearchBar {
48+
SearchPageBar(viewModel) {
4049
navController.navigateUp()
4150
}
4251
}
4352
},
4453
) { pv ->
45-
Box(modifier = Modifier.padding(pv))
54+
Box(modifier = Modifier.padding(pv)) {
55+
if (viewModel.result.isEmpty() || viewModel.keywords.value.isEmpty()) {
56+
DefaultPage(hotWords = viewModel.hotWords) {
57+
viewModel.searchResult(it)
58+
}
59+
} else {
60+
LazyColumn(content = {
61+
items(viewModel.result, key = { it.id }) {
62+
ArticleItemPage(itemData = it) {}
63+
}
64+
})
65+
}
66+
67+
}
4668
}
4769
}
4870

71+
@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterial3Api::class)
4972
@Composable
50-
@OptIn(ExperimentalMaterial3Api::class)
51-
private fun SearchBar(onBackPressed: () -> Unit) {
52-
val searchWords = remember {
53-
mutableStateOf("")
54-
}
55-
val isActive = remember {
56-
mutableStateOf(false)
73+
private fun DefaultPage(hotWords: List<SearchHotWords>, onItemClick: (String) -> Unit) {
74+
val selectRecord = remember {
75+
mutableStateMapOf<Int, Boolean>()
5776
}
58-
SearchBar(query = searchWords.value, onQueryChange = {
59-
searchWords.value = it
60-
isActive.value = it.isNotEmpty()
61-
}, onSearch = {}, active = isActive.value, onActiveChange = {}, leadingIcon = {
62-
IconButton(onClick = {
63-
if (isActive.value) {
64-
isActive.value = false
65-
} else {
66-
onBackPressed()
67-
}
68-
}) {
69-
Icon(Icons.Default.ArrowBack, contentDescription = null)
70-
}
71-
}, modifier = Modifier
72-
.padding(bottom = 16.dp, start = 16.dp, end = 16.dp)
73-
.fillMaxWidth(),
77+
FlowRow(
78+
Modifier
79+
.fillMaxSize()
80+
.padding(16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)
7481
) {
75-
// TODO: search history
82+
hotWords.forEachIndexed { index, hotWords ->
83+
ElevatedFilterChip(selected = selectRecord[index] ?: false, onClick = {
84+
selectRecord[index] = !(selectRecord[index] ?: false)
85+
onItemClick(hotWords.name)
86+
}, leadingIcon = {
87+
if (selectRecord[index] == true) {
88+
Icon(Icons.Default.Check, contentDescription = null)
89+
}
90+
}, label = {
91+
Text(text = hotWords.name)
92+
})
93+
}
7694
}
7795
}

0 commit comments

Comments
 (0)