Skip to content

Commit c2892cf

Browse files
committed
Merge branch 'release/v1.4.0'
2 parents e78fac0 + 238f0df commit c2892cf

File tree

86 files changed

+3511
-172
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+3511
-172
lines changed

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ android {
1919

2020
defaultConfig {
2121
applicationId = "com.mrl.pixiv"
22-
versionCode = 10303
23-
versionName = "1.3.3"
22+
versionCode = 10400
23+
versionName = "1.4.0"
2424

2525
vectorDrawables {
2626
useSupportLibrary = true

app/src/main/kotlin/com/mrl/pixiv/App.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import coil3.PlatformContext
66
import coil3.disk.DiskCache
77
import coil3.memory.MemoryCache
88
import com.mrl.pixiv.common.data.setting.setAppCompatDelegateThemeMode
9+
import com.mrl.pixiv.common.repository.BlockingRepositoryV2
910
import com.mrl.pixiv.common.repository.SettingRepository
1011
import com.mrl.pixiv.common.repository.VersionManager
1112
import com.mrl.pixiv.common.util.AppUtil
@@ -48,6 +49,7 @@ class App : Application() {
4849
modules(allModule)
4950
}
5051
migrateDataStoreToMMKV()
52+
migrateBlockingToNewFile()
5153
setAppCompatDelegateThemeMode(SettingRepository.settingTheme)
5254
VersionManager.checkUpdate()
5355
}
@@ -85,6 +87,10 @@ class App : Application() {
8587
awaitAll(search, userPreference, userInfo)
8688
}
8789
}
90+
91+
private fun migrateBlockingToNewFile() {
92+
BlockingRepositoryV2.migrate()
93+
}
8894
}
8995

9096
internal object CoilDiskCache {

app/src/main/kotlin/com/mrl/pixiv/navigation/Navigation3MainGraph.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import com.mrl.pixiv.MainScreen
3333
import com.mrl.pixiv.artwork.ArtworkScreen
3434
import com.mrl.pixiv.collection.CollectionScreen
3535
import com.mrl.pixiv.collection.tags.BookmarkedTagsScreen
36+
import com.mrl.pixiv.comment.BlockCommentsScreen
37+
import com.mrl.pixiv.comment.CommentScreen
3638
import com.mrl.pixiv.common.animation.DefaultFloatAnimationSpec
3739
import com.mrl.pixiv.common.compose.LocalSharedKeyPrefix
3840
import com.mrl.pixiv.common.compose.LocalSharedTransitionScope
@@ -54,6 +56,7 @@ import com.mrl.pixiv.login.oauth.OAuthLoginScreen
5456
import com.mrl.pixiv.picture.HorizontalSwipePictureScreen
5557
import com.mrl.pixiv.picture.PictureDeeplinkScreen
5658
import com.mrl.pixiv.profile.detail.ProfileDetailScreen
59+
import com.mrl.pixiv.report.ReportScreen
5760
import com.mrl.pixiv.search.SearchScreen
5861
import com.mrl.pixiv.search.result.SearchResultsScreen
5962
import com.mrl.pixiv.setting.FileNameFormatScreen
@@ -174,7 +177,7 @@ fun Navigation3MainGraph(
174177
) {
175178
NetworkSettingScreen()
176179
}
177-
180+
178181
// 保存格式设置
179182
entry<Destination.FileNameFormat>(
180183
metadata = ListDetailSceneStrategy.detailPane()
@@ -256,6 +259,9 @@ fun Navigation3MainGraph(
256259
entry<Destination.BlockSettings> {
257260
BlockSettingsScreen()
258261
}
262+
entry<Destination.BlockComments> {
263+
BlockCommentsScreen()
264+
}
259265
entry<Destination.AppData> {
260266
AppDataScreen()
261267
}
@@ -265,6 +271,18 @@ fun Navigation3MainGraph(
265271
entry<Destination.About> {
266272
AboutScreen()
267273
}
274+
entry<Destination.Comment> {
275+
CommentScreen(
276+
id = it.id,
277+
type = it.type,
278+
)
279+
}
280+
entry<Destination.Report> {
281+
ReportScreen(
282+
id = it.id,
283+
type = it.type,
284+
)
285+
}
268286
}
269287
)
270288
}

common/core/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
plugins {
22
id("pixiv.android.library.compose")
33
alias(kotlinx.plugins.serialization)
4-
alias(kotlinx.plugins.ktorfit)
54
alias(kotlinx.plugins.parcelize)
65
}
76

common/core/src/main/kotlin/com/mrl/pixiv/common/mmkv/MMKVConfig.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import kotlinx.serialization.serializer
66

77
interface MMKVOwner {
88
val id: String
9-
val kv: MMKV_KMP
9+
val kv: MMKV_KMP get() = mmkvWithID(id)
1010
}
1111

1212
/**

common/core/src/main/kotlin/com/mrl/pixiv/common/router/Navigation.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ sealed class Destination : NavKey {
9090
@Serializable
9191
data object BlockSettings : Destination()
9292

93+
@Serializable
94+
data object BlockComments : Destination()
95+
9396
@Serializable
9497
data object AppData : Destination()
9598

@@ -98,6 +101,12 @@ sealed class Destination : NavKey {
98101

99102
@Serializable
100103
data object About : Destination()
104+
105+
@Serializable
106+
data class Comment(val id: Long, val type: CommentType) : Destination()
107+
108+
@Serializable
109+
data class Report(val id: Long, val type: ReportType) : Destination()
101110
}
102111

103112
@Serializable
@@ -163,3 +172,18 @@ sealed class MainPage(
163172
}
164173
)
165174
}
175+
176+
@Serializable
177+
enum class CommentType {
178+
ILLUST,
179+
NOVEL,
180+
}
181+
182+
@Serializable
183+
enum class ReportType {
184+
USER,
185+
ILLUST,
186+
NOVEL,
187+
ILLUST_COMMENT,
188+
NOVEL_COMMENT,
189+
}

common/core/src/main/kotlin/com/mrl/pixiv/common/router/NavigationManager.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,12 @@ class NavigationManager(
169169
fun navigateToAboutScreen() {
170170
backStack.navigate(route = Destination.About)
171171
}
172+
173+
fun navigateToCommentScreen(id: Long, type: CommentType) {
174+
backStack.navigate(route = Destination.Comment(id, type))
175+
}
176+
177+
fun navigateToReportCommentScreen(commentId: Long, type: ReportType) {
178+
backStack.navigate(route = Destination.Report(commentId, type))
179+
}
172180
}

common/core/src/main/kotlin/com/mrl/pixiv/common/util/BitmapUtil.kt

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,80 @@ fun isImageExists(fileName: String, type: PictureType, subFolder: String? = null
5252
}
5353
}
5454

55+
/**
56+
* 获取指定文件的下载路径。
57+
*
58+
* 通过提供的文件名、图片类型以及可选的子文件夹,查询对应的文件在系统中的存储路径。
59+
*
60+
* @param fileName 要查询的文件名。
61+
* @param type 图片类型,包含文件的扩展名及相关信息。
62+
* @param subFolder 可选参数,子文件夹路径,如果存在则附加到查询路径中。
63+
* @return 一个 Pair,其中第一个值为路径或文件 URI 的字符串形式,第二个值为实际存储的文件路径;若未找到文件,则返回空字符串。
64+
*/
65+
fun getDownloadPath(
66+
fileName: String,
67+
type: PictureType,
68+
subFolder: String? = null
69+
): Pair<String, String> {
70+
val context = AppUtil.appContext
71+
val projection = arrayOf(MediaStore.Images.Media._ID)
72+
val selection =
73+
"${MediaStore.Images.Media.DISPLAY_NAME} = ? AND ${MediaStore.Images.Media.RELATIVE_PATH} = ?"
74+
val downloadDir = if (subFolder != null) "$DOWNLOAD_DIR$subFolder/" else DOWNLOAD_DIR
75+
val selectionArgs = arrayOf(fileName + type.extension, downloadDir)
76+
val filePath = File(
77+
Environment.getExternalStoragePublicDirectory(""),
78+
"$downloadDir$fileName${type.extension}"
79+
).absolutePath
80+
81+
return try {
82+
context.contentResolver.query(
83+
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
84+
projection,
85+
selection,
86+
selectionArgs,
87+
null
88+
)?.use { cursor ->
89+
if (cursor.moveToFirst()) {
90+
val idIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
91+
val id = cursor.getLong(idIndex)
92+
val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI.buildUpon()
93+
.appendPath(id.toString())
94+
.build()
95+
uri.toString() to filePath
96+
} else {
97+
"" to ""
98+
}
99+
} ?: ("" to "")
100+
} catch (_: Exception) {
101+
"" to ""
102+
}
103+
}
104+
55105
suspend fun saveToAlbum(
56106
bytes: ByteArray,
57107
fileName: String,
58108
mimeType: String?,
59109
subFolder: String? = null,
60-
): Boolean = withContext(Dispatchers.IO) {
110+
): Pair<String, String>? = withContext(Dispatchers.IO) {
61111
val type = when (mimeType?.lowercase()) {
62112
PictureType.PNG.mimeType -> PictureType.PNG
63113
PictureType.JPG.mimeType, PictureType.JPEG.mimeType -> PictureType.JPG
64114
PictureType.GIF.mimeType -> PictureType.GIF
65-
else -> return@withContext false
115+
else -> return@withContext null
66116
}
67117

68118
if (isImageExists(fileName, type, subFolder)) {
69-
return@withContext true
119+
return@withContext getDownloadPath(fileName, type, subFolder)
70120
}
71121

72122
val context = AppUtil.appContext
73123
val contentValues = createContentValues(fileName, type, subFolder)
124+
val downloadDir = if (subFolder != null) "$DOWNLOAD_DIR$subFolder/" else DOWNLOAD_DIR
125+
val filePath = File(
126+
Environment.getExternalStoragePublicDirectory(""),
127+
"$downloadDir$fileName${type.extension}"
128+
).absolutePath
74129

75130
try {
76131
val uri = context.contentResolver.insert(
@@ -81,11 +136,11 @@ suspend fun saveToAlbum(
81136
context.contentResolver.openOutputStream(it)?.use { out ->
82137
out.write(bytes)
83138
}
84-
true
85-
} ?: false
139+
it.toString() to filePath
140+
}
86141
} catch (e: Exception) {
87142
e.printStackTrace()
88-
false
143+
null
89144
}
90145
}
91146

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
package com.mrl.pixiv.common.util
22

3-
import android.content.ContentValues
43
import android.content.Intent
5-
import android.provider.MediaStore
64
import androidx.activity.compose.ManagedActivityResultLauncher
75
import androidx.activity.result.ActivityResult
8-
import coil3.SingletonImageLoader
9-
import coil3.request.ImageRequest
10-
import coil3.toBitmap
11-
import com.mrl.pixiv.common.data.Illust
6+
import androidx.core.net.toUri
127

138
object ShareUtil {
149
fun createShareIntent(text: String): Intent {
@@ -25,48 +20,18 @@ object ShareUtil {
2520
* 如果本地不存在目标文件,则从指定下载地址下载图片保存到本地相册;
2621
* 如果文件已存在,则直接启动分享操作。
2722
*
28-
* @param index 图片索引,用于生成文件名。
29-
* @param downloadUrl 图片下载地址。
30-
* @param illust 插图信息对象,用于获取插图相关数据。
23+
* @param imagePath 图片文件路径。
3124
* @param shareLauncher 用于启动分享操作的Activity结果启动器。
3225
*/
33-
suspend fun createShareImage(
34-
index: Int,
35-
downloadUrl: String,
36-
illust: Illust,
26+
fun createShareImage(
27+
imagePath: String,
3728
shareLauncher: ManagedActivityResultLauncher<Intent, ActivityResult>
3829
) {
39-
val fileName = "${illust.id}_${index}${PictureType.PNG.extension}"
40-
val context = AppUtil.appContext
41-
42-
val contentValues = ContentValues().apply {
43-
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
44-
put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
45-
put(MediaStore.MediaColumns.RELATIVE_PATH, DOWNLOAD_DIR)
46-
}
47-
48-
val uri = context.contentResolver.insert(
49-
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
50-
contentValues
51-
)
52-
if (uri != null) {
53-
val imageLoader = SingletonImageLoader.get(context)
54-
val request = ImageRequest
55-
.Builder(context)
56-
.data(downloadUrl)
57-
.build()
58-
val result = imageLoader.execute(request)
59-
val bitmap = result.image?.toBitmap() ?: return
60-
61-
context.contentResolver.openOutputStream(uri)?.use { outputStream ->
62-
bitmap.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, outputStream)
63-
}
64-
65-
val intent = Intent(Intent.ACTION_SEND)
66-
intent.type = "image/*"
67-
intent.putExtra(Intent.EXTRA_STREAM, uri)
68-
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
69-
shareLauncher.launch(intent)
70-
}
30+
val uri = imagePath.toUri()
31+
val intent = Intent(Intent.ACTION_SEND)
32+
intent.type = "image/*"
33+
intent.putExtra(Intent.EXTRA_STREAM, uri)
34+
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
35+
shareLauncher.launch(intent)
7136
}
7237
}

common/data/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ android {
1010
dependencies {
1111
// Serialization
1212
implementation(kotlinx.bundles.serialization)
13+
implementation(kotlinx.datetime)
1314
}

0 commit comments

Comments
 (0)