Merge pull request #1207 from journey-ad/feature/private-group
新增隐私分组功能
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -73,7 +73,7 @@ val appDb by lazy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
version = 88,
|
version = 89,
|
||||||
exportSchema = true,
|
exportSchema = true,
|
||||||
entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class,
|
entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class,
|
||||||
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
|
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
|
||||||
@@ -128,7 +128,8 @@ val appDb by lazy {
|
|||||||
AutoMigration(from = 84, to = 85),
|
AutoMigration(from = 84, to = 85),
|
||||||
AutoMigration(from = 85, to = 86),
|
AutoMigration(from = 85, to = 86),
|
||||||
AutoMigration(from = 86, to = 87),
|
AutoMigration(from = 86, to = 87),
|
||||||
AutoMigration(from = 87, to = 88)
|
AutoMigration(from = 87, to = 88),
|
||||||
|
AutoMigration(from = 88, to = 89)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|||||||
@@ -22,6 +22,15 @@ data class GroupBookCount(
|
|||||||
val count: Int
|
val count: Int
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private const val PRIVATE_GROUP_MASK =
|
||||||
|
"(SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0 AND isPrivate = 1)"
|
||||||
|
|
||||||
|
private const val PUBLIC_GROUP_MASK =
|
||||||
|
"(SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0 AND isPrivate = 0)"
|
||||||
|
|
||||||
|
private const val PUBLIC_BOOK_FILTER =
|
||||||
|
"(`group` = 0 OR (`group` & $PRIVATE_GROUP_MASK) = 0)"
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface BookDao {
|
interface BookDao {
|
||||||
|
|
||||||
@@ -69,7 +78,8 @@ interface BookDao {
|
|||||||
"""
|
"""
|
||||||
select * from books where type & ${BookType.text} > 0
|
select * from books where type & ${BookType.text} > 0
|
||||||
and type & ${BookType.local} = 0
|
and type & ${BookType.local} = 0
|
||||||
and ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0
|
and ($PUBLIC_GROUP_MASK & `group`) = 0
|
||||||
|
and $PUBLIC_BOOK_FILTER
|
||||||
and (select show from book_groups where groupId = ${BookGroup.IdNetNone}) != 1
|
and (select show from book_groups where groupId = ${BookGroup.IdNetNone}) != 1
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@@ -103,7 +113,8 @@ interface BookDao {
|
|||||||
FROM books
|
FROM books
|
||||||
where type & ${BookType.text} > 0
|
where type & ${BookType.text} > 0
|
||||||
and type & ${BookType.local} = 0
|
and type & ${BookType.local} = 0
|
||||||
and ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0
|
and ($PUBLIC_GROUP_MASK & `group`) = 0
|
||||||
|
and $PUBLIC_BOOK_FILTER
|
||||||
and (select show from book_groups where groupId = ${BookGroup.IdNetNone}) != 1
|
and (select show from book_groups where groupId = ${BookGroup.IdNetNone}) != 1
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@@ -138,6 +149,7 @@ interface BookDao {
|
|||||||
kind,
|
kind,
|
||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
|
WHERE $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@@ -173,6 +185,7 @@ interface BookDao {
|
|||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.audio} > 0
|
WHERE type & ${BookType.audio} > 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfAudio(): Flow<List<BookShelfItem>>
|
fun flowBookShelfAudio(): Flow<List<BookShelfItem>>
|
||||||
@@ -207,6 +220,7 @@ interface BookDao {
|
|||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.local} > 0
|
WHERE type & ${BookType.local} > 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfLocal(): Flow<List<BookShelfItem>>
|
fun flowBookShelfLocal(): Flow<List<BookShelfItem>>
|
||||||
@@ -246,7 +260,8 @@ interface BookDao {
|
|||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
where type & ${BookType.audio} = 0 and type & ${BookType.local} = 0
|
where type & ${BookType.audio} = 0 and type & ${BookType.local} = 0
|
||||||
and ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0
|
and ($PUBLIC_GROUP_MASK & `group`) = 0
|
||||||
|
and $PUBLIC_BOOK_FILTER
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfNetNoGroup(): Flow<List<BookShelfItem>>
|
fun flowBookShelfNetNoGroup(): Flow<List<BookShelfItem>>
|
||||||
@@ -286,7 +301,8 @@ interface BookDao {
|
|||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
where type & ${BookType.local} > 0
|
where type & ${BookType.local} > 0
|
||||||
and ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0
|
and ($PUBLIC_GROUP_MASK & `group`) = 0
|
||||||
|
and $PUBLIC_BOOK_FILTER
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfLocalNoGroup(): Flow<List<BookShelfItem>>
|
fun flowBookShelfLocalNoGroup(): Flow<List<BookShelfItem>>
|
||||||
@@ -321,6 +337,7 @@ interface BookDao {
|
|||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE (`group` & :group) > 0
|
WHERE (`group` & :group) > 0
|
||||||
|
AND ((SELECT isPrivate FROM book_groups WHERE groupId = :group) = 1 OR $PUBLIC_BOOK_FILTER)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfByUserGroup(group: Long): Flow<List<BookShelfItem>>
|
fun flowBookShelfByUserGroup(group: Long): Flow<List<BookShelfItem>>
|
||||||
@@ -356,7 +373,8 @@ interface BookDao {
|
|||||||
kind,
|
kind,
|
||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE name like '%'||:key||'%' or author like '%'||:key||'%' or originName like '%'||:key||'%'
|
WHERE (name like '%'||:key||'%' or author like '%'||:key||'%' or originName like '%'||:key||'%')
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfSearch(key: String): Flow<List<BookShelfItem>>
|
fun flowBookShelfSearch(key: String): Flow<List<BookShelfItem>>
|
||||||
@@ -391,6 +409,7 @@ interface BookDao {
|
|||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
where type & ${BookType.updateError} > 0
|
where type & ${BookType.updateError} > 0
|
||||||
|
and $PUBLIC_BOOK_FILTER
|
||||||
order by durChapterTime desc
|
order by durChapterTime desc
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@@ -426,6 +445,7 @@ interface BookDao {
|
|||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE durChapterIndex = 0 AND durChapterPos = 0
|
WHERE durChapterIndex = 0 AND durChapterPos = 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfUnread(): Flow<List<BookShelfItem>>
|
fun flowBookShelfUnread(): Flow<List<BookShelfItem>>
|
||||||
@@ -460,6 +480,7 @@ interface BookDao {
|
|||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1
|
WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfReadFinished(): Flow<List<BookShelfItem>>
|
fun flowBookShelfReadFinished(): Flow<List<BookShelfItem>>
|
||||||
@@ -494,6 +515,7 @@ interface BookDao {
|
|||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE totalChapterNum > 0 AND durChapterIndex > 0 AND durChapterIndex < totalChapterNum - 1
|
WHERE totalChapterNum > 0 AND durChapterIndex > 0 AND durChapterIndex < totalChapterNum - 1
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfReading(): Flow<List<BookShelfItem>>
|
fun flowBookShelfReading(): Flow<List<BookShelfItem>>
|
||||||
@@ -528,6 +550,7 @@ interface BookDao {
|
|||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.image} > 0
|
WHERE type & ${BookType.image} > 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfManga(): Flow<List<BookShelfItem>>
|
fun flowBookShelfManga(): Flow<List<BookShelfItem>>
|
||||||
@@ -562,6 +585,7 @@ interface BookDao {
|
|||||||
wordCount
|
wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.text} > 0
|
WHERE type & ${BookType.text} > 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowBookShelfText(): Flow<List<BookShelfItem>>
|
fun flowBookShelfText(): Flow<List<BookShelfItem>>
|
||||||
@@ -677,35 +701,44 @@ interface BookDao {
|
|||||||
|
|
||||||
// ── Group preview / count queries (DB-level, replaces in-memory buildGroupPreviewState) ──
|
// ── Group preview / count queries (DB-level, replaces in-memory buildGroupPreviewState) ──
|
||||||
|
|
||||||
@Query("SELECT COUNT(*) FROM books")
|
@Query("SELECT COUNT(*) FROM books WHERE $PUBLIC_BOOK_FILTER")
|
||||||
fun flowAllBookShelfCount(): Flow<Int>
|
fun flowAllBookShelfCount(): Flow<Int>
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""
|
"""
|
||||||
SELECT ${BookGroup.IdAll} AS groupId, COUNT(*) AS count FROM books
|
SELECT ${BookGroup.IdAll} AS groupId, COUNT(*) AS count FROM books WHERE $PUBLIC_BOOK_FILTER
|
||||||
UNION ALL SELECT ${BookGroup.IdRoot}, COUNT(*) FROM books
|
UNION ALL SELECT ${BookGroup.IdRoot}, COUNT(*) FROM books
|
||||||
WHERE type & ${BookType.text} > 0 AND type & ${BookType.local} = 0
|
WHERE type & ${BookType.text} > 0 AND type & ${BookType.local} = 0
|
||||||
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
AND ($PUBLIC_GROUP_MASK & `group`) = 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
AND (SELECT show FROM book_groups WHERE groupId = ${BookGroup.IdNetNone}) != 1
|
AND (SELECT show FROM book_groups WHERE groupId = ${BookGroup.IdNetNone}) != 1
|
||||||
UNION ALL SELECT ${BookGroup.IdLocal}, COUNT(*) FROM books WHERE type & ${BookType.local} > 0
|
UNION ALL SELECT ${BookGroup.IdLocal}, COUNT(*) FROM books WHERE type & ${BookType.local} > 0 AND $PUBLIC_BOOK_FILTER
|
||||||
UNION ALL SELECT ${BookGroup.IdAudio}, COUNT(*) FROM books WHERE type & ${BookType.audio} > 0
|
UNION ALL SELECT ${BookGroup.IdAudio}, COUNT(*) FROM books WHERE type & ${BookType.audio} > 0 AND $PUBLIC_BOOK_FILTER
|
||||||
UNION ALL SELECT ${BookGroup.IdNetNone}, COUNT(*) FROM books
|
UNION ALL SELECT ${BookGroup.IdNetNone}, COUNT(*) FROM books
|
||||||
WHERE type & ${BookType.audio} = 0 AND type & ${BookType.local} = 0
|
WHERE type & ${BookType.audio} = 0 AND type & ${BookType.local} = 0
|
||||||
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
AND ($PUBLIC_GROUP_MASK & `group`) = 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
UNION ALL SELECT ${BookGroup.IdLocalNone}, COUNT(*) FROM books
|
UNION ALL SELECT ${BookGroup.IdLocalNone}, COUNT(*) FROM books
|
||||||
WHERE type & ${BookType.local} > 0
|
WHERE type & ${BookType.local} > 0
|
||||||
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
AND ($PUBLIC_GROUP_MASK & `group`) = 0
|
||||||
UNION ALL SELECT ${BookGroup.IdManga}, COUNT(*) FROM books WHERE type & ${BookType.image} > 0
|
AND $PUBLIC_BOOK_FILTER
|
||||||
UNION ALL SELECT ${BookGroup.IdText}, COUNT(*) FROM books WHERE type & ${BookType.text} > 0
|
UNION ALL SELECT ${BookGroup.IdManga}, COUNT(*) FROM books WHERE type & ${BookType.image} > 0 AND $PUBLIC_BOOK_FILTER
|
||||||
UNION ALL SELECT ${BookGroup.IdError}, COUNT(*) FROM books WHERE type & ${BookType.updateError} > 0
|
UNION ALL SELECT ${BookGroup.IdText}, COUNT(*) FROM books WHERE type & ${BookType.text} > 0 AND $PUBLIC_BOOK_FILTER
|
||||||
UNION ALL SELECT ${BookGroup.IdUnread}, COUNT(*) FROM books WHERE durChapterIndex = 0 AND durChapterPos = 0
|
UNION ALL SELECT ${BookGroup.IdError}, COUNT(*) FROM books WHERE type & ${BookType.updateError} > 0 AND $PUBLIC_BOOK_FILTER
|
||||||
UNION ALL SELECT ${BookGroup.IdReading}, COUNT(*) FROM books WHERE totalChapterNum > 0 AND durChapterIndex > 0 AND durChapterIndex < totalChapterNum - 1
|
UNION ALL SELECT ${BookGroup.IdUnread}, COUNT(*) FROM books WHERE durChapterIndex = 0 AND durChapterPos = 0 AND $PUBLIC_BOOK_FILTER
|
||||||
UNION ALL SELECT ${BookGroup.IdReadFinished}, COUNT(*) FROM books WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1
|
UNION ALL SELECT ${BookGroup.IdReading}, COUNT(*) FROM books WHERE totalChapterNum > 0 AND durChapterIndex > 0 AND durChapterIndex < totalChapterNum - 1 AND $PUBLIC_BOOK_FILTER
|
||||||
|
UNION ALL SELECT ${BookGroup.IdReadFinished}, COUNT(*) FROM books WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1 AND $PUBLIC_BOOK_FILTER
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun flowSystemGroupCounts(): Flow<List<GroupBookCount>>
|
fun flowSystemGroupCounts(): Flow<List<GroupBookCount>>
|
||||||
|
|
||||||
@Query("SELECT COUNT(*) FROM books WHERE (`group` & :groupId) > 0")
|
@Query(
|
||||||
|
"""
|
||||||
|
SELECT COUNT(*) FROM books
|
||||||
|
WHERE (`group` & :groupId) > 0
|
||||||
|
AND ((SELECT isPrivate FROM book_groups WHERE groupId = :groupId) = 1 OR $PUBLIC_BOOK_FILTER)
|
||||||
|
"""
|
||||||
|
)
|
||||||
fun flowUserGroupBookCount(groupId: Long): Flow<Int>
|
fun flowUserGroupBookCount(groupId: Long): Flow<Int>
|
||||||
|
|
||||||
fun flowGroupPreview(groupId: Long): Flow<List<BookShelfItem>> {
|
fun flowGroupPreview(groupId: Long): Flow<List<BookShelfItem>> {
|
||||||
@@ -737,6 +770,7 @@ interface BookDao {
|
|||||||
type, `group`, `order`, canUpdate,
|
type, `group`, `order`, canUpdate,
|
||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
|
WHERE $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
@@ -753,7 +787,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.text} > 0 AND type & ${BookType.local} = 0
|
WHERE type & ${BookType.text} > 0 AND type & ${BookType.local} = 0
|
||||||
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
AND ($PUBLIC_GROUP_MASK & `group`) = 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
AND (SELECT show FROM book_groups WHERE groupId = ${BookGroup.IdNetNone}) != 1
|
AND (SELECT show FROM book_groups WHERE groupId = ${BookGroup.IdNetNone}) != 1
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
@@ -771,6 +806,7 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.local} > 0
|
WHERE type & ${BookType.local} > 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
@@ -787,6 +823,7 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.audio} > 0
|
WHERE type & ${BookType.audio} > 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
@@ -803,7 +840,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.audio} = 0 AND type & ${BookType.local} = 0
|
WHERE type & ${BookType.audio} = 0 AND type & ${BookType.local} = 0
|
||||||
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
AND ($PUBLIC_GROUP_MASK & `group`) = 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
@@ -820,7 +858,8 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.local} > 0
|
WHERE type & ${BookType.local} > 0
|
||||||
AND ((SELECT COALESCE(SUM(groupId), 0) FROM book_groups WHERE groupId > 0) & `group`) = 0
|
AND ($PUBLIC_GROUP_MASK & `group`) = 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
@@ -837,6 +876,7 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.image} > 0
|
WHERE type & ${BookType.image} > 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
@@ -853,6 +893,7 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.text} > 0
|
WHERE type & ${BookType.text} > 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
@@ -869,6 +910,7 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE type & ${BookType.updateError} > 0
|
WHERE type & ${BookType.updateError} > 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
@@ -885,6 +927,7 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE durChapterIndex = 0 AND durChapterPos = 0
|
WHERE durChapterIndex = 0 AND durChapterPos = 0
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
@@ -901,6 +944,7 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE totalChapterNum > 0 AND durChapterIndex > 0 AND durChapterIndex < totalChapterNum - 1
|
WHERE totalChapterNum > 0 AND durChapterIndex > 0 AND durChapterIndex < totalChapterNum - 1
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
@@ -917,6 +961,7 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1
|
WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1
|
||||||
|
AND $PUBLIC_BOOK_FILTER
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
@@ -933,6 +978,7 @@ interface BookDao {
|
|||||||
ifnull(customIntro, intro) as intro, kind, wordCount
|
ifnull(customIntro, intro) as intro, kind, wordCount
|
||||||
FROM books
|
FROM books
|
||||||
WHERE (`group` & :groupId) > 0
|
WHERE (`group` & :groupId) > 0
|
||||||
|
AND ((SELECT isPrivate FROM book_groups WHERE groupId = :groupId) = 1 OR $PUBLIC_BOOK_FILTER)
|
||||||
ORDER BY durChapterTime DESC
|
ORDER BY durChapterTime DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -25,42 +25,75 @@ interface BookGroupDao {
|
|||||||
|
|
||||||
@get:Query(
|
@get:Query(
|
||||||
"""
|
"""
|
||||||
with const as (SELECT sum(groupId) sumGroupId FROM book_groups where groupId > 0)
|
with const as (
|
||||||
|
SELECT
|
||||||
|
COALESCE(SUM(CASE WHEN groupId > 0 AND isPrivate = 0 THEN groupId ELSE 0 END), 0) sumPublicGroupId,
|
||||||
|
COALESCE(SUM(CASE WHEN groupId > 0 AND isPrivate = 1 THEN groupId ELSE 0 END), 0) sumPrivateGroupId
|
||||||
|
FROM book_groups
|
||||||
|
)
|
||||||
SELECT book_groups.* FROM book_groups join const
|
SELECT book_groups.* FROM book_groups join const
|
||||||
where show > 0
|
where show > 0
|
||||||
and (
|
and (
|
||||||
(groupId >= 0 and exists (select 1 from books where `group` & book_groups.groupId > 0))
|
(groupId >= 0 and exists (
|
||||||
|
select 1 from books
|
||||||
|
where `group` & book_groups.groupId > 0
|
||||||
|
and (book_groups.isPrivate = 1 or `group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
|
||||||
|
))
|
||||||
or groupId = ${BookGroup.IdAll}
|
or groupId = ${BookGroup.IdAll}
|
||||||
or (groupId = ${BookGroup.IdLocal} and exists (select 1 from books where type & ${BookType.local} > 0))
|
or (groupId = ${BookGroup.IdLocal} and exists (
|
||||||
or (groupId = ${BookGroup.IdAudio} and exists (select 1 from books where type & ${BookType.audio} > 0))
|
select 1 from books
|
||||||
or (groupId = ${BookGroup.IdManga} and exists (select 1 FROM books where type & ${BookType.image} > 0))
|
where type & ${BookType.local} > 0
|
||||||
or (groupId = ${BookGroup.IdText} and exists (select 1 FROM books where type & ${BookType.text} > 0))
|
and (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
|
||||||
|
))
|
||||||
|
or (groupId = ${BookGroup.IdAudio} and exists (
|
||||||
|
select 1 from books
|
||||||
|
where type & ${BookType.audio} > 0
|
||||||
|
and (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
|
||||||
|
))
|
||||||
|
or (groupId = ${BookGroup.IdManga} and exists (
|
||||||
|
select 1 FROM books
|
||||||
|
where type & ${BookType.image} > 0
|
||||||
|
and (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
|
||||||
|
))
|
||||||
|
or (groupId = ${BookGroup.IdText} and exists (
|
||||||
|
select 1 FROM books
|
||||||
|
where type & ${BookType.text} > 0
|
||||||
|
and (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
|
||||||
|
))
|
||||||
or (groupId = ${BookGroup.IdReading} and exists (
|
or (groupId = ${BookGroup.IdReading} and exists (
|
||||||
SELECT 1 FROM books
|
SELECT 1 FROM books
|
||||||
WHERE totalChapterNum > 0
|
WHERE totalChapterNum > 0
|
||||||
AND durChapterIndex > 0
|
AND durChapterIndex > 0
|
||||||
AND durChapterIndex < totalChapterNum - 1
|
AND durChapterIndex < totalChapterNum - 1
|
||||||
|
AND (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
|
||||||
))
|
))
|
||||||
or (groupId = ${BookGroup.IdUnread} and exists (
|
or (groupId = ${BookGroup.IdUnread} and exists (
|
||||||
SELECT 1 FROM books
|
SELECT 1 FROM books
|
||||||
WHERE durChapterIndex = 0
|
WHERE durChapterIndex = 0
|
||||||
AND durChapterPos = 0
|
AND durChapterPos = 0
|
||||||
|
AND (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
|
||||||
))
|
))
|
||||||
or (groupId = ${BookGroup.IdReadFinished} and exists (
|
or (groupId = ${BookGroup.IdReadFinished} and exists (
|
||||||
SELECT 1 FROM books
|
SELECT 1 FROM books
|
||||||
WHERE totalChapterNum > 0
|
WHERE totalChapterNum > 0
|
||||||
AND durChapterIndex >= totalChapterNum - 1
|
AND durChapterIndex >= totalChapterNum - 1
|
||||||
AND durChapterPos != 0
|
AND durChapterPos != 0
|
||||||
|
AND (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
|
||||||
))
|
))
|
||||||
|
|
||||||
or (groupId = ${BookGroup.IdError} and exists (select 1 from books where type & ${BookType.updateError} > 0))
|
or (groupId = ${BookGroup.IdError} and exists (
|
||||||
|
select 1 from books
|
||||||
|
where type & ${BookType.updateError} > 0
|
||||||
|
and (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
|
||||||
|
))
|
||||||
|
|
||||||
or (groupId = ${BookGroup.IdNetNone}
|
or (groupId = ${BookGroup.IdNetNone}
|
||||||
and exists (
|
and exists (
|
||||||
select 1 from books
|
select 1 from books
|
||||||
where type & ${BookType.audio} = 0
|
where type & ${BookType.audio} = 0
|
||||||
and type & ${BookType.local} = 0
|
and type & ${BookType.local} = 0
|
||||||
and const.sumGroupId & `group` = 0
|
and (const.sumPublicGroupId & `group`) = 0
|
||||||
|
and (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
or (groupId = ${BookGroup.IdLocalNone}
|
or (groupId = ${BookGroup.IdLocalNone}
|
||||||
@@ -68,7 +101,8 @@ interface BookGroupDao {
|
|||||||
select 1 from books
|
select 1 from books
|
||||||
where type & ${BookType.audio} = 0
|
where type & ${BookType.audio} = 0
|
||||||
and type & ${BookType.local} > 0
|
and type & ${BookType.local} > 0
|
||||||
and const.sumGroupId & `group` = 0
|
and (const.sumPublicGroupId & `group`) = 0
|
||||||
|
and (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ data class BookGroup(
|
|||||||
@ColumnInfo(defaultValue = "1")
|
@ColumnInfo(defaultValue = "1")
|
||||||
var show: Boolean = true,
|
var show: Boolean = true,
|
||||||
@ColumnInfo(defaultValue = "-1")
|
@ColumnInfo(defaultValue = "-1")
|
||||||
var bookSort: Int = -1
|
var bookSort: Int = -1,
|
||||||
|
@ColumnInfo(defaultValue = "0")
|
||||||
|
var isPrivate: Boolean = false
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -83,6 +85,7 @@ data class BookGroup(
|
|||||||
&& other.enableRefresh == enableRefresh
|
&& other.enableRefresh == enableRefresh
|
||||||
&& other.show == show
|
&& other.show == show
|
||||||
&& other.order == order
|
&& other.order == order
|
||||||
|
&& other.isPrivate == isPrivate
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,11 @@ class GroupEditDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_book_gro
|
|||||||
binding.ivCover.load(group.cover)
|
binding.ivCover.load(group.cover)
|
||||||
}
|
}
|
||||||
binding.cbEnableRefresh.isChecked = group.enableRefresh
|
binding.cbEnableRefresh.isChecked = group.enableRefresh
|
||||||
|
binding.cbPrivate.isChecked = group.isPrivate
|
||||||
|
if (group.groupId <= 0) {
|
||||||
|
binding.cbPrivate.gone()
|
||||||
|
binding.tvPrivateDesc.gone()
|
||||||
|
}
|
||||||
|
|
||||||
selectedSortIndex = group.bookSort
|
selectedSortIndex = group.bookSort
|
||||||
val displayIndex = selectedSortIndex + 1
|
val displayIndex = selectedSortIndex + 1
|
||||||
@@ -103,6 +108,17 @@ class GroupEditDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_book_gro
|
|||||||
selectedSortIndex = position - 1
|
selectedSortIndex = position - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.cbPrivate.setOnCheckedChangeListener { buttonView, isChecked ->
|
||||||
|
if (!isChecked && bookGroup?.isPrivate == true) {
|
||||||
|
alert(R.string.disable_private_group, R.string.sure_disable_private_group) {
|
||||||
|
yesButton()
|
||||||
|
noButton {
|
||||||
|
buttonView.isChecked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding.run {
|
binding.run {
|
||||||
ivCover.onClick {
|
ivCover.onClick {
|
||||||
selectImage.launch()
|
selectImage.launch()
|
||||||
@@ -128,11 +144,13 @@ class GroupEditDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_book_gro
|
|||||||
val bookSort = selectedSortIndex
|
val bookSort = selectedSortIndex
|
||||||
val coverPath = binding.ivCover.bitmapPath
|
val coverPath = binding.ivCover.bitmapPath
|
||||||
val enableRefresh = binding.cbEnableRefresh.isChecked
|
val enableRefresh = binding.cbEnableRefresh.isChecked
|
||||||
|
val isPrivate = binding.cbPrivate.isChecked
|
||||||
bookGroup?.let {
|
bookGroup?.let {
|
||||||
it.groupName = groupName
|
it.groupName = groupName
|
||||||
it.cover = coverPath
|
it.cover = coverPath
|
||||||
it.bookSort = bookSort
|
it.bookSort = bookSort
|
||||||
it.enableRefresh = enableRefresh
|
it.enableRefresh = enableRefresh
|
||||||
|
it.isPrivate = isPrivate
|
||||||
viewModel.upGroup(it) {
|
viewModel.upGroup(it) {
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
@@ -141,6 +159,7 @@ class GroupEditDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_book_gro
|
|||||||
groupName,
|
groupName,
|
||||||
bookSort,
|
bookSort,
|
||||||
enableRefresh,
|
enableRefresh,
|
||||||
|
isPrivate,
|
||||||
coverPath
|
coverPath
|
||||||
) {
|
) {
|
||||||
dismiss()
|
dismiss()
|
||||||
@@ -163,7 +182,12 @@ class GroupEditDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_book_gro
|
|||||||
|
|
||||||
|
|
||||||
private fun deleteGroup(ok: () -> Unit) {
|
private fun deleteGroup(ok: () -> Unit) {
|
||||||
alert(R.string.delete, R.string.sure_del) {
|
val message = if (bookGroup?.isPrivate == true) {
|
||||||
|
R.string.sure_del_private_group
|
||||||
|
} else {
|
||||||
|
R.string.sure_del
|
||||||
|
}
|
||||||
|
alert(R.string.delete, message) {
|
||||||
yesButton {
|
yesButton {
|
||||||
ok.invoke()
|
ok.invoke()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,12 +103,15 @@ fun GroupEditContent(
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
var groupName by remember(group) { mutableStateOf(group?.groupName ?: "") }
|
var groupName by remember(group) { mutableStateOf(group?.groupName ?: "") }
|
||||||
var enableRefresh by remember(group) { mutableStateOf(group?.enableRefresh ?: true) }
|
var enableRefresh by remember(group) { mutableStateOf(group?.enableRefresh ?: true) }
|
||||||
|
var isPrivate by remember(group) { mutableStateOf(group?.isPrivate ?: false) }
|
||||||
|
var showDisablePrivateDialog by remember(group) { mutableStateOf(false) }
|
||||||
var selectedSortIndex by remember(group) { mutableIntStateOf(group?.bookSort ?: -1) }
|
var selectedSortIndex by remember(group) { mutableIntStateOf(group?.bookSort ?: -1) }
|
||||||
|
|
||||||
val sortOptions = stringArrayResource(R.array.book_sort)
|
val sortOptions = stringArrayResource(R.array.book_sort)
|
||||||
val sortEntryValues = remember(sortOptions) {
|
val sortEntryValues = remember(sortOptions) {
|
||||||
Array(sortOptions.size) { (it - 1).toString() }
|
Array(sortOptions.size) { (it - 1).toString() }
|
||||||
}
|
}
|
||||||
|
val canSetPrivate = group == null || group.groupId > 0
|
||||||
|
|
||||||
val selectImage = rememberLauncherForActivityResult(SelectImageContract()) { result ->
|
val selectImage = rememberLauncherForActivityResult(SelectImageContract()) { result ->
|
||||||
result.uri?.let { uri ->
|
result.uri?.let { uri ->
|
||||||
@@ -190,6 +193,23 @@ fun GroupEditContent(
|
|||||||
onCheckedChange = { enableRefresh = it }
|
onCheckedChange = { enableRefresh = it }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (canSetPrivate) {
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
CompactSwitchSettingItem(
|
||||||
|
title = stringResource(R.string.private_group),
|
||||||
|
description = stringResource(R.string.private_group_desc),
|
||||||
|
checked = isPrivate,
|
||||||
|
onCheckedChange = { checked ->
|
||||||
|
if (!checked && group?.isPrivate == true) {
|
||||||
|
showDisablePrivateDialog = true
|
||||||
|
} else {
|
||||||
|
isPrivate = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
ConfirmDismissButtonsRow(
|
ConfirmDismissButtonsRow(
|
||||||
@@ -199,13 +219,14 @@ fun GroupEditContent(
|
|||||||
if (groupName.isEmpty()) {
|
if (groupName.isEmpty()) {
|
||||||
appCtx.toastOnUi("分组名称不能为空")
|
appCtx.toastOnUi("分组名称不能为空")
|
||||||
} else {
|
} else {
|
||||||
if (group != null && group.groupId != 0b1L) {
|
if (group != null) {
|
||||||
viewModel.upGroup(
|
viewModel.upGroup(
|
||||||
group.copy(
|
group.copy(
|
||||||
groupName = groupName,
|
groupName = groupName,
|
||||||
cover = coverPath,
|
cover = coverPath,
|
||||||
bookSort = selectedSortIndex,
|
bookSort = selectedSortIndex,
|
||||||
enableRefresh = enableRefresh
|
enableRefresh = enableRefresh,
|
||||||
|
isPrivate = isPrivate
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
onDismissRequest()
|
onDismissRequest()
|
||||||
@@ -215,6 +236,7 @@ fun GroupEditContent(
|
|||||||
groupName,
|
groupName,
|
||||||
selectedSortIndex,
|
selectedSortIndex,
|
||||||
enableRefresh,
|
enableRefresh,
|
||||||
|
isPrivate,
|
||||||
coverPath
|
coverPath
|
||||||
) {
|
) {
|
||||||
onDismissRequest()
|
onDismissRequest()
|
||||||
@@ -226,6 +248,20 @@ fun GroupEditContent(
|
|||||||
confirmText = stringResource(R.string.ok)
|
confirmText = stringResource(R.string.ok)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppAlertDialog(
|
||||||
|
show = showDisablePrivateDialog,
|
||||||
|
onDismissRequest = { showDisablePrivateDialog = false },
|
||||||
|
title = stringResource(R.string.disable_private_group),
|
||||||
|
text = stringResource(R.string.sure_disable_private_group),
|
||||||
|
confirmText = stringResource(android.R.string.ok),
|
||||||
|
onConfirm = {
|
||||||
|
isPrivate = false
|
||||||
|
showDisablePrivateDialog = false
|
||||||
|
},
|
||||||
|
dismissText = stringResource(android.R.string.cancel),
|
||||||
|
onDismiss = { showDisablePrivateDialog = false }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -247,7 +283,9 @@ fun GroupDeleteAction(
|
|||||||
show = showDeleteDialog,
|
show = showDeleteDialog,
|
||||||
onDismissRequest = { showDeleteDialog = false },
|
onDismissRequest = { showDeleteDialog = false },
|
||||||
title = stringResource(R.string.delete),
|
title = stringResource(R.string.delete),
|
||||||
text = stringResource(R.string.sure_del),
|
text = stringResource(
|
||||||
|
if (group.isPrivate) R.string.sure_del_private_group else R.string.sure_del
|
||||||
|
),
|
||||||
confirmText = stringResource(android.R.string.ok),
|
confirmText = stringResource(android.R.string.ok),
|
||||||
onConfirm = {
|
onConfirm = {
|
||||||
showDeleteDialog = false
|
showDeleteDialog = false
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class GroupViewModel(
|
|||||||
groupName: String,
|
groupName: String,
|
||||||
bookSort: Int,
|
bookSort: Int,
|
||||||
enableRefresh: Boolean,
|
enableRefresh: Boolean,
|
||||||
|
isPrivate: Boolean,
|
||||||
cover: String?,
|
cover: String?,
|
||||||
finally: () -> Unit
|
finally: () -> Unit
|
||||||
) {
|
) {
|
||||||
@@ -35,6 +36,7 @@ class GroupViewModel(
|
|||||||
cover = cover,
|
cover = cover,
|
||||||
bookSort = bookSort,
|
bookSort = bookSort,
|
||||||
enableRefresh = enableRefresh,
|
enableRefresh = enableRefresh,
|
||||||
|
isPrivate = isPrivate,
|
||||||
order = bookGroupRepository.getMaxOrder().plus(1)
|
order = bookGroupRepository.getMaxOrder().plus(1)
|
||||||
)
|
)
|
||||||
bookGroupRepository.getByID(groupId) ?: removeBookGroupAssignmentUseCase.execute(groupId)
|
bookGroupRepository.getByID(groupId) ?: removeBookGroupAssignmentUseCase.execute(groupId)
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ fun GroupSelectSheet(
|
|||||||
) {
|
) {
|
||||||
var selectedGroupId by remember(currentGroupId, show) { mutableLongStateOf(currentGroupId) }
|
var selectedGroupId by remember(currentGroupId, show) { mutableLongStateOf(currentGroupId) }
|
||||||
var editingGroup by remember(show) { mutableStateOf<BookGroup?>(null) }
|
var editingGroup by remember(show) { mutableStateOf<BookGroup?>(null) }
|
||||||
|
var showAddGroup by remember(show) { mutableStateOf(false) }
|
||||||
|
|
||||||
AppModalBottomSheet(
|
AppModalBottomSheet(
|
||||||
show = show,
|
show = show,
|
||||||
@@ -145,7 +146,7 @@ fun GroupSelectSheet(
|
|||||||
title = stringResource(R.string.group_select),
|
title = stringResource(R.string.group_select),
|
||||||
startAction = {
|
startAction = {
|
||||||
MediumPlainButton(
|
MediumPlainButton(
|
||||||
onClick = { editingGroup = BookGroup() },
|
onClick = { showAddGroup = true },
|
||||||
icon = Icons.Default.Add
|
icon = Icons.Default.Add
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@@ -198,7 +199,14 @@ fun GroupSelectSheet(
|
|||||||
Spacer(modifier = Modifier.height(12.dp))
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GroupEditSheet(show = editingGroup != null, group = editingGroup, onDismissRequest = { editingGroup = null })
|
GroupEditSheet(
|
||||||
|
show = showAddGroup || editingGroup != null,
|
||||||
|
group = editingGroup,
|
||||||
|
onDismissRequest = {
|
||||||
|
showAddGroup = false
|
||||||
|
editingGroup = null
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@@ -648,4 +656,3 @@ fun ChangeSourceSheet(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ data class BookGroupUi(
|
|||||||
val order: Int,
|
val order: Int,
|
||||||
val enableRefresh: Boolean,
|
val enableRefresh: Boolean,
|
||||||
val show: Boolean,
|
val show: Boolean,
|
||||||
val bookSort: Int
|
val bookSort: Int,
|
||||||
|
val isPrivate: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
fun BookGroup.toBookGroupUi() = BookGroupUi(
|
fun BookGroup.toBookGroupUi() = BookGroupUi(
|
||||||
@@ -21,5 +22,6 @@ fun BookGroup.toBookGroupUi() = BookGroupUi(
|
|||||||
order = order,
|
order = order,
|
||||||
enableRefresh = enableRefresh,
|
enableRefresh = enableRefresh,
|
||||||
show = show,
|
show = show,
|
||||||
bookSort = bookSort
|
bookSort = bookSort,
|
||||||
|
isPrivate = isPrivate
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -103,6 +103,25 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/iv_cover" />
|
app:layout_constraintTop_toBottomOf="@id/iv_cover" />
|
||||||
|
|
||||||
|
<com.google.android.material.materialswitch.MaterialSwitch
|
||||||
|
android:id="@+id/cb_private"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/private_group"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/cb_enable_refresh" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_private_desc"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/private_group_desc"
|
||||||
|
android:textAppearance="?attr/textAppearanceBodySmall"
|
||||||
|
android:textColor="?attr/colorOnSurfaceVariant"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/cb_private"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/cb_private" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -570,6 +570,8 @@
|
|||||||
<string name="no">否</string>
|
<string name="no">否</string>
|
||||||
<string name="sure">确认</string>
|
<string name="sure">确认</string>
|
||||||
<string name="sure_del">是否确认删除?</string>
|
<string name="sure_del">是否确认删除?</string>
|
||||||
|
<string name="sure_del_private_group">删除后,相关书籍可能在公开书架中显示,是否确认删除?</string>
|
||||||
|
<string name="sure_disable_private_group">关闭后,本组书籍可能在公开书架中显示,是否确认关闭?</string>
|
||||||
<string name="sure_del_any">是否确认删除 %s ?</string>
|
<string name="sure_del_any">是否确认删除 %s ?</string>
|
||||||
<string name="sure_del_all_book">是否删除全部书籍?</string>
|
<string name="sure_del_all_book">是否删除全部书籍?</string>
|
||||||
<string name="sure_del_download_book">是否同时删除已下载的书籍目录?</string>
|
<string name="sure_del_download_book">是否同时删除已下载的书籍目录?</string>
|
||||||
@@ -1207,6 +1209,9 @@
|
|||||||
<string name="file_manage_summary">管理私有文件夹的文件</string>
|
<string name="file_manage_summary">管理私有文件夹的文件</string>
|
||||||
<string name="create_folder">创建文件夹</string>
|
<string name="create_folder">创建文件夹</string>
|
||||||
<string name="allow_drop_down_refresh">允许下拉刷新</string>
|
<string name="allow_drop_down_refresh">允许下拉刷新</string>
|
||||||
|
<string name="private_group">设为隐私分组</string>
|
||||||
|
<string name="disable_private_group">关闭隐私分组</string>
|
||||||
|
<string name="private_group_desc">开启后,本分组内的书籍将从公开书架隐藏</string>
|
||||||
<string name="text_underline">文字下划线</string>
|
<string name="text_underline">文字下划线</string>
|
||||||
<string name="select_new_source">选中新增源</string>
|
<string name="select_new_source">选中新增源</string>
|
||||||
<string name="select_update_source">选中更新源</string>
|
<string name="select_update_source">选中更新源</string>
|
||||||
|
|||||||
@@ -508,6 +508,8 @@
|
|||||||
<string name="no">唔係</string>
|
<string name="no">唔係</string>
|
||||||
<string name="sure">確認</string>
|
<string name="sure">確認</string>
|
||||||
<string name="sure_del">是否確認刪除?</string>
|
<string name="sure_del">是否確認刪除?</string>
|
||||||
|
<string name="sure_del_private_group">刪除後,相關書籍可能喺公開書架中顯示,是否確認刪除?</string>
|
||||||
|
<string name="sure_disable_private_group">關閉後,本組書籍可能喺公開書架中顯示,是否確認關閉?</string>
|
||||||
<string name="sure_del_any">是否確認刪除 %s?</string>
|
<string name="sure_del_any">是否確認刪除 %s?</string>
|
||||||
<string name="sure_del_all_book">是否刪除全部書籍?</string>
|
<string name="sure_del_all_book">是否刪除全部書籍?</string>
|
||||||
<string name="sure_del_download_book">是否同時刪除已下載的書籍目錄?</string>
|
<string name="sure_del_download_book">是否同時刪除已下載的書籍目錄?</string>
|
||||||
@@ -1137,6 +1139,9 @@
|
|||||||
<string name="file_manage_summary">管理私有文件夹的文件</string>
|
<string name="file_manage_summary">管理私有文件夹的文件</string>
|
||||||
<string name="create_folder">创建文件夹</string>
|
<string name="create_folder">创建文件夹</string>
|
||||||
<string name="allow_drop_down_refresh">允许下拉刷新</string>
|
<string name="allow_drop_down_refresh">允许下拉刷新</string>
|
||||||
|
<string name="private_group">設為私隱分組</string>
|
||||||
|
<string name="disable_private_group">關閉私隱分組</string>
|
||||||
|
<string name="private_group_desc">開啟後,本分組內嘅書籍將從公開書架隱藏</string>
|
||||||
<string name="text_underline">文字下划线</string>
|
<string name="text_underline">文字下划线</string>
|
||||||
<string name="select_new_source">选中新增源</string>
|
<string name="select_new_source">选中新增源</string>
|
||||||
<string name="select_update_source">选中更新源</string>
|
<string name="select_update_source">选中更新源</string>
|
||||||
|
|||||||
@@ -517,6 +517,8 @@
|
|||||||
<string name="no">否</string>
|
<string name="no">否</string>
|
||||||
<string name="sure">確認</string>
|
<string name="sure">確認</string>
|
||||||
<string name="sure_del">是否確認刪除?</string>
|
<string name="sure_del">是否確認刪除?</string>
|
||||||
|
<string name="sure_del_private_group">刪除後,相關書籍可能在公開書架中顯示,是否確認刪除?</string>
|
||||||
|
<string name="sure_disable_private_group">關閉後,本組書籍可能在公開書架中顯示,是否確認關閉?</string>
|
||||||
<string name="sure_del_any">是否確認刪除 %s?</string>
|
<string name="sure_del_any">是否確認刪除 %s?</string>
|
||||||
<string name="sure_del_all_book">是否刪除全部書籍?</string>
|
<string name="sure_del_all_book">是否刪除全部書籍?</string>
|
||||||
<string name="sure_del_download_book">是否同時刪除已下載的書籍目錄?</string>
|
<string name="sure_del_download_book">是否同時刪除已下載的書籍目錄?</string>
|
||||||
@@ -1140,6 +1142,9 @@
|
|||||||
<string name="file_manage_summary">管理私有文件夹的文件</string>
|
<string name="file_manage_summary">管理私有文件夹的文件</string>
|
||||||
<string name="create_folder">创建文件夹</string>
|
<string name="create_folder">创建文件夹</string>
|
||||||
<string name="allow_drop_down_refresh">允许下拉刷新</string>
|
<string name="allow_drop_down_refresh">允许下拉刷新</string>
|
||||||
|
<string name="private_group">設為隱私分組</string>
|
||||||
|
<string name="disable_private_group">關閉隱私分組</string>
|
||||||
|
<string name="private_group_desc">開啟後,本分組內的書籍將從公開書架隱藏</string>
|
||||||
<string name="text_underline">文字下划线</string>
|
<string name="text_underline">文字下划线</string>
|
||||||
<string name="select_new_source">选中新增源</string>
|
<string name="select_new_source">选中新增源</string>
|
||||||
<string name="select_update_source">选中更新源</string>
|
<string name="select_update_source">选中更新源</string>
|
||||||
|
|||||||
@@ -591,6 +591,8 @@
|
|||||||
<string name="no">No</string>
|
<string name="no">No</string>
|
||||||
<string name="sure">OK</string>
|
<string name="sure">OK</string>
|
||||||
<string name="sure_del">Are you sure to delete it?</string>
|
<string name="sure_del">Are you sure to delete it?</string>
|
||||||
|
<string name="sure_del_private_group">Related books may appear in public bookshelf views after deletion. Are you sure to delete?</string>
|
||||||
|
<string name="sure_disable_private_group">Books in this group may appear in public bookshelf views after disabling. Are you sure to disable?</string>
|
||||||
<string name="sure_del_any">Are you sure to delete %s?</string>
|
<string name="sure_del_any">Are you sure to delete %s?</string>
|
||||||
<string name="sure_del_all_book">Are you sure to delete all books?</string>
|
<string name="sure_del_all_book">Are you sure to delete all books?</string>
|
||||||
<string name="sure_del_download_book">Do you want to delete the downloaded book chapters at the same time?</string>
|
<string name="sure_del_download_book">Do you want to delete the downloaded book chapters at the same time?</string>
|
||||||
@@ -1245,6 +1247,9 @@
|
|||||||
<string name="file_manage_summary">Managing files in the application\'s private folder</string>
|
<string name="file_manage_summary">Managing files in the application\'s private folder</string>
|
||||||
<string name="create_folder">Create Folder</string>
|
<string name="create_folder">Create Folder</string>
|
||||||
<string name="allow_drop_down_refresh">Allow drop-down refresh</string>
|
<string name="allow_drop_down_refresh">Allow drop-down refresh</string>
|
||||||
|
<string name="private_group">Set as private group</string>
|
||||||
|
<string name="disable_private_group">Disable private group</string>
|
||||||
|
<string name="private_group_desc">After enabling, books in this group are hidden from the public bookshelf</string>
|
||||||
<string name="text_underline">Text underline</string>
|
<string name="text_underline">Text underline</string>
|
||||||
<string name="select_new_source">Select new source</string>
|
<string name="select_new_source">Select new source</string>
|
||||||
<string name="select_update_source">Select update source</string>
|
<string name="select_update_source">Select update source</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user