Skip to content
This repository was archived by the owner on Jul 18, 2026. It is now read-only.

Commit 2892668

Browse files
authored
Merge:更新版本号、依赖、增加手动录入cookies功能
更新版本号、依赖、增加手动录入cookies功能
2 parents 1ece996 + fa6f435 commit 2892668

20 files changed

Lines changed: 558 additions & 134 deletions

File tree

app/build.gradle.kts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Config.Version.source
55
import Config.isRelease
66
import Config.lastCommitSha
77
import com.android.build.gradle.internal.api.BaseVariantOutputImpl
8+
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
89

910
plugins {
1011
alias(libs.plugins.com.android.application)
@@ -37,7 +38,7 @@ android {
3738
applicationId = "com.yenaly.han1meviewer"
3839
minSdk = property("min.sdk")?.toString()?.toIntOrNull()
3940
targetSdk = property("target.sdk")?.toString()?.toIntOrNull()
40-
val (code, name) = createVersion(major = 0, minor = 15, patch = 5)
41+
val (code, name) = createVersion(major = 0, minor = 16, patch = 0)
4142
versionCode = code
4243
versionName = name
4344

@@ -94,9 +95,14 @@ android {
9495
sourceCompatibility = JavaVersion.VERSION_21
9596
targetCompatibility = JavaVersion.VERSION_21
9697
}
97-
kotlinOptions {
98-
jvmTarget = JavaVersion.VERSION_21.toString()
99-
freeCompilerArgs = listOf("-opt-in=kotlin.RequiresOptIn", "-Xjvm-default=all-compatibility")
98+
kotlin {
99+
compilerOptions {
100+
jvmTarget.value(JvmTarget.JVM_21)
101+
freeCompilerArgs.addAll(
102+
"-opt-in=kotlin.RequiresOptIn",
103+
"-Xjvm-default=all-compatibility"
104+
)
105+
}
100106
}
101107
lint {
102108
disable += setOf("EnsureInitializerMetadata")
@@ -105,7 +111,7 @@ android {
105111
}
106112

107113
dependencies {
108-
implementation(libs.androidx.appcompat.v161)
114+
implementation(libs.appcompat)
109115
implementation(libs.androidx.window)
110116
implementation(libs.androidx.window.java)
111117
implementation(project(":yenaly_libs"))
@@ -120,17 +126,27 @@ dependencies {
120126
implementation(libs.palette)
121127
implementation(libs.material)
122128
//compose
123-
implementation(platform(libs.compose.compose.bom)) // 引入 BOM 平台
129+
implementation(platform(libs.compose.compose.bom))
124130
implementation(libs.compose.ui.graphics)
125131
implementation(libs.compose.material3)
126132
implementation(libs.androidx.activity.compose)
127133
implementation(libs.compose.ui.ui.tooling.preview)
134+
implementation(libs.androidx.ui)
135+
androidTestImplementation(platform(libs.compose.compose.bom))
136+
androidTestImplementation(libs.androidx.ui.test.junit4)
128137
debugImplementation(libs.compose.ui.ui.tooling)
129138
implementation(libs.androidx.navigation.compose)
130139
implementation(libs.androidx.material.icons.core)
131140
implementation(libs.coil.compose)
132141
implementation(libs.coil.network.okhttp)
133142

143+
//for QRCODE scanner
144+
implementation(libs.androidx.camera.core)
145+
implementation(libs.androidx.camera.camera2)
146+
implementation(libs.androidx.camera.lifecycle)
147+
implementation(libs.androidx.camera.view)
148+
implementation(libs.barcode.scanning)
149+
134150
// datetime
135151

136152
implementation(libs.datetime)
@@ -181,6 +197,7 @@ dependencies {
181197
implementation(libs.firebase.crashlytics)
182198
implementation(libs.firebase.perf)
183199
implementation(libs.firebase.config)
200+
debugImplementation(libs.androidx.ui.test.manifest)
184201

185202
ksp(libs.room.compiler)
186203

app/src/main/AndroidManifest.xml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:tools="http://schemas.android.com/tools">
44

5+
<uses-feature
6+
android:name="android.hardware.camera"
7+
android:required="false" />
8+
59
<uses-permission android:name="android.permission.INTERNET" />
610
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
711
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
812
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
9-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
13+
<uses-permission android:name="android.permission.CAMERA" />
14+
15+
<uses-permission
16+
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
1017
android:maxSdkVersion="28" /> <!-- 兼容旧版系统 -->
11-
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
18+
<uses-permission
19+
android:name="android.permission.READ_EXTERNAL_STORAGE"
1220
android:maxSdkVersion="32" />
1321

14-
1522
<application
1623
android:name=".HanimeApplication"
1724
android:allowBackup="true"
@@ -24,6 +31,11 @@
2431
android:supportsRtl="true"
2532
android:theme="@style/Theme.Hanime1"
2633
tools:targetApi="34">
34+
<activity
35+
android:name=".ui.activity.QRcodeScannerActivity"
36+
android:exported="false"
37+
android:label="@string/title_activity_qrcode_scanner"
38+
android:theme="@style/Theme.Hanime1" />
2739

2840
<service
2941
android:name="androidx.work.impl.foreground.SystemForegroundService"

app/src/main/java/com/yenaly/han1meviewer/logic/Parser.kt

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,9 @@ object Parser {
282282

283283
var likeStatus = parseBody.selectFirst("[name=like-status]")
284284
?.attr("value")
285-
Log.i("likeStatus",likeStatus.toString())
286-
if(!likeStatus.isNullOrEmpty()){
287-
likeStatus= "1"
285+
Log.i("likeStatus", likeStatus.toString())
286+
if (!likeStatus.isNullOrEmpty()) {
287+
likeStatus = "1"
288288
}
289289
val likesCount = parseBody.selectFirst("input[name=likes-count]")
290290
?.attr("value")?.toIntOrNull()
@@ -310,7 +310,7 @@ object Parser {
310310
tagListWithLikeNum.add(child.text())
311311
}
312312
}
313-
val tagList=tagListWithLikeNum.map { it.substringBefore(" (") }
313+
val tagList = tagListWithLikeNum.map { it.substringBefore(" (") }
314314
val myListCheckboxWrapper = parseBody.select("div[class~=playlist-checkbox-wrapper]")
315315
val myListInfo = mutableListOf<HanimeVideo.MyList.MyListInfo>()
316316
myListCheckboxWrapper.forEach {
@@ -336,7 +336,7 @@ object Parser {
336336
val playlistName = it.selectFirst("div > div > h4")?.text()
337337
val playlistScroll = it.getElementById("playlist-scroll")
338338
playlistScroll?.children()?.forEach { parent ->
339-
if (parent.tagName()=="a"){
339+
if (parent.tagName() == "a") {
340340
return@forEach
341341
}
342342
// println("S------------------------------------S")
@@ -388,27 +388,25 @@ object Parser {
388388
?.getElementsByClass("home-rows-videos-div")
389389
?.firstOrNull() != null
390390
if (isSimplified) {
391-
if (children != null) {
392-
for (each in children) {
393-
val eachContent = each.selectFirst("a")
394-
val homeRowsVideosDiv =
395-
eachContent?.getElementsByClass("home-rows-videos-div")?.firstOrNull()
396-
397-
if (homeRowsVideosDiv != null) {
398-
val eachVideoCode = eachContent.absUrl("href").toVideoCode() ?: continue
399-
val eachCoverUrl = homeRowsVideosDiv.selectFirst("img")?.absUrl("src")
400-
.throwIfParseNull(Parser::hanimeVideoVer2.name, "eachCoverUrl")
401-
val eachTitle =
402-
homeRowsVideosDiv.selectFirst("div[class$=title]")?.text()
403-
.throwIfParseNull(Parser::hanimeVideoVer2.name, "eachTitle")
404-
relatedAnimeList.add(
405-
HanimeInfo(
406-
title = eachTitle, coverUrl = eachCoverUrl,
407-
videoCode = eachVideoCode,
408-
itemType = HanimeInfo.SIMPLIFIED
409-
)
391+
for (each in children) {
392+
val eachContent = each.selectFirst("a")
393+
val homeRowsVideosDiv =
394+
eachContent?.getElementsByClass("home-rows-videos-div")?.firstOrNull()
395+
396+
if (homeRowsVideosDiv != null) {
397+
val eachVideoCode = eachContent.absUrl("href").toVideoCode() ?: continue
398+
val eachCoverUrl = homeRowsVideosDiv.selectFirst("img")?.absUrl("src")
399+
.throwIfParseNull(Parser::hanimeVideoVer2.name, "eachCoverUrl")
400+
val eachTitle =
401+
homeRowsVideosDiv.selectFirst("div[class$=title]")?.text()
402+
.throwIfParseNull(Parser::hanimeVideoVer2.name, "eachTitle")
403+
relatedAnimeList.add(
404+
HanimeInfo(
405+
title = eachTitle, coverUrl = eachCoverUrl,
406+
videoCode = eachVideoCode,
407+
itemType = HanimeInfo.SIMPLIFIED
410408
)
411-
}
409+
)
412410
}
413411
}
414412
} else {
@@ -464,7 +462,7 @@ object Parser {
464462
)
465463
} else null
466464
}
467-
val artist = if (artistAvatarUrl != null && artistName != null && artistGenre != null) {
465+
val artist = if (artistName != null && artistGenre != null) {
468466
HanimeVideo.Artist(
469467
name = artistName,
470468
avatarUrl = artistAvatarUrl,
@@ -713,7 +711,7 @@ object Parser {
713711

714712
buildList {
715713
allCommentsClass?.children()?.chunked(5)?.forEach { elements ->
716-
this += Element("div").apply { appendChildren(elements) }
714+
add(Element("div").apply { appendChildren(elements) })
717715
}
718716
}.forEach { child: Element ->
719717
val avatarUrl = child.selectFirst("img")?.absUrl("src")
@@ -878,38 +876,41 @@ object Parser {
878876
artistName = artistName,
879877
avatar = avatarSrc
880878
)
881-
} catch (e: Exception) {
879+
} catch (_: Exception) {
882880
null
883881
}
884882
}
885883

886884
// 解析订阅视频
887885
val videos = subscriptionsVideosRoot.select("div.col-xs-12.search-doujin-videos")
888886
.mapNotNull { videoCard ->
889-
try {
890-
val link = videoCard.selectFirst("a.overlay")?.absUrl("href") ?: return@mapNotNull null
891-
val videoCode = Regex("""watch\?v=(\d+)""").find(link)?.groupValues?.get(1) ?: return@mapNotNull null
892-
val imgs = videoCard.select("img")
893-
val coverUrl = imgs.getOrNull(1)?.absUrl("src") ?: return@mapNotNull null
894-
val title = videoCard.selectFirst("div.card-mobile-title")?.text()?.trim() ?: return@mapNotNull null
895-
val duration = videoCard.selectFirst("div.card-mobile-duration")?.text()?.trim()
896-
val infoBoxes = videoCard.select("div.card-mobile-duration")
897-
.map { it.text().trim() }
898-
val reviews = infoBoxes.find { it.contains("%") }
899-
val views = infoBoxes.find { it.contains("") }
900-
901-
SubscriptionVideosItem(
902-
title = title,
903-
coverUrl = coverUrl,
904-
videoCode = videoCode,
905-
duration = duration,
906-
views = views,
907-
reviews = reviews
908-
)
909-
} catch (e: Exception) {
910-
null
887+
try {
888+
val link =
889+
videoCard.selectFirst("a.overlay")?.absUrl("href") ?: return@mapNotNull null
890+
val videoCode = Regex("""watch\?v=(\d+)""").find(link)?.groupValues?.get(1)
891+
?: return@mapNotNull null
892+
val imgs = videoCard.select("img")
893+
val coverUrl = imgs.getOrNull(1)?.absUrl("src") ?: return@mapNotNull null
894+
val title = videoCard.selectFirst("div.card-mobile-title")?.text()?.trim()
895+
?: return@mapNotNull null
896+
val duration = videoCard.selectFirst("div.card-mobile-duration")?.text()?.trim()
897+
val infoBoxes = videoCard.select("div.card-mobile-duration")
898+
.map { it.text().trim() }
899+
val reviews = infoBoxes.find { it.contains("%") }
900+
val views = infoBoxes.find { it.contains("") }
901+
902+
SubscriptionVideosItem(
903+
title = title,
904+
coverUrl = coverUrl,
905+
videoCode = videoCode,
906+
duration = duration,
907+
views = views,
908+
reviews = reviews
909+
)
910+
} catch (_: Exception) {
911+
null
912+
}
911913
}
912-
}
913914

914915
return WebsiteState.Success(
915916
MySubscriptions(

app/src/main/java/com/yenaly/han1meviewer/logic/state/DownloadState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import androidx.annotation.IntDef
88
* @author Yenaly Liew
99
* @time 2025/3/3 21:11
1010
*/
11-
enum class DownloadState(@Mask val mask: Int) {
11+
enum class DownloadState(@param:Mask val mask: Int) {
1212
// 未知状态(刚添加进来的状态),队列中,下载中,暂停,已完成,失败
1313
Unknown(Mask.UNKNOWN),
1414
Queued(Mask.QUEUED),

0 commit comments

Comments
 (0)