Skip to content

Commit

Permalink
Merge pull request #123 from dmzz-yyhyy/pull_to_refresh
Browse files Browse the repository at this point in the history
添加探索页的下拉刷新功能
  • Loading branch information
dmzz-yyhyy authored Oct 26, 2024
2 parents 00c1d62 + fd178d5 commit b4a0349
Show file tree
Hide file tree
Showing 18 changed files with 291 additions and 182 deletions.
4 changes: 2 additions & 2 deletions .idea/deploymentTargetSelector.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ android {
minSdk = 24
targetSdk = 34
// 版本号为x.y.z则versionCode为x*1000000+y*10000+z*100+debug版本号(开发需要时迭代, 两位数)
versionCode = 1_00_00_003
versionCode = 1_00_00_004
versionName = "1.0.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Expand Down Expand Up @@ -81,20 +81,20 @@ dependencies {
// android lib
implementation("androidx.core:core-ktx:1.13.1")
implementation ("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.5")
implementation("androidx.lifecycle:lifecycle-runtime-compose-android:2.8.5")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.5")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.6")
implementation("androidx.lifecycle:lifecycle-runtime-compose-android:2.8.6")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.6")
// compose
implementation("androidx.activity:activity-compose:1.9.2")
implementation("androidx.compose.animation:animation-graphics-android:1.7.1")
implementation(platform("androidx.compose:compose-bom:2024.09.01"))
implementation("androidx.compose.material3:material3:1.3.0")
androidTestImplementation(platform("androidx.compose:compose-bom:2024.09.01"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3:1.3.0")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
androidTestImplementation(platform("androidx.compose:compose-bom:2024.09.01"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
// junit
testImplementation("junit:junit:4.13.2")
Expand Down
Binary file added app/release/LightNovelReader-1.0.0-release.apk
Binary file not shown.
21 changes: 21 additions & 0 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "indi.dmzz_yyhyy.lightnovelreader",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0.0",
"outputFile": "LightNovelReader-1.0.0-release.apk"
}
],
"elementType": "File",
"minSdkVersionForDexing": 24
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ class ExplorationRepository @Inject constructor(
) {
private val searchResultCacheMap = mutableMapOf<String, List<BookInformation>>()
private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)
val explorationPageTitleList = webBookDataSource.explorationPageTitleList
val searchTypeNameList = webBookDataSource.searchTypeNameList
val searchTypeMap = webBookDataSource.searchTypeMap
val searchTipMap = webBookDataSource.searchTipMap

suspend fun getExplorationPageMap() = webBookDataSource.getExplorationPageMap()
suspend fun getExplorationPageTitleList() = webBookDataSource.getExplorationPageTitleList()
fun getExplorationExpandedPageDataSource(expandedPageDataSourceId: String): ExplorationExpandedPageDataSource? =
webBookDataSource.getExplorationExpandedPageDataSourceMap()[expandedPageDataSourceId]

Expand All @@ -42,7 +45,4 @@ class ExplorationRepository @Inject constructor(
return flow
}
fun stopAllSearch() = webBookDataSource.stopAllSearch()
fun getSearchTypeNameList(): List<String> = webBookDataSource.getSearchTypeNameList()
fun getSearchTypeMap(): Map<String, String> = webBookDataSource.getSearchTypeMap()
fun getSearchTipMap(): Map<String, String> = webBookDataSource.getSearchTipMap()
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,42 @@ import indi.dmzz_yyhyy.lightnovelreader.data.web.exploration.ExplorationExpanded
import indi.dmzz_yyhyy.lightnovelreader.data.web.exploration.ExplorationPageDataSource
import kotlinx.coroutines.flow.Flow

/**
* LightNovelReader 的网络数据提供源接口,可以通过实现此接口使软件支持新的数据源
* 版本: 0.1
*/
interface WebBookDataSource {
val id: Int
/**
* 获取当前软件整体是否处于离线状态
*/
suspend fun isOffLine(): Boolean

/**
* 获取当前软件整体是否处于离线状态的数据流
* 此数据流应当为热数据流, 并且不断对状态进行更新
* 该函数应当保证主线程安全
*
*@return 是否处于离线状态的数据流
*/
suspend fun getIsOffLineFlow(): Flow<Boolean>
val isOffLineFlow: Flow<Boolean>

/**
* 所有探索页页面的标题
*/
val explorationPageTitleList: List<String>

/**
* 搜索类型名称和id的对应表
*/
val searchTypeMap: Map<String, String>

/**
* 搜索类型id和搜索栏提示的对应表
*/
val searchTipMap: Map<String, String>

/**
* 搜索类型名称的有序列表
*/
val searchTypeNameList: List<String>

/**
* 此函数无需保证主线程安全性, 为阻塞函数, 获取到数据前应当保持阻塞
Expand Down Expand Up @@ -54,14 +80,6 @@ interface WebBookDataSource {
*/
suspend fun getExplorationPageMap(): Map<String, ExplorationPageDataSource>

/**
* 获取所有探索页页面的标题
* 此函数应当保证主线程安全
*
* @return 有序的所有探索页页面的标题列表
*/
suspend fun getExplorationPageTitleList(): List<String>

/**
* 获取各个探索页横栏的展开页的id与展开页数据源的对应表
* 此函数应当保证主线程安全
Expand All @@ -83,30 +101,6 @@ interface WebBookDataSource {
*/
fun search(searchType: String, keyword: String): Flow<List<BookInformation>>

/**
* 获取搜索类型名称和id的对应表
* 此函数应当保证主线程安全
*
* @return 以搜索类型名称为键, 以id为值的Map
*/
fun getSearchTypeMap(): Map<String, String>

/**
* 获取搜索类型id和搜索栏提示的对应表
* 此函数应当保证主线程安全
*
* @return 以搜索类型id为键, 以搜索栏提示为值的Map
*/
fun getSearchTipMap(): Map<String, String>

/**
* 获取搜索类型名称的有序列表
* 此函数应当保证主线程安全
*
* @return 搜索类型名称的有序列表
*/
fun getSearchTypeNameList(): List<String>

/**
* 停止当前所执行的所有搜索任务
* 此函数应当保证主线程安全
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,24 @@ object Wenku8Api: WebBookDataSource {
private var allBookChapterListCacheId: Int = -1
private var allBookChapterListCache: List<ChapterInformation> = emptyList()
private val DATA_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd")
private val isOffLineFlow = flow {
private val explorationExpandedPageDataSourceMap = mutableMapOf<String, ExplorationExpandedPageDataSource>()
private var coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)

override val isOffLineFlow = flow {
while(true) {
emit(isOffLine())
delay(2500)
delay(500)
}
}
private val explorationExpandedPageDataSourceMap = mutableMapOf<String, ExplorationExpandedPageDataSource>()
private var coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)

private fun isOffLine(): Boolean {
override suspend fun isOffLine(): Boolean =
try {
Jsoup.connect(update("eNpb85aBtYRBMaOkpMBKXz-xoECvPDUvu9RCLzk_Vz8xL6UoPzNFryCjAAAfiA5Q").toString()).get()
Jsoup.connect("https://www.wenku8.cc/").get()
return false
false
} catch (_: Exception) {
return true
true
}
}

private fun isAppDataSourceOffLine(): Boolean {
try {
Expand All @@ -70,8 +70,6 @@ object Wenku8Api: WebBookDataSource {

override val id: Int = "wenku8".hashCode()

override suspend fun getIsOffLineFlow(): Flow<Boolean> = isOffLineFlow

override fun getBookInformation(id: Int): BookInformation {
if (isAppDataSourceOffLine()) return BookInformation.empty()
return wenku8Api("action=book&do=meta&aid=$id&t=0")?.let {
Expand Down Expand Up @@ -172,7 +170,7 @@ object Wenku8Api: WebBookDataSource {
Pair("分类", Wenku8TagsExplorationPage)
)

override suspend fun getExplorationPageTitleList(): List<String> = listOf("首页", "全部", "分类")
override val explorationPageTitleList: List<String> = listOf("首页", "全部", "分类")

override fun getExplorationExpandedPageDataSourceMap(): Map<String, ExplorationExpandedPageDataSource> = explorationExpandedPageDataSourceMap

Expand Down Expand Up @@ -203,16 +201,16 @@ object Wenku8Api: WebBookDataSource {
coroutineScope = CoroutineScope(Dispatchers.IO)
}

override fun getSearchTypeNameList(): List<String> =
override val searchTypeNameList =
listOf("按书名搜索", "按作者名搜索")

override fun getSearchTypeMap(): Map<String, String> =
override val searchTypeMap: Map<String, String> =
mapOf(
Pair("按书名搜索", "articlename"),
Pair("按作者名搜索", "author"),
)

override fun getSearchTipMap(): Map<String, String> =
override val searchTipMap: Map<String, String> =
mapOf(
Pair("articlename", "请输入书本名称"),
Pair("author", "请输入作者名称"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package indi.dmzz_yyhyy.lightnovelreader.zaicomic
package indi.dmzz_yyhyy.lightnovelreader.data.web.zaicomic

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
Expand Down Expand Up @@ -46,7 +46,7 @@ object ZaiComic : WebBookDataSource {
private val comicVolumesCacheMap: MutableMap<Int, BookVolumes> = LimitedMap(10)
private var searchJob: Job? = null

private val isOffLineFlow = flow {
override val isOffLineFlow = flow {
while(true) {
emit(isOffLine())
delay(2500)
Expand All @@ -59,29 +59,23 @@ object ZaiComic : WebBookDataSource {
return this
}

private fun isOffLine(): Boolean {
return try {
override suspend fun isOffLine(): Boolean =
try {
!Jsoup.connect(HOST).get().text().contains("It Works")
} catch (_: Exception) {
true
}
}

override val id: Int
get() = "ZaiComic".hashCode()

override suspend fun getIsOffLineFlow(): Flow<Boolean> { return isOffLineFlow }

/*
GET /app/v1/comic/detail/33322?channel=android&timestamp=1728136936
*/
override fun getBookInformation(id: Int): BookInformation? {
val detailData =
if (comicDetailCacheMap.contains(id))
comicDetailCacheMap[id]
else
Jsoup
.connect(HOST+"/app/v1/comic/detail/$id?channel=android&timestamp=${(System.currentTimeMillis() / 1000)}")
.connect(HOST +"/app/v1/comic/detail/$id?channel=android&timestamp=${(System.currentTimeMillis() / 1000)}")
.ignoreContentType(true)
.get()
.outputSettings(
Expand Down Expand Up @@ -109,7 +103,7 @@ object ZaiComic : WebBookDataSource {
comicDetailCacheMap[id]
else
Jsoup
.connect(HOST+"/app/v1/comic/detail/$id?channel=android&timestamp=${(System.currentTimeMillis() / 1000)}")
.connect(HOST +"/app/v1/comic/detail/$id?channel=android&timestamp=${(System.currentTimeMillis() / 1000)}")
.ignoreContentType(true)
.get()
.outputSettings(
Expand Down Expand Up @@ -156,7 +150,7 @@ object ZaiComic : WebBookDataSource {
if (chapterIdIndex != chapterIds.size - 1) chapterIds[chapterIdIndex + 1]
else -1
val chapterContent = Jsoup
.connect(HOST+"/app/v1/comic/chapter/$bookId/$chapterId?channel=android&timestamp=${(System.currentTimeMillis() / 1000)}")
.connect(HOST +"/app/v1/comic/chapter/$bookId/$chapterId?channel=android&timestamp=${(System.currentTimeMillis() / 1000)}")
.ignoreContentType(true)
.get()
.outputSettings(
Expand All @@ -178,7 +172,7 @@ object ZaiComic : WebBookDataSource {
override suspend fun getExplorationPageMap(): Map<String, ExplorationPageDataSource> =
mapOf()

override suspend fun getExplorationPageTitleList(): List<String> =
override val explorationPageTitleList: List<String> =
listOf()

override fun getExplorationExpandedPageDataSourceMap(): Map<String, ExplorationExpandedPageDataSource> =
Expand Down Expand Up @@ -246,17 +240,17 @@ object ZaiComic : WebBookDataSource {
return comicList
}

override fun getSearchTypeMap(): Map<String, String> =
override val searchTypeMap: Map<String, String> =
mapOf(
"按漫画名称搜索" to "name"
)

override fun getSearchTipMap(): Map<String, String> =
override val searchTipMap: Map<String, String> =
mapOf(
"name" to "请输入漫画名称"
)

override fun getSearchTypeNameList(): List<String> = listOf("按漫画名称搜索")
override val searchTypeNameList: List<String> = listOf("按漫画名称搜索")

override fun stopAllSearch() {
searchJob?.cancel()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ import androidx.compose.ui.unit.dp

@Composable
fun EmptyPage(
modifier: Modifier = Modifier,
painter: Painter,
title: String,
description: String,
button: @Composable () -> Unit = {},
) {
Box(Modifier.fillMaxSize()) {
Box(modifier.fillMaxSize()) {
Column(
modifier = Modifier.align(Alignment.Center),
horizontalAlignment = Alignment.CenterHorizontally
Expand Down
Loading

0 comments on commit b4a0349

Please sign in to comment.