一些优化
This commit is contained in:
39 files changed
+136
-1008
No files matched your search
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"enable": false,
|
"enable": true,
|
||||||
"searchUrl": "",
|
"searchUrl": "data:;base64,{{java.base64Encode(key)}},{\"type\":\"lyc\"}",
|
||||||
"coverRule": ""
|
"coverRule": "@js:\nvar key = java.hexDecodeToString(result);\nvar url1 = `https://pre-api.tuishujun.com/api/searchBook?search_value=${key}&page=1&pageSize=20`;\nvar url2 = `http://m.ypshuo.com/api/novel/search?keyword=${key}&searchType=1&page=1`;\nvar [rr1, rr2] = java.ajaxAll([url1, url2]).map(r => r.body());\nfunction jjson(str, rule) {\n try {\n return com.jayway.jsonpath.JsonPath.read(str, rule);\n } catch (e) {\n return [];\n }\n}\nrr1 = jjson(rr1, '$.data.data[*]');\nrr2 = jjson(rr2, '$.data.data[*]');\nvar na = String(book.name),\n au = String(book.author);\nfunction search() {\n for (let char of rr1) {\n //本地书名包含搜索结果书名\n if (na.includes(char.title + '')) {\n let au2 = char.author_nickname + '';\n //作者匹配\n if (au.includes(au2) || au2.includes(au)) {\n return char.cover;\n }\n }\n }\n for (let char of rr2) {\n if (na.includes(char.novel_name + '')) {\n let au2 = char.author_name + '';\n if (au.includes(au2) || au2.includes(au)) {\n return char.novel_img;\n }\n }\n }\n return '';\n}\nsearch()"
|
||||||
}
|
}
|
||||||
@@ -1,42 +1 @@
|
|||||||
[
|
[]
|
||||||
{
|
|
||||||
"customOrder": 2,
|
|
||||||
"enableJs": true,
|
|
||||||
"enabled": true,
|
|
||||||
"singleUrl": true,
|
|
||||||
"sourceGroup": "legado",
|
|
||||||
"sourceIcon": "https://cdn.jsdelivr.net/gh/gedoor/legado@master/app/src/main/res/mipmap-hdpi/ic_launcher.png",
|
|
||||||
"sourceName": "使用说明",
|
|
||||||
"sourceUrl": "https://www.yuque.com/legado"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"customOrder": 3,
|
|
||||||
"enableJs": true,
|
|
||||||
"enabled": true,
|
|
||||||
"singleUrl": true,
|
|
||||||
"sourceGroup": "legado",
|
|
||||||
"sourceIcon": "http://mmbiz.qpic.cn/mmbiz_png/hpfMV8hEuL2eS6vnCxvTzoOiaCAibV6exBzJWq9xMic9xDg3YXAick87tsfafic0icRwkQ5ibV0bJ84JtSuxhPuEDVquA/0?wx_fmt=png",
|
|
||||||
"sourceName": "小说拾遗",
|
|
||||||
"sourceUrl": "snssdk1128://user/profile/562564899806367"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"customOrder": 4,
|
|
||||||
"enableJs": true,
|
|
||||||
"enabled": true,
|
|
||||||
"singleUrl": true,
|
|
||||||
"sourceGroup": "legado",
|
|
||||||
"sourceIcon": "https://cdn.jsdelivr.net/gh/mgz0227/meowcloud/icon.png",
|
|
||||||
"sourceName": "Meow云",
|
|
||||||
"sourceUrl": "https://pan.miaogongzi.net"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"customOrder": 5,
|
|
||||||
"enableJs": true,
|
|
||||||
"enabled": true,
|
|
||||||
"singleUrl": true,
|
|
||||||
"sourceGroup": "legado",
|
|
||||||
"sourceIcon": "https://cdn.jsdelivr.net/gh/gedoor/legado@master/app/src/main/res/mipmap-hdpi/ic_launcher.png",
|
|
||||||
"sourceName": "烏雲净化",
|
|
||||||
"sourceUrl": "https://www.lanzoux.com/b0bw8jwoh"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -45,6 +45,7 @@ import io.legado.app.domain.usecase.CacheBookChaptersUseCase
|
|||||||
import io.legado.app.domain.usecase.ChangeBookSourceUseCase
|
import io.legado.app.domain.usecase.ChangeBookSourceUseCase
|
||||||
import io.legado.app.domain.usecase.ClearBookCacheUseCase
|
import io.legado.app.domain.usecase.ClearBookCacheUseCase
|
||||||
import io.legado.app.domain.usecase.DeleteBooksUseCase
|
import io.legado.app.domain.usecase.DeleteBooksUseCase
|
||||||
|
import io.legado.app.domain.usecase.ExploreKindUiUseCase
|
||||||
import io.legado.app.domain.usecase.GetReadingProgressUseCase
|
import io.legado.app.domain.usecase.GetReadingProgressUseCase
|
||||||
import io.legado.app.domain.usecase.RemoveBookGroupAssignmentUseCase
|
import io.legado.app.domain.usecase.RemoveBookGroupAssignmentUseCase
|
||||||
import io.legado.app.domain.usecase.ResolveBookShelfStateUseCase
|
import io.legado.app.domain.usecase.ResolveBookShelfStateUseCase
|
||||||
@@ -103,7 +104,6 @@ import io.legado.app.ui.rss.favorites.RssFavoritesViewModel
|
|||||||
import io.legado.app.ui.rss.read.ReadRssViewModel
|
import io.legado.app.ui.rss.read.ReadRssViewModel
|
||||||
import io.legado.app.ui.rss.source.manage.RssSourceViewModel
|
import io.legado.app.ui.rss.source.manage.RssSourceViewModel
|
||||||
import io.legado.app.ui.rss.subscription.RuleSubViewModel
|
import io.legado.app.ui.rss.subscription.RuleSubViewModel
|
||||||
import io.legado.app.ui.widget.components.explore.ExploreKindUiUseCase
|
|
||||||
import org.koin.core.module.dsl.singleOf
|
import org.koin.core.module.dsl.singleOf
|
||||||
import org.koin.core.module.dsl.viewModel
|
import org.koin.core.module.dsl.viewModel
|
||||||
import org.koin.core.module.dsl.viewModelOf
|
import org.koin.core.module.dsl.viewModelOf
|
||||||
|
|||||||
+4
-4
@@ -1,4 +1,4 @@
|
|||||||
package io.legado.app.ui.widget.components.explore
|
package io.legado.app.domain.usecase
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.script.rhino.runScriptWithContext
|
import com.script.rhino.runScriptWithContext
|
||||||
@@ -10,7 +10,7 @@ import io.legado.app.data.entities.rule.ExploreKind
|
|||||||
import io.legado.app.help.source.getExploreInfoMap
|
import io.legado.app.help.source.getExploreInfoMap
|
||||||
import io.legado.app.ui.login.SourceLoginJsExtensions
|
import io.legado.app.ui.login.SourceLoginJsExtensions
|
||||||
import io.legado.app.utils.InfoMap
|
import io.legado.app.utils.InfoMap
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ class ExploreKindUiUseCase(
|
|||||||
override fun reUiView() = onRefreshKinds()
|
override fun reUiView() = onRefreshKinds()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
withContext(IO) {
|
withContext(Dispatchers.IO) {
|
||||||
evalButtonClick(actionText, source, effectiveInfoMap, title, sourceJsExtensions)
|
evalButtonClick(actionText, source, effectiveInfoMap, title, sourceJsExtensions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ class ExploreKindUiUseCase(
|
|||||||
|
|
||||||
private suspend fun getOrLoadBookSource(sourceUrl: String): BookSource? {
|
private suspend fun getOrLoadBookSource(sourceUrl: String): BookSource? {
|
||||||
sourceCache[sourceUrl]?.let { return it }
|
sourceCache[sourceUrl]?.let { return it }
|
||||||
return withContext(IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
bookSourceDao.getBookSource(sourceUrl)
|
bookSourceDao.getBookSource(sourceUrl)
|
||||||
}?.also { source ->
|
}?.also { source ->
|
||||||
sourceCache[sourceUrl] = source
|
sourceCache[sourceUrl] = source
|
||||||
@@ -61,6 +61,7 @@ import dev.chrisbanes.haze.HazeState
|
|||||||
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
||||||
import io.legado.app.data.entities.SearchBook
|
import io.legado.app.data.entities.SearchBook
|
||||||
import io.legado.app.domain.model.BookShelfState
|
import io.legado.app.domain.model.BookShelfState
|
||||||
|
import io.legado.app.domain.usecase.ExploreKindUiUseCase
|
||||||
import io.legado.app.ui.main.bookCoverSharedElementKey
|
import io.legado.app.ui.main.bookCoverSharedElementKey
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.theme.ThemeResolver
|
import io.legado.app.ui.theme.ThemeResolver
|
||||||
@@ -74,7 +75,6 @@ import io.legado.app.ui.widget.components.book.SearchBookListItem
|
|||||||
import io.legado.app.ui.widget.components.button.AnimatedTextButton
|
import io.legado.app.ui.widget.components.button.AnimatedTextButton
|
||||||
import io.legado.app.ui.widget.components.card.TextCard
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
import io.legado.app.ui.widget.components.explore.ExploreKindMultiTypeItem
|
import io.legado.app.ui.widget.components.explore.ExploreKindMultiTypeItem
|
||||||
import io.legado.app.ui.widget.components.explore.ExploreKindUiUseCase
|
|
||||||
import io.legado.app.ui.widget.components.explore.calculateExploreKindRows
|
import io.legado.app.ui.widget.components.explore.calculateExploreKindRows
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
|||||||
import io.legado.app.ui.widget.components.button.ConfirmDismissButtonsRow
|
import io.legado.app.ui.widget.components.button.ConfirmDismissButtonsRow
|
||||||
import io.legado.app.ui.widget.components.button.MediumIconButton
|
import io.legado.app.ui.widget.components.button.MediumIconButton
|
||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
import io.legado.app.ui.widget.components.card.GlassCard
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
import io.legado.app.ui.widget.components.image.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
||||||
import io.legado.app.ui.widget.components.settingItem.CompactDropdownSettingItem
|
import io.legado.app.ui.widget.components.settingItem.CompactDropdownSettingItem
|
||||||
import io.legado.app.ui.widget.components.settingItem.CompactSwitchSettingItem
|
import io.legado.app.ui.widget.components.settingItem.CompactSwitchSettingItem
|
||||||
|
|||||||
@@ -91,9 +91,9 @@ import io.legado.app.ui.widget.components.AppTextField
|
|||||||
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
import io.legado.app.ui.widget.components.card.GlassCard
|
||||||
import io.legado.app.ui.widget.components.card.TextCard
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
|
||||||
import io.legado.app.ui.widget.components.cover.buildCoverImageRequest
|
|
||||||
import io.legado.app.ui.widget.components.icon.AppIcon
|
import io.legado.app.ui.widget.components.icon.AppIcon
|
||||||
|
import io.legado.app.ui.widget.components.image.cover.CoilBookCover
|
||||||
|
import io.legado.app.ui.widget.components.image.cover.buildCoverImageRequest
|
||||||
import io.legado.app.ui.widget.components.log.AppLogSheet
|
import io.legado.app.ui.widget.components.log.AppLogSheet
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ import io.legado.app.ui.widget.components.button.SmallIconButton
|
|||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
import io.legado.app.ui.widget.components.card.GlassCard
|
||||||
import io.legado.app.ui.widget.components.card.SelectionItemCard
|
import io.legado.app.ui.widget.components.card.SelectionItemCard
|
||||||
import io.legado.app.ui.widget.components.checkBox.AppCheckbox
|
import io.legado.app.ui.widget.components.checkBox.AppCheckbox
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
import io.legado.app.ui.widget.components.image.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
||||||
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ import io.legado.app.model.analyzeRule.AnalyzeUrl
|
|||||||
import io.legado.app.model.localBook.LocalBook
|
import io.legado.app.model.localBook.LocalBook
|
||||||
import io.legado.app.model.webBook.WebBook
|
import io.legado.app.model.webBook.WebBook
|
||||||
import io.legado.app.ui.config.coverConfig.CoverConfig
|
import io.legado.app.ui.config.coverConfig.CoverConfig
|
||||||
import io.legado.app.ui.widget.components.cover.buildCoverImageRequest
|
import io.legado.app.ui.widget.components.image.cover.buildCoverImageRequest
|
||||||
import io.legado.app.utils.ArchiveUtils
|
import io.legado.app.utils.ArchiveUtils
|
||||||
import io.legado.app.utils.GSON
|
import io.legado.app.utils.GSON
|
||||||
import io.legado.app.utils.ImageSaveUtils
|
import io.legado.app.utils.ImageSaveUtils
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ import io.legado.app.ui.widget.components.AppScaffold
|
|||||||
import io.legado.app.ui.widget.components.AppTextField
|
import io.legado.app.ui.widget.components.AppTextField
|
||||||
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
||||||
import io.legado.app.ui.widget.components.button.MediumOutlinedIconButton
|
import io.legado.app.ui.widget.components.button.MediumOutlinedIconButton
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
import io.legado.app.ui.widget.components.image.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
||||||
import io.legado.app.ui.widget.components.settingItem.SwitchSettingItem
|
import io.legado.app.ui.widget.components.settingItem.SwitchSettingItem
|
||||||
|
|||||||
@@ -88,10 +88,10 @@ import io.legado.app.ui.widget.components.card.GlassCard
|
|||||||
import io.legado.app.ui.widget.components.card.ReorderableSelectionItem
|
import io.legado.app.ui.widget.components.card.ReorderableSelectionItem
|
||||||
import io.legado.app.ui.widget.components.card.SelectionItemCard
|
import io.legado.app.ui.widget.components.card.SelectionItemCard
|
||||||
import io.legado.app.ui.widget.components.card.TextCard
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
|
||||||
import io.legado.app.ui.widget.components.divider.PillDivider
|
import io.legado.app.ui.widget.components.divider.PillDivider
|
||||||
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
|
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
|
||||||
import io.legado.app.ui.widget.components.icon.AppIcons
|
import io.legado.app.ui.widget.components.icon.AppIcons
|
||||||
|
import io.legado.app.ui.widget.components.image.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.list.ListScaffold
|
import io.legado.app.ui.widget.components.list.ListScaffold
|
||||||
import io.legado.app.ui.widget.components.list.ListUiState
|
import io.legado.app.ui.widget.components.list.ListUiState
|
||||||
import io.legado.app.ui.widget.components.log.AppLogSheet
|
import io.legado.app.ui.widget.components.log.AppLogSheet
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ import io.legado.app.ui.theme.adaptiveHorizontalPadding
|
|||||||
import io.legado.app.ui.widget.components.AppScaffold
|
import io.legado.app.ui.widget.components.AppScaffold
|
||||||
import io.legado.app.ui.widget.components.button.MediumIconButton
|
import io.legado.app.ui.widget.components.button.MediumIconButton
|
||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
import io.legado.app.ui.widget.components.card.GlassCard
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
|
||||||
import io.legado.app.ui.widget.components.heatmap.HeatmapMode
|
import io.legado.app.ui.widget.components.heatmap.HeatmapMode
|
||||||
|
import io.legado.app.ui.widget.components.image.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.tabRow.AppTabRow
|
import io.legado.app.ui.widget.components.tabRow.AppTabRow
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
import io.legado.app.ui.widget.components.topbar.GlassMediumFlexibleTopAppBar
|
import io.legado.app.ui.widget.components.topbar.GlassMediumFlexibleTopAppBar
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ import io.legado.app.ui.theme.LegadoTheme
|
|||||||
import io.legado.app.ui.theme.adaptiveContentPaddingOnlyVertical
|
import io.legado.app.ui.theme.adaptiveContentPaddingOnlyVertical
|
||||||
import io.legado.app.ui.theme.adaptiveHorizontalPadding
|
import io.legado.app.ui.theme.adaptiveHorizontalPadding
|
||||||
import io.legado.app.ui.theme.fadingEdge
|
import io.legado.app.ui.theme.fadingEdge
|
||||||
import io.legado.app.ui.widget.CollapsibleHeader
|
|
||||||
import io.legado.app.ui.widget.components.AppScaffold
|
import io.legado.app.ui.widget.components.AppScaffold
|
||||||
|
import io.legado.app.ui.widget.components.CollapsibleHeader
|
||||||
import io.legado.app.ui.widget.components.EmptyMessage
|
import io.legado.app.ui.widget.components.EmptyMessage
|
||||||
import io.legado.app.ui.widget.components.SearchBar
|
import io.legado.app.ui.widget.components.SearchBar
|
||||||
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
||||||
@@ -75,7 +75,6 @@ import io.legado.app.ui.widget.components.button.AppIconButton
|
|||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
import io.legado.app.ui.widget.components.card.GlassCard
|
||||||
import io.legado.app.ui.widget.components.card.TextCard
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
import io.legado.app.ui.widget.components.checkBox.CheckboxItem
|
import io.legado.app.ui.widget.components.checkBox.CheckboxItem
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
|
||||||
import io.legado.app.ui.widget.components.heatmap.HEATMAP_CALENDAR_TITLE
|
import io.legado.app.ui.widget.components.heatmap.HEATMAP_CALENDAR_TITLE
|
||||||
import io.legado.app.ui.widget.components.heatmap.HeatmapCalendarEndAction
|
import io.legado.app.ui.widget.components.heatmap.HeatmapCalendarEndAction
|
||||||
import io.legado.app.ui.widget.components.heatmap.HeatmapCalendarStartAction
|
import io.legado.app.ui.widget.components.heatmap.HeatmapCalendarStartAction
|
||||||
@@ -89,6 +88,7 @@ import io.legado.app.ui.widget.components.heatmap.rememberDateRange
|
|||||||
import io.legado.app.ui.widget.components.heatmap.rememberDaysInRange
|
import io.legado.app.ui.widget.components.heatmap.rememberDaysInRange
|
||||||
import io.legado.app.ui.widget.components.heatmap.rememberWeeks
|
import io.legado.app.ui.widget.components.heatmap.rememberWeeks
|
||||||
import io.legado.app.ui.widget.components.icon.AppIcon
|
import io.legado.app.ui.widget.components.icon.AppIcon
|
||||||
|
import io.legado.app.ui.widget.components.image.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.list.TopFloatingStickyItem
|
import io.legado.app.ui.widget.components.list.TopFloatingStickyItem
|
||||||
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
||||||
import io.legado.app.ui.widget.components.swipe.SwipeAction
|
import io.legado.app.ui.widget.components.swipe.SwipeAction
|
||||||
|
|||||||
+15
-3
@@ -2,8 +2,20 @@ package io.legado.app.ui.book.readRecord.component
|
|||||||
|
|
||||||
import androidx.compose.foundation.basicMarquee
|
import androidx.compose.foundation.basicMarquee
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
@@ -16,7 +28,7 @@ import io.legado.app.ui.book.readRecord.ReadRecordFormatter
|
|||||||
import io.legado.app.ui.book.readRecord.ReadRecordViewModel
|
import io.legado.app.ui.book.readRecord.ReadRecordViewModel
|
||||||
import io.legado.app.ui.book.readRecord.TimelineItem
|
import io.legado.app.ui.book.readRecord.TimelineItem
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
import io.legado.app.ui.widget.components.image.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
import io.legado.app.utils.StringUtils.formatFriendlyDate
|
import io.legado.app.utils.StringUtils.formatFriendlyDate
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
package io.legado.app.ui.book.readRecord.component
|
package io.legado.app.ui.book.readRecord.component
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.legado.app.ui.book.readRecord.ReadRecordFormatter
|
import io.legado.app.ui.book.readRecord.ReadRecordFormatter
|
||||||
import io.legado.app.ui.book.readRecord.ReadRecordUiState
|
import io.legado.app.ui.book.readRecord.ReadRecordUiState
|
||||||
@@ -12,7 +23,7 @@ import io.legado.app.ui.book.readRecord.ReadRecordViewModel
|
|||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.theme.adaptiveHorizontalPadding
|
import io.legado.app.ui.theme.adaptiveHorizontalPadding
|
||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
import io.legado.app.ui.widget.components.card.GlassCard
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
import io.legado.app.ui.widget.components.image.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
@@ -23,17 +22,12 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Book
|
import androidx.compose.material.icons.filled.Book
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.material.icons.filled.History
|
|
||||||
import androidx.compose.material.icons.filled.Layers
|
import androidx.compose.material.icons.filled.Layers
|
||||||
import androidx.compose.material.icons.filled.PlayArrow
|
import androidx.compose.material.icons.filled.PlayArrow
|
||||||
import androidx.compose.material.icons.filled.Stop
|
import androidx.compose.material.icons.filled.Stop
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import io.legado.app.ui.widget.components.progressIndicator.AppCircularProgressIndicator
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import io.legado.app.ui.widget.components.topbar.GlassMediumFlexibleTopAppBar
|
|
||||||
import io.legado.app.ui.widget.components.topbar.M3GlassScrollBehavior
|
|
||||||
import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
@@ -42,9 +36,9 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberUpdatedState
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.runtime.snapshotFlow
|
import androidx.compose.runtime.snapshotFlow
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
@@ -58,6 +52,7 @@ import androidx.lifecycle.compose.LocalLifecycleOwner
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.data.entities.SearchKeyword
|
import io.legado.app.data.entities.SearchKeyword
|
||||||
|
import io.legado.app.ui.main.bookCoverSharedElementKey
|
||||||
import io.legado.app.ui.main.bookshelf.BookShelfItem
|
import io.legado.app.ui.main.bookshelf.BookShelfItem
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.theme.ThemeResolver
|
import io.legado.app.ui.theme.ThemeResolver
|
||||||
@@ -68,22 +63,23 @@ import io.legado.app.ui.widget.components.AppFloatingActionButton
|
|||||||
import io.legado.app.ui.widget.components.AppScaffold
|
import io.legado.app.ui.widget.components.AppScaffold
|
||||||
import io.legado.app.ui.widget.components.SearchBar
|
import io.legado.app.ui.widget.components.SearchBar
|
||||||
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
||||||
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
|
||||||
import io.legado.app.ui.widget.components.book.SearchBookListItem
|
import io.legado.app.ui.widget.components.book.SearchBookListItem
|
||||||
import io.legado.app.ui.widget.components.button.SmallIconButton
|
import io.legado.app.ui.widget.components.button.SmallIconButton
|
||||||
import io.legado.app.ui.widget.components.button.SmallTextButton
|
import io.legado.app.ui.widget.components.button.SmallTextButton
|
||||||
import io.legado.app.ui.widget.components.card.NormalCard
|
import io.legado.app.ui.widget.components.card.NormalCard
|
||||||
import io.legado.app.ui.widget.components.card.SelectionItemCard
|
import io.legado.app.ui.widget.components.card.SelectionItemCard
|
||||||
|
import io.legado.app.ui.widget.components.icon.AppIcon
|
||||||
|
import io.legado.app.ui.widget.components.icon.AppIcons
|
||||||
|
import io.legado.app.ui.widget.components.list.TopFloatingStickyItem
|
||||||
|
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
||||||
|
import io.legado.app.ui.widget.components.progressIndicator.AppCircularProgressIndicator
|
||||||
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
|
import io.legado.app.ui.widget.components.topbar.GlassMediumFlexibleTopAppBar
|
||||||
|
import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults
|
||||||
|
import io.legado.app.ui.widget.components.topbar.M3GlassScrollBehavior
|
||||||
import io.legado.app.ui.widget.components.topbar.TopBarActionButton
|
import io.legado.app.ui.widget.components.topbar.TopBarActionButton
|
||||||
import io.legado.app.ui.widget.components.topbar.TopBarAnimatedActionButton
|
import io.legado.app.ui.widget.components.topbar.TopBarAnimatedActionButton
|
||||||
import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
|
import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
|
||||||
import io.legado.app.ui.widget.components.icon.AppIcon
|
|
||||||
import io.legado.app.ui.widget.components.icon.AppIcons
|
|
||||||
import io.legado.app.ui.book.search.ScopeSelectSheet
|
|
||||||
import io.legado.app.ui.widget.components.list.TopFloatingStickyItem
|
|
||||||
import io.legado.app.ui.widget.components.tabRow.AppTabRow
|
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
|
||||||
import io.legado.app.ui.main.bookCoverSharedElementKey
|
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
import kotlinx.coroutines.FlowPreview
|
import kotlinx.coroutines.FlowPreview
|
||||||
import kotlinx.coroutines.flow.debounce
|
import kotlinx.coroutines.flow.debounce
|
||||||
@@ -480,19 +476,17 @@ fun SearchScreen(
|
|||||||
viewModel.onIntent(SearchIntent.DismissEmptyScopeAction)
|
viewModel.onIntent(SearchIntent.DismissEmptyScopeAction)
|
||||||
},
|
},
|
||||||
title = stringResource(R.string.draw),
|
title = stringResource(R.string.draw),
|
||||||
|
textProvider = {
|
||||||
|
if (wasPrecisionSearch) {
|
||||||
|
stringResource(R.string.search_empty_scope_disable_precision, scopeDisplay)
|
||||||
|
} else {
|
||||||
|
stringResource(R.string.search_empty_scope_switch_all, scopeDisplay)
|
||||||
|
}
|
||||||
|
},
|
||||||
confirmText = stringResource(R.string.ok),
|
confirmText = stringResource(R.string.ok),
|
||||||
onConfirm = { viewModel.onIntent(SearchIntent.ConfirmEmptyScopeAction) },
|
onConfirm = { viewModel.onIntent(SearchIntent.ConfirmEmptyScopeAction) },
|
||||||
dismissText = stringResource(R.string.cancel),
|
dismissText = stringResource(R.string.cancel),
|
||||||
onDismiss = { viewModel.onIntent(SearchIntent.DismissEmptyScopeAction) },
|
onDismiss = { viewModel.onIntent(SearchIntent.DismissEmptyScopeAction) },
|
||||||
content = {
|
|
||||||
Text(
|
|
||||||
text = if (it.wasPrecisionSearch) {
|
|
||||||
stringResource(R.string.search_empty_scope_disable_precision, it.scopeDisplay)
|
|
||||||
} else {
|
|
||||||
stringResource(R.string.search_empty_scope_switch_all, it.scopeDisplay)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ScopeSelectSheet(
|
ScopeSelectSheet(
|
||||||
@@ -681,12 +675,8 @@ private fun SearchResultFooter(
|
|||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
) {
|
) {
|
||||||
Box(
|
AppCircularProgressIndicator()
|
||||||
modifier = Modifier.size(18.dp),
|
Spacer(modifier = Modifier.padding(horizontal = 8.dp))
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
AppCircularProgressIndicator()
|
|
||||||
}
|
|
||||||
AppText(text = stringResource(R.string.is_loading))
|
AppText(text = stringResource(R.string.is_loading))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,10 +84,10 @@ import io.legado.app.ui.replace.ReplaceEditRoute
|
|||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.theme.adaptiveContentPaddingOnlyVertical
|
import io.legado.app.ui.theme.adaptiveContentPaddingOnlyVertical
|
||||||
import io.legado.app.ui.theme.adaptiveHorizontalPadding
|
import io.legado.app.ui.theme.adaptiveHorizontalPadding
|
||||||
import io.legado.app.ui.widget.CollapsibleHeader
|
|
||||||
import io.legado.app.ui.widget.components.ActionItem
|
import io.legado.app.ui.widget.components.ActionItem
|
||||||
import io.legado.app.ui.widget.components.AppFloatingActionButtonMenu
|
import io.legado.app.ui.widget.components.AppFloatingActionButtonMenu
|
||||||
import io.legado.app.ui.widget.components.AppScaffold
|
import io.legado.app.ui.widget.components.AppScaffold
|
||||||
|
import io.legado.app.ui.widget.components.CollapsibleHeader
|
||||||
import io.legado.app.ui.widget.components.EmptyMessage
|
import io.legado.app.ui.widget.components.EmptyMessage
|
||||||
import io.legado.app.ui.widget.components.FabMenuItem
|
import io.legado.app.ui.widget.components.FabMenuItem
|
||||||
import io.legado.app.ui.widget.components.SelectionBottomBar
|
import io.legado.app.ui.widget.components.SelectionBottomBar
|
||||||
|
|||||||
@@ -1,328 +0,0 @@
|
|||||||
package io.legado.app.ui.book.toc.rule
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.appcompat.widget.Toolbar
|
|
||||||
import androidx.core.os.bundleOf
|
|
||||||
import androidx.fragment.app.viewModels
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import io.legado.app.R
|
|
||||||
import io.legado.app.base.BaseDialogFragment
|
|
||||||
import io.legado.app.base.adapter.ItemViewHolder
|
|
||||||
import io.legado.app.base.adapter.RecyclerAdapter
|
|
||||||
import io.legado.app.constant.AppLog
|
|
||||||
import io.legado.app.data.appDb
|
|
||||||
import io.legado.app.data.entities.TxtTocRule
|
|
||||||
import io.legado.app.databinding.DialogEditTextBinding
|
|
||||||
import io.legado.app.databinding.DialogTocRegexBinding
|
|
||||||
import io.legado.app.databinding.ItemTocRegexBinding
|
|
||||||
import io.legado.app.lib.dialogs.alert
|
|
||||||
//import io.legado.app.lib.theme.backgroundColor
|
|
||||||
//import io.legado.app.lib.theme.primaryColor
|
|
||||||
import io.legado.app.ui.association.ImportTxtTocRuleDialog
|
|
||||||
import io.legado.app.ui.file.HandleFileContract
|
|
||||||
import io.legado.app.ui.qrcode.QrCodeResult
|
|
||||||
import io.legado.app.ui.widget.recycler.ItemTouchCallback
|
|
||||||
import io.legado.app.ui.widget.recycler.VerticalDivider
|
|
||||||
import io.legado.app.utils.ACache
|
|
||||||
import io.legado.app.utils.isAbsUrl
|
|
||||||
import io.legado.app.utils.launch
|
|
||||||
import io.legado.app.utils.readText
|
|
||||||
import io.legado.app.utils.showDialogFragment
|
|
||||||
import io.legado.app.utils.showHelp
|
|
||||||
import io.legado.app.utils.splitNotBlank
|
|
||||||
import io.legado.app.utils.toastOnUi
|
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
|
||||||
import kotlinx.coroutines.flow.catch
|
|
||||||
import kotlinx.coroutines.flow.conflate
|
|
||||||
import kotlinx.coroutines.flow.flowOn
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
/**
|
|
||||||
* txt目录规则
|
|
||||||
*/
|
|
||||||
class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
|
|
||||||
Toolbar.OnMenuItemClickListener,
|
|
||||||
TxtTocRuleEditDialog.Callback {
|
|
||||||
|
|
||||||
constructor(tocRegex: String?) : this() {
|
|
||||||
arguments = Bundle().apply {
|
|
||||||
putString("tocRegex", tocRegex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val importTocRuleKey = "tocRuleUrl"
|
|
||||||
private val viewModel: TxtTocRuleViewModel by viewModels()
|
|
||||||
private val binding by viewBinding(DialogTocRegexBinding::bind)
|
|
||||||
private val adapter by lazy { TocRegexAdapter(requireContext()) }
|
|
||||||
var selectedName: String? = null
|
|
||||||
private var durRegex: String? = null
|
|
||||||
private val qrCodeResult = registerForActivityResult(QrCodeResult()) {
|
|
||||||
it ?: return@registerForActivityResult
|
|
||||||
showDialogFragment(ImportTxtTocRuleDialog(it))
|
|
||||||
}
|
|
||||||
private val importDoc = registerForActivityResult(HandleFileContract()) {
|
|
||||||
kotlin.runCatching {
|
|
||||||
it.uri?.readText(requireContext())?.let {
|
|
||||||
showDialogFragment(ImportTxtTocRuleDialog(it))
|
|
||||||
}
|
|
||||||
}.onFailure {
|
|
||||||
toastOnUi("readTextError:${it.localizedMessage}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
//binding.toolBar.setBackgroundColor(primaryColor)
|
|
||||||
durRegex = arguments?.getString("tocRegex")
|
|
||||||
binding.toolBar.setTitle(R.string.txt_toc_rule)
|
|
||||||
binding.toolBar.inflateMenu(R.menu.txt_toc_rule)
|
|
||||||
//binding.toolBar.menu.applyTint(requireContext())
|
|
||||||
binding.toolBar.setOnMenuItemClickListener(this)
|
|
||||||
initView()
|
|
||||||
initData()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initView() = binding.run {
|
|
||||||
recyclerView.addItemDecoration(VerticalDivider(requireContext()))
|
|
||||||
recyclerView.adapter = adapter
|
|
||||||
val itemTouchCallback = ItemTouchCallback(adapter)
|
|
||||||
itemTouchCallback.isCanDrag = true
|
|
||||||
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(recyclerView)
|
|
||||||
tvCancel.setOnClickListener {
|
|
||||||
dismissAllowingStateLoss()
|
|
||||||
}
|
|
||||||
tvOk.setOnClickListener {
|
|
||||||
adapter.getItems().forEach { tocRule ->
|
|
||||||
if (selectedName == tocRule.name) {
|
|
||||||
val callBack = activity as? CallBack
|
|
||||||
callBack?.onTocRegexDialogResult(tocRule.rule)
|
|
||||||
dismissAllowingStateLoss()
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initData() {
|
|
||||||
lifecycleScope.launch {
|
|
||||||
appDb.txtTocRuleDao.observeAll().catch {
|
|
||||||
AppLog.put("TXT目录规则对话框获取数据失败\n${it.localizedMessage}", it)
|
|
||||||
}.flowOn(IO).conflate().collect { tocRules ->
|
|
||||||
initSelectedName(tocRules)
|
|
||||||
adapter.setItems(tocRules, adapter.diffItemCallBack)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initSelectedName(tocRules: List<TxtTocRule>) {
|
|
||||||
if (selectedName == null && durRegex != null) {
|
|
||||||
tocRules.forEach {
|
|
||||||
if (durRegex == it.rule) {
|
|
||||||
selectedName = it.name
|
|
||||||
return@forEach
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (selectedName == null) {
|
|
||||||
selectedName = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMenuItemClick(item: MenuItem?): Boolean {
|
|
||||||
when (item?.itemId) {
|
|
||||||
R.id.menu_add -> showDialogFragment(TxtTocRuleEditDialog())
|
|
||||||
R.id.menu_import_local -> importDoc.launch {
|
|
||||||
mode = HandleFileContract.FILE
|
|
||||||
allowExtensions = arrayOf("txt", "json")
|
|
||||||
}
|
|
||||||
R.id.menu_import_onLine -> showImportDialog()
|
|
||||||
R.id.menu_import_qr -> qrCodeResult.launch()
|
|
||||||
R.id.menu_help -> showHelp("txtTocRuleHelp")
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun saveTxtTocRule(txtTocRule: TxtTocRule) {
|
|
||||||
//viewModel.update(txtTocRule)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("InflateParams")
|
|
||||||
private fun showImportDialog() {
|
|
||||||
val aCache = ACache.get(cacheDir = false)
|
|
||||||
val defaultUrl = "https://gitee.com/fisher52/YueDuJson/raw/master/myTxtChapterRule.json"
|
|
||||||
val cacheUrls: MutableList<String> = aCache
|
|
||||||
.getAsString(importTocRuleKey)
|
|
||||||
?.splitNotBlank(",")
|
|
||||||
?.toMutableList()
|
|
||||||
?: mutableListOf()
|
|
||||||
if (!cacheUrls.contains(defaultUrl)) {
|
|
||||||
cacheUrls.add(0, defaultUrl)
|
|
||||||
}
|
|
||||||
requireContext().alert(titleResource = R.string.import_on_line) {
|
|
||||||
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
|
|
||||||
editView.hint = "url"
|
|
||||||
editView.setFilterValues(cacheUrls)
|
|
||||||
editView.delCallBack = {
|
|
||||||
cacheUrls.remove(it)
|
|
||||||
aCache.put(importTocRuleKey, cacheUrls.joinToString(","))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
customView { alertBinding.root }
|
|
||||||
okButton {
|
|
||||||
val text = alertBinding.editView.text?.toString()
|
|
||||||
text?.let {
|
|
||||||
if (it.isAbsUrl() && !cacheUrls.contains(it)) {
|
|
||||||
cacheUrls.add(0, it)
|
|
||||||
aCache.put(importTocRuleKey, cacheUrls.joinToString(","))
|
|
||||||
}
|
|
||||||
showDialogFragment(ImportTxtTocRuleDialog(it))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cancelButton()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class TocRegexAdapter(context: Context) :
|
|
||||||
RecyclerAdapter<TxtTocRule, ItemTocRegexBinding>(context),
|
|
||||||
ItemTouchCallback.Callback {
|
|
||||||
|
|
||||||
val diffItemCallBack = object : DiffUtil.ItemCallback<TxtTocRule>() {
|
|
||||||
|
|
||||||
override fun areItemsTheSame(oldItem: TxtTocRule, newItem: TxtTocRule): Boolean {
|
|
||||||
return oldItem.id == newItem.id
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun areContentsTheSame(oldItem: TxtTocRule, newItem: TxtTocRule): Boolean {
|
|
||||||
if (oldItem.name != newItem.name) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (oldItem.enable != newItem.enable) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (oldItem.example != newItem.example) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getChangePayload(oldItem: TxtTocRule, newItem: TxtTocRule): Any? {
|
|
||||||
val payload = Bundle()
|
|
||||||
if (oldItem.name != newItem.name) {
|
|
||||||
payload.putBoolean("upName", true)
|
|
||||||
}
|
|
||||||
if (oldItem.enable != newItem.enable) {
|
|
||||||
payload.putBoolean("enabled", newItem.enable)
|
|
||||||
}
|
|
||||||
if (oldItem.example != newItem.example) {
|
|
||||||
payload.putBoolean("upExample", true)
|
|
||||||
}
|
|
||||||
if (payload.isEmpty) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return payload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getViewBinding(parent: ViewGroup): ItemTocRegexBinding {
|
|
||||||
return ItemTocRegexBinding.inflate(inflater, parent, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun convert(
|
|
||||||
holder: ItemViewHolder,
|
|
||||||
binding: ItemTocRegexBinding,
|
|
||||||
item: TxtTocRule,
|
|
||||||
payloads: MutableList<Any>
|
|
||||||
) {
|
|
||||||
binding.apply {
|
|
||||||
if (payloads.isEmpty()) {
|
|
||||||
//root.setBackgroundColor(context.backgroundColor)
|
|
||||||
rbRegexName.text = item.name
|
|
||||||
titleExample.text = item.example
|
|
||||||
rbRegexName.isChecked = item.name == selectedName
|
|
||||||
swtEnabled.isChecked = item.enable
|
|
||||||
} else {
|
|
||||||
for (i in payloads.indices) {
|
|
||||||
val bundle = payloads[i] as Bundle
|
|
||||||
bundle.keySet().forEach {
|
|
||||||
when (it) {
|
|
||||||
"upName" -> rbRegexName.text = item.name
|
|
||||||
"upExample" -> titleExample.text = item.example
|
|
||||||
"enabled" -> swtEnabled.isChecked = item.enable
|
|
||||||
"upSelect" -> rbRegexName.isChecked = item.name == selectedName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun registerListener(holder: ItemViewHolder, binding: ItemTocRegexBinding) {
|
|
||||||
binding.apply {
|
|
||||||
rbRegexName.setOnCheckedChangeListener { buttonView, isChecked ->
|
|
||||||
if (buttonView.isPressed && isChecked) {
|
|
||||||
selectedName = getItem(holder.layoutPosition)?.name
|
|
||||||
updateItems(0, itemCount - 1, bundleOf("upSelect" to null))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
swtEnabled.setOnCheckedChangeListener { buttonView, isChecked ->
|
|
||||||
if (buttonView.isPressed) {
|
|
||||||
getItem(holder.layoutPosition)?.let {
|
|
||||||
it.enable = isChecked
|
|
||||||
//viewModel.update(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ivEdit.setOnClickListener {
|
|
||||||
showDialogFragment(TxtTocRuleEditDialog(getItem(holder.layoutPosition)?.id))
|
|
||||||
}
|
|
||||||
ivDelete.setOnClickListener {
|
|
||||||
getItem(holder.layoutPosition)?.let { item ->
|
|
||||||
alert(R.string.draw) {
|
|
||||||
setMessage(getString(R.string.sure_del) + "\n" + item.name)
|
|
||||||
noButton()
|
|
||||||
yesButton {
|
|
||||||
//viewModel.delete(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var isMoved = false
|
|
||||||
|
|
||||||
override fun swap(srcPosition: Int, targetPosition: Int): Boolean {
|
|
||||||
swapItem(srcPosition, targetPosition)
|
|
||||||
isMoved = true
|
|
||||||
return super.swap(srcPosition, targetPosition)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onClearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
|
|
||||||
super.onClearView(recyclerView, viewHolder)
|
|
||||||
if (isMoved) {
|
|
||||||
for ((index, item) in getItems().withIndex()) {
|
|
||||||
item.serialNumber = index + 1
|
|
||||||
}
|
|
||||||
//viewModel.update(*getItems().toTypedArray())
|
|
||||||
}
|
|
||||||
isMoved = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CallBack {
|
|
||||||
fun onTocRegexDialogResult(tocRegex: String) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
package io.legado.app.ui.book.toc.rule
|
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.appcompat.widget.Toolbar
|
|
||||||
import androidx.fragment.app.viewModels
|
|
||||||
import io.legado.app.R
|
|
||||||
import io.legado.app.base.BaseBottomSheetDialogFragment
|
|
||||||
import io.legado.app.base.BaseViewModel
|
|
||||||
import io.legado.app.constant.AppLog
|
|
||||||
import io.legado.app.data.appDb
|
|
||||||
import io.legado.app.data.entities.TxtTocRule
|
|
||||||
import io.legado.app.databinding.DialogTocRegexEditBinding
|
|
||||||
import io.legado.app.exception.NoStackTraceException
|
|
||||||
//import io.legado.app.lib.theme.primaryColor
|
|
||||||
import io.legado.app.utils.*
|
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import java.util.regex.Pattern
|
|
||||||
import java.util.regex.PatternSyntaxException
|
|
||||||
|
|
||||||
class TxtTocRuleEditDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_toc_regex_edit),
|
|
||||||
Toolbar.OnMenuItemClickListener {
|
|
||||||
|
|
||||||
constructor(id: Long?) : this() {
|
|
||||||
id ?: return
|
|
||||||
arguments = Bundle().apply {
|
|
||||||
putLong("id", id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val binding by viewBinding(DialogTocRegexEditBinding::bind)
|
|
||||||
private val viewModel by viewModels<ViewModel>()
|
|
||||||
private val callback get() = (parentFragment as? Callback) ?: activity as? Callback
|
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
//binding.toolBar.setBackgroundColor(primaryColor)
|
|
||||||
initMenu()
|
|
||||||
viewModel.initData(arguments?.getLong("id")) {
|
|
||||||
upRuleView(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initMenu() {
|
|
||||||
binding.toolBar.inflateMenu(R.menu.txt_toc_rule_edit)
|
|
||||||
//binding.toolBar.menu.applyTint(requireContext())
|
|
||||||
binding.toolBar.setOnMenuItemClickListener(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMenuItemClick(item: MenuItem?): Boolean {
|
|
||||||
when (item?.itemId) {
|
|
||||||
R.id.menu_save -> {
|
|
||||||
val tocRule = getRuleFromView()
|
|
||||||
if (checkValid(tocRule)) {
|
|
||||||
callback?.saveTxtTocRule(getRuleFromView())
|
|
||||||
dismissAllowingStateLoss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
R.id.menu_copy_rule -> context?.sendToClip(GSON.toJson(getRuleFromView()))
|
|
||||||
R.id.menu_paste_rule -> viewModel.pasteRule {
|
|
||||||
upRuleView(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkValid(tocRule: TxtTocRule): Boolean {
|
|
||||||
if (tocRule.name.isEmpty()) {
|
|
||||||
toastOnUi("名称不能为空")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Pattern.compile(tocRule.rule, Pattern.MULTILINE)
|
|
||||||
} catch (ex: PatternSyntaxException) {
|
|
||||||
AppLog.put("正则语法错误或不支持(txt):${ex.localizedMessage}", ex, true)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun upRuleView(tocRule: TxtTocRule?) {
|
|
||||||
binding.tvRuleName.setText(tocRule?.name)
|
|
||||||
binding.tvRuleRegex.setText(tocRule?.rule)
|
|
||||||
binding.tvRuleExample.setText(tocRule?.example)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getRuleFromView(): TxtTocRule {
|
|
||||||
val tocRule = viewModel.tocRule ?: TxtTocRule().apply {
|
|
||||||
viewModel.tocRule = this
|
|
||||||
}
|
|
||||||
binding.run {
|
|
||||||
tocRule.name = tvRuleName.text.toString()
|
|
||||||
tocRule.rule = tvRuleRegex.text.toString()
|
|
||||||
tocRule.example = tvRuleExample.text.toString()
|
|
||||||
}
|
|
||||||
return tocRule
|
|
||||||
}
|
|
||||||
|
|
||||||
class ViewModel(application: Application) : BaseViewModel(application) {
|
|
||||||
|
|
||||||
var tocRule: TxtTocRule? = null
|
|
||||||
|
|
||||||
fun initData(id: Long?, finally: (tocRule: TxtTocRule?) -> Unit) {
|
|
||||||
if (tocRule != null) return
|
|
||||||
execute {
|
|
||||||
if (id == null) return@execute
|
|
||||||
tocRule = appDb.txtTocRuleDao.get(id)
|
|
||||||
}.onFinally {
|
|
||||||
finally.invoke(tocRule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun pasteRule(success: (TxtTocRule) -> Unit) {
|
|
||||||
execute(context = Dispatchers.Main) {
|
|
||||||
val text = context.getClipText()
|
|
||||||
if (text.isNullOrBlank()) {
|
|
||||||
throw NoStackTraceException("剪贴板为空")
|
|
||||||
}
|
|
||||||
GSON.fromJsonObject<TxtTocRule>(text).getOrNull()
|
|
||||||
?: throw NoStackTraceException("格式不对")
|
|
||||||
}.onSuccess {
|
|
||||||
success.invoke(it)
|
|
||||||
}.onError {
|
|
||||||
context.toastOnUi(it.localizedMessage ?: "Error")
|
|
||||||
it.printOnDebug()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Callback {
|
|
||||||
|
|
||||||
fun saveTxtTocRule(txtTocRule: TxtTocRule)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package io.legado.app.ui.config
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.View
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import io.legado.app.R
|
|
||||||
import io.legado.app.base.BaseBottomSheetDialogFragment
|
|
||||||
import io.legado.app.databinding.DialogCoverRuleConfigBinding
|
|
||||||
//import io.legado.app.lib.theme.primaryColor
|
|
||||||
import io.legado.app.model.BookCover
|
|
||||||
import io.legado.app.utils.GSON
|
|
||||||
import io.legado.app.utils.toastOnUi
|
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import splitties.views.onClick
|
|
||||||
|
|
||||||
class CoverRuleConfigDialog : BaseBottomSheetDialogFragment(R.layout.dialog_cover_rule_config) {
|
|
||||||
|
|
||||||
val binding by viewBinding(DialogCoverRuleConfigBinding::bind)
|
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
//binding.toolBar.setBackgroundColor(primaryColor)
|
|
||||||
initData()
|
|
||||||
binding.tvCancel.onClick {
|
|
||||||
dismissAllowingStateLoss()
|
|
||||||
}
|
|
||||||
binding.tvOk.onClick {
|
|
||||||
val enable = binding.cbEnable.isChecked
|
|
||||||
val searchUrl = binding.editSearchUrl.text?.toString()
|
|
||||||
val coverRule = binding.editCoverUrlRule.text?.toString()
|
|
||||||
if (searchUrl.isNullOrBlank() || coverRule.isNullOrBlank()) {
|
|
||||||
toastOnUi("搜索url和cover规则不能为空")
|
|
||||||
} else {
|
|
||||||
BookCover.CoverRule(enable, searchUrl, coverRule).let { config ->
|
|
||||||
BookCover.saveCoverRule(config)
|
|
||||||
}
|
|
||||||
dismissAllowingStateLoss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
binding.tvFooterLeft.onClick {
|
|
||||||
BookCover.delCoverRule()
|
|
||||||
dismissAllowingStateLoss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initData() {
|
|
||||||
lifecycleScope.launch {
|
|
||||||
val rule = withContext(IO) {
|
|
||||||
BookCover.getCoverRule()
|
|
||||||
}
|
|
||||||
Log.e("coverRule", GSON.toJson(rule))
|
|
||||||
binding.cbEnable.isChecked = rule.enable
|
|
||||||
binding.editSearchUrl.setText(rule.searchUrl)
|
|
||||||
binding.editCoverUrlRule.setText(rule.coverRule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
package io.legado.app.ui.config
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import androidx.appcompat.widget.Toolbar
|
|
||||||
import io.legado.app.R
|
|
||||||
import io.legado.app.base.BaseBottomSheetDialogFragment
|
|
||||||
import io.legado.app.databinding.DialogDirectLinkUploadConfigBinding
|
|
||||||
import io.legado.app.help.DirectLinkUpload
|
|
||||||
import io.legado.app.lib.dialogs.alert
|
|
||||||
import io.legado.app.lib.dialogs.selector
|
|
||||||
//import io.legado.app.lib.theme.primaryColor
|
|
||||||
import io.legado.app.utils.GSON
|
|
||||||
import io.legado.app.utils.applyTint
|
|
||||||
import io.legado.app.utils.fromJsonObject
|
|
||||||
import io.legado.app.utils.getClipText
|
|
||||||
import io.legado.app.utils.sendToClip
|
|
||||||
import io.legado.app.utils.toastOnUi
|
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
|
||||||
import splitties.init.appCtx
|
|
||||||
import splitties.views.onClick
|
|
||||||
|
|
||||||
class DirectLinkUploadConfig : BaseBottomSheetDialogFragment(R.layout.dialog_direct_link_upload_config),
|
|
||||||
Toolbar.OnMenuItemClickListener {
|
|
||||||
|
|
||||||
private val binding by viewBinding(DialogDirectLinkUploadConfigBinding::bind)
|
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
//setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
//binding.toolBar.setBackgroundColor(primaryColor)
|
|
||||||
binding.toolBar.inflateMenu(R.menu.direct_link_upload_config)
|
|
||||||
binding.toolBar.menu.applyTint(requireContext())
|
|
||||||
binding.toolBar.setOnMenuItemClickListener(this)
|
|
||||||
upView(DirectLinkUpload.getRule())
|
|
||||||
binding.tvCancel.onClick {
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
binding.tvFooterLeft.onClick {
|
|
||||||
test()
|
|
||||||
}
|
|
||||||
binding.tvOk.onClick {
|
|
||||||
getRule()?.let { rule ->
|
|
||||||
DirectLinkUpload.putConfig(rule)
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMenuItemClick(item: MenuItem?): Boolean {
|
|
||||||
when (item?.itemId) {
|
|
||||||
R.id.menu_import_default -> importDefault()
|
|
||||||
R.id.menu_copy_rule -> getRule()?.let { rule ->
|
|
||||||
requireContext().sendToClip(GSON.toJson(rule))
|
|
||||||
}
|
|
||||||
|
|
||||||
R.id.menu_paste_rule -> runCatching {
|
|
||||||
requireContext().getClipText()!!.let {
|
|
||||||
val rule = GSON.fromJsonObject<DirectLinkUpload.Rule>(it).getOrThrow()
|
|
||||||
upView(rule)
|
|
||||||
}
|
|
||||||
}.onFailure {
|
|
||||||
toastOnUi("剪贴板为空或格式不对")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun upView(rule: DirectLinkUpload.Rule) {
|
|
||||||
binding.editUploadUrl.setText(rule.uploadUrl)
|
|
||||||
binding.editDownloadUrlRule.setText(rule.downloadUrlRule)
|
|
||||||
binding.editSummary.setText(rule.summary)
|
|
||||||
binding.cbCompress.isChecked = rule.compress
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getRule(): DirectLinkUpload.Rule? {
|
|
||||||
val uploadUrl = binding.editUploadUrl.text?.toString()
|
|
||||||
val downloadUrlRule = binding.editDownloadUrlRule.text?.toString()
|
|
||||||
val summary = binding.editSummary.text?.toString()
|
|
||||||
val compress = binding.cbCompress.isChecked
|
|
||||||
if (uploadUrl.isNullOrBlank()) {
|
|
||||||
toastOnUi("上传Url不能为空")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
if (downloadUrlRule.isNullOrBlank()) {
|
|
||||||
toastOnUi("下载Url规则不能为空")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
if (summary.isNullOrBlank()) {
|
|
||||||
toastOnUi("注释不能为空")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return DirectLinkUpload.Rule(uploadUrl, downloadUrlRule, summary, compress)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun importDefault() {
|
|
||||||
requireContext().selector(DirectLinkUpload.defaultRules) { _, rule, _ ->
|
|
||||||
upView(rule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun test() {
|
|
||||||
val rule = getRule() ?: return
|
|
||||||
execute {
|
|
||||||
DirectLinkUpload.upLoad("test.json", "{}", "application/json", rule)
|
|
||||||
}.onError {
|
|
||||||
alertTestResult(it.localizedMessage ?: "ERROR")
|
|
||||||
}.onSuccess { result ->
|
|
||||||
alertTestResult(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun alertTestResult(result: String) {
|
|
||||||
alert {
|
|
||||||
setTitle("result")
|
|
||||||
setMessage(result)
|
|
||||||
okButton()
|
|
||||||
negativeButton(R.string.copy_text) {
|
|
||||||
appCtx.sendToClip(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -2,105 +2,56 @@ package io.legado.app.ui.config.coverConfig
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Save
|
import androidx.compose.material.icons.filled.Save
|
||||||
import androidx.compose.material.icons.filled.SettingsBackupRestore
|
import androidx.compose.material.icons.filled.SettingsBackupRestore
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.Checkbox
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.OutlinedButton
|
|
||||||
import androidx.compose.material3.TextButton
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
|
import io.legado.app.help.DefaultData
|
||||||
import io.legado.app.model.BookCover
|
import io.legado.app.model.BookCover
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
|
||||||
import io.legado.app.ui.widget.components.AppTextField
|
import io.legado.app.ui.widget.components.AppTextField
|
||||||
import io.legado.app.ui.widget.components.button.MediumIconButton
|
import io.legado.app.ui.widget.components.button.MediumIconButton
|
||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
|
||||||
import io.legado.app.ui.widget.components.checkBox.CheckboxItem
|
import io.legado.app.ui.widget.components.checkBox.CheckboxItem
|
||||||
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
|
|
||||||
private const val DEFAULT_SEARCH_URL = "data:;base64,{{java.base64Encode(key)}},{\"type\":\"lyc\"}"
|
|
||||||
private val DEFAULT_COVER_RULE = """
|
|
||||||
@js:
|
|
||||||
var key = java.hexDecodeToString(result);
|
|
||||||
var url1 = `https://pre-api.tuishujun.com/api/searchBook?search_value=${'$'}{key}&page=1&pageSize=20`;
|
|
||||||
var url2 = `http://m.ypshuo.com/api/novel/search?keyword=${'$'}{key}&searchType=1&page=1`;
|
|
||||||
var [rr1, rr2] = java.ajaxAll([url1, url2]).map(r => r.body());
|
|
||||||
function jjson(str, rule) {
|
|
||||||
try {
|
|
||||||
return com.jayway.jsonpath.JsonPath.read(str, rule);
|
|
||||||
} catch (e) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rr1 = jjson(rr1, '$.data.data[*]');
|
|
||||||
rr2 = jjson(rr2, '$.data.data[*]');
|
|
||||||
var na = String(book.name),
|
|
||||||
au = String(book.author);
|
|
||||||
function search() {
|
|
||||||
for (let char of rr1) {
|
|
||||||
//本地书名包含搜索结果书名
|
|
||||||
if (na.includes(char.title + '')) {
|
|
||||||
let au2 = char.author_nickname + '';
|
|
||||||
//作者匹配
|
|
||||||
if (au.includes(au2) || au2.includes(au)) {
|
|
||||||
return char.cover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let char of rr2) {
|
|
||||||
if (na.includes(char.novel_name + '')) {
|
|
||||||
let au2 = char.author_name + '';
|
|
||||||
if (au.includes(au2) || au2.includes(au)) {
|
|
||||||
return char.novel_img;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
search()
|
|
||||||
""".trimIndent()
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CoverRuleConfigSheet(
|
fun CoverRuleConfigSheet(
|
||||||
show: Boolean,
|
show: Boolean,
|
||||||
onDismissRequest: () -> Unit
|
onDismissRequest: () -> Unit
|
||||||
) {
|
) {
|
||||||
|
var ruleState by remember { mutableStateOf<BookCover.CoverRule?>(null) }
|
||||||
var enable by remember { mutableStateOf(false) }
|
var enable by remember { mutableStateOf(false) }
|
||||||
var searchUrl by remember { mutableStateOf("") }
|
var searchUrl by remember { mutableStateOf("") }
|
||||||
var coverRule by remember { mutableStateOf("") }
|
var coverRule by remember { mutableStateOf("") }
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(show) {
|
||||||
val rule = withContext(Dispatchers.IO) {
|
if (show) {
|
||||||
BookCover.getCoverRule()
|
val rule = withContext(Dispatchers.IO) {
|
||||||
|
BookCover.getCoverRule()
|
||||||
|
}
|
||||||
|
ruleState = rule
|
||||||
|
enable = rule.enable
|
||||||
|
searchUrl = rule.searchUrl
|
||||||
|
coverRule = rule.coverRule
|
||||||
}
|
}
|
||||||
enable = rule.enable
|
|
||||||
searchUrl = rule.searchUrl
|
|
||||||
coverRule = rule.coverRule
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AppModalBottomSheet(
|
AppModalBottomSheet(
|
||||||
@@ -111,8 +62,11 @@ fun CoverRuleConfigSheet(
|
|||||||
MediumIconButton(
|
MediumIconButton(
|
||||||
imageVector = Icons.Default.SettingsBackupRestore,
|
imageVector = Icons.Default.SettingsBackupRestore,
|
||||||
onClick = {
|
onClick = {
|
||||||
searchUrl = DEFAULT_SEARCH_URL
|
DefaultData.coverRule.let {
|
||||||
coverRule = DEFAULT_COVER_RULE
|
enable = it.enable
|
||||||
|
searchUrl = it.searchUrl
|
||||||
|
coverRule = it.coverRule
|
||||||
|
}
|
||||||
appCtx.toastOnUi(R.string.restore_default)
|
appCtx.toastOnUi(R.string.restore_default)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -124,8 +78,16 @@ fun CoverRuleConfigSheet(
|
|||||||
if (searchUrl.isBlank() || coverRule.isBlank()) {
|
if (searchUrl.isBlank() || coverRule.isBlank()) {
|
||||||
appCtx.toastOnUi("搜索url和cover规则不能为空")
|
appCtx.toastOnUi("搜索url和cover规则不能为空")
|
||||||
} else {
|
} else {
|
||||||
BookCover.CoverRule(enable, searchUrl, coverRule).let { config ->
|
val newConfig = ruleState?.copy(
|
||||||
BookCover.saveCoverRule(config)
|
enable = enable,
|
||||||
|
searchUrl = searchUrl,
|
||||||
|
coverRule = coverRule
|
||||||
|
) ?: BookCover.CoverRule(enable, searchUrl, coverRule)
|
||||||
|
|
||||||
|
if (newConfig == DefaultData.coverRule) {
|
||||||
|
BookCover.delCoverRule()
|
||||||
|
} else {
|
||||||
|
BookCover.saveCoverRule(newConfig)
|
||||||
}
|
}
|
||||||
onDismissRequest()
|
onDismissRequest()
|
||||||
}
|
}
|
||||||
@@ -136,6 +98,7 @@ fun CoverRuleConfigSheet(
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 24.dp)
|
||||||
.verticalScroll(rememberScrollState()),
|
.verticalScroll(rememberScrollState()),
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ import io.legado.app.ui.config.themeConfig.ThemeConfig
|
|||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.widget.components.card.NormalCard
|
import io.legado.app.ui.widget.components.card.NormalCard
|
||||||
import io.legado.app.ui.widget.components.card.TextCard
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
import io.legado.app.ui.widget.components.cover.BookshelfCover
|
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
|
||||||
import io.legado.app.ui.widget.components.icon.AppIcon
|
import io.legado.app.ui.widget.components.icon.AppIcon
|
||||||
|
import io.legado.app.ui.widget.components.image.cover.BookshelfCover
|
||||||
|
import io.legado.app.ui.widget.components.image.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
import io.legado.app.utils.toTimeAgo
|
import io.legado.app.utils.toTimeAgo
|
||||||
|
|
||||||
@@ -214,7 +214,7 @@ fun BookshelfItem(
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.padding(top = 4.dp, bottom = 4.dp, end = 4.dp),
|
.padding(top = 4.dp, bottom = 4.dp, end = 8.dp, start = 4.dp),
|
||||||
verticalArrangement = Arrangement.Center
|
verticalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
@@ -232,7 +232,7 @@ fun BookshelfItem(
|
|||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
titleEnd?.let {
|
titleEnd?.let {
|
||||||
Box(modifier = Modifier.padding(top = 4.dp)) {
|
Box(modifier = Modifier.padding(top = 4.dp, start = 4.dp)) {
|
||||||
it.invoke()
|
it.invoke()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -523,7 +523,7 @@ fun BookGroupItemHorizontalCovers(
|
|||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(vertical = 4.dp),
|
.padding(vertical = 8.dp, horizontal = 4.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import androidx.compose.material.icons.filled.Refresh
|
|||||||
import androidx.compose.material.icons.filled.Search
|
import androidx.compose.material.icons.filled.Search
|
||||||
import androidx.compose.material.icons.filled.VerticalAlignTop
|
import androidx.compose.material.icons.filled.VerticalAlignTop
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import io.legado.app.ui.widget.components.progressIndicator.AppCircularProgressIndicator
|
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.ListItem
|
import androidx.compose.material3.ListItem
|
||||||
import androidx.compose.material3.ListItemDefaults
|
import androidx.compose.material3.ListItemDefaults
|
||||||
@@ -41,8 +40,8 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.rotate
|
import androidx.compose.ui.draw.rotate
|
||||||
@@ -53,23 +52,22 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.data.entities.BookSourcePart
|
import io.legado.app.data.entities.BookSourcePart
|
||||||
|
import io.legado.app.domain.usecase.ExploreKindUiUseCase
|
||||||
import io.legado.app.help.source.getExploreInfoMap
|
import io.legado.app.help.source.getExploreInfoMap
|
||||||
import io.legado.app.ui.widget.components.explore.ExploreKindUiUseCase
|
|
||||||
import io.legado.app.ui.book.search.SearchActivity
|
import io.legado.app.ui.book.search.SearchActivity
|
||||||
import io.legado.app.ui.book.search.SearchScope
|
import io.legado.app.ui.book.search.SearchScope
|
||||||
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
|
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
|
||||||
import io.legado.app.ui.login.SourceLoginActivity
|
import io.legado.app.ui.login.SourceLoginActivity
|
||||||
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.theme.LegadoTheme.composeEngine
|
import io.legado.app.ui.theme.LegadoTheme.composeEngine
|
||||||
import io.legado.app.ui.theme.ThemeResolver
|
import io.legado.app.ui.theme.ThemeResolver
|
||||||
import io.legado.app.ui.theme.adaptiveContentPadding
|
import io.legado.app.ui.theme.adaptiveContentPadding
|
||||||
|
import io.legado.app.ui.widget.components.EmptyMessage
|
||||||
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
import io.legado.app.ui.widget.components.card.GlassCard
|
||||||
import io.legado.app.ui.widget.components.card.TextCard
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
import io.legado.app.ui.widget.components.divider.PillHeaderDivider
|
import io.legado.app.ui.widget.components.divider.PillHeaderDivider
|
||||||
import io.legado.app.ui.widget.components.explore.ExploreKindMultiTypeItem
|
import io.legado.app.ui.widget.components.explore.ExploreKindMultiTypeItem
|
||||||
import io.legado.app.ui.widget.components.EmptyMessage
|
|
||||||
import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn
|
import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn
|
||||||
import io.legado.app.ui.widget.components.list.ListScaffold
|
import io.legado.app.ui.widget.components.list.ListScaffold
|
||||||
import io.legado.app.ui.widget.components.list.TopFloatingStickyItem
|
import io.legado.app.ui.widget.components.list.TopFloatingStickyItem
|
||||||
@@ -79,7 +77,6 @@ import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
|||||||
import io.legado.app.ui.widget.components.progressIndicator.AppContainedLoadingIndicator
|
import io.legado.app.ui.widget.components.progressIndicator.AppContainedLoadingIndicator
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
import io.legado.app.utils.startActivity
|
import io.legado.app.utils.startActivity
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.androidx.compose.koinViewModel
|
import org.koin.androidx.compose.koinViewModel
|
||||||
import org.koin.compose.koinInject
|
import org.koin.compose.koinInject
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import io.legado.app.base.BaseViewModel
|
|||||||
import io.legado.app.data.entities.BookSourcePart
|
import io.legado.app.data.entities.BookSourcePart
|
||||||
import io.legado.app.data.entities.rule.ExploreKind
|
import io.legado.app.data.entities.rule.ExploreKind
|
||||||
import io.legado.app.data.repository.ExploreRepository
|
import io.legado.app.data.repository.ExploreRepository
|
||||||
|
import io.legado.app.domain.usecase.ExploreKindUiUseCase
|
||||||
import io.legado.app.help.source.clearExploreKindsCache
|
import io.legado.app.help.source.clearExploreKindsCache
|
||||||
import io.legado.app.help.source.exploreKinds
|
import io.legado.app.help.source.exploreKinds
|
||||||
import io.legado.app.help.source.getExploreInfoMap
|
import io.legado.app.help.source.getExploreInfoMap
|
||||||
import io.legado.app.ui.widget.components.explore.ExploreKindUiUseCase
|
|
||||||
import io.legado.app.ui.widget.components.explore.calculateExploreKindRows
|
import io.legado.app.ui.widget.components.explore.calculateExploreKindRows
|
||||||
import io.legado.app.ui.widget.components.list.ListUiState
|
import io.legado.app.ui.widget.components.list.ListUiState
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|||||||
@@ -52,12 +52,12 @@ import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
|
|||||||
import io.legado.app.ui.rss.source.manage.RssSourceActivity
|
import io.legado.app.ui.rss.source.manage.RssSourceActivity
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.theme.adaptiveContentPadding
|
import io.legado.app.ui.theme.adaptiveContentPadding
|
||||||
import io.legado.app.ui.widget.components.SourceIcon
|
|
||||||
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
import io.legado.app.ui.widget.components.card.GlassCard
|
||||||
import io.legado.app.ui.widget.components.divider.PillDivider
|
import io.legado.app.ui.widget.components.divider.PillDivider
|
||||||
import io.legado.app.ui.widget.components.divider.PillHeaderDivider
|
import io.legado.app.ui.widget.components.divider.PillHeaderDivider
|
||||||
import io.legado.app.ui.widget.components.icon.AppIcon
|
import io.legado.app.ui.widget.components.icon.AppIcon
|
||||||
|
import io.legado.app.ui.widget.components.image.sourceIcon.SourceIcon
|
||||||
import io.legado.app.ui.widget.components.list.ListScaffold
|
import io.legado.app.ui.widget.components.list.ListScaffold
|
||||||
import io.legado.app.ui.widget.components.menuItem.MenuItemIcon
|
import io.legado.app.ui.widget.components.menuItem.MenuItemIcon
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ import io.legado.app.ui.theme.adaptiveContentPadding
|
|||||||
import io.legado.app.ui.widget.components.AppPullToRefresh
|
import io.legado.app.ui.widget.components.AppPullToRefresh
|
||||||
import io.legado.app.ui.widget.components.EmptyMessage
|
import io.legado.app.ui.widget.components.EmptyMessage
|
||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
import io.legado.app.ui.widget.components.card.GlassCard
|
||||||
import io.legado.app.ui.widget.components.cover.buildCoverImageRequest
|
import io.legado.app.ui.widget.components.image.cover.buildCoverImageRequest
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ import io.legado.app.data.entities.RssStar
|
|||||||
import io.legado.app.ui.theme.adaptiveContentPadding
|
import io.legado.app.ui.theme.adaptiveContentPadding
|
||||||
import io.legado.app.ui.widget.components.ActionItem
|
import io.legado.app.ui.widget.components.ActionItem
|
||||||
import io.legado.app.ui.widget.components.EmptyMessage
|
import io.legado.app.ui.widget.components.EmptyMessage
|
||||||
import io.legado.app.ui.widget.components.SourceIcon
|
|
||||||
import io.legado.app.ui.widget.components.button.SmallIconButton
|
import io.legado.app.ui.widget.components.button.SmallIconButton
|
||||||
import io.legado.app.ui.widget.components.card.SelectionItemCard
|
import io.legado.app.ui.widget.components.card.SelectionItemCard
|
||||||
import io.legado.app.ui.widget.components.dialog.TextListInputDialog
|
import io.legado.app.ui.widget.components.dialog.TextListInputDialog
|
||||||
import io.legado.app.ui.widget.components.divider.PillDivider
|
import io.legado.app.ui.widget.components.divider.PillDivider
|
||||||
|
import io.legado.app.ui.widget.components.image.sourceIcon.SourceIcon
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
||||||
import io.legado.app.ui.widget.components.rules.RuleListScaffold
|
import io.legado.app.ui.widget.components.rules.RuleListScaffold
|
||||||
import org.koin.androidx.compose.koinViewModel
|
import org.koin.androidx.compose.koinViewModel
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,4 @@
|
|||||||
package io.legado.app.ui.widget
|
package io.legado.app.ui.widget.components
|
||||||
|
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -10,7 +10,6 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.filled.ExpandMore
|
import androidx.compose.material.icons.filled.ExpandMore
|
||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
package io.legado.app.ui.widget.components
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SectionHeader(
|
|
||||||
// 左侧主标题内容
|
|
||||||
titleContent: @Composable () -> Unit,
|
|
||||||
// 右侧或副标题内容
|
|
||||||
detailContent: @Composable (() -> Unit)? = null,
|
|
||||||
// 主要内容的排列方式
|
|
||||||
verticalArrangement: Arrangement.Vertical = Arrangement.Center,
|
|
||||||
// 定义水平对齐方式
|
|
||||||
horizontalArrangement: Arrangement.Horizontal = Arrangement.SpaceBetween,
|
|
||||||
// 根容器的 Padding
|
|
||||||
contentPadding: PaddingValues = PaddingValues(horizontal = 16.dp, vertical = 8.dp)
|
|
||||||
) {
|
|
||||||
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(contentPadding),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = horizontalArrangement
|
|
||||||
) {
|
|
||||||
titleContent()
|
|
||||||
detailContent?.let {
|
|
||||||
it()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -144,6 +144,7 @@ fun <T> AppAlertDialog(
|
|||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
title: String? = null,
|
title: String? = null,
|
||||||
text: String? = null,
|
text: String? = null,
|
||||||
|
textProvider: @Composable (T.() -> String)? = null,
|
||||||
confirmText: String = "确定",
|
confirmText: String = "确定",
|
||||||
onConfirm: ((T) -> Unit)? = null,
|
onConfirm: ((T) -> Unit)? = null,
|
||||||
dismissText: String = "取消",
|
dismissText: String = "取消",
|
||||||
@@ -159,11 +160,17 @@ fun <T> AppAlertDialog(
|
|||||||
|
|
||||||
val currentData = cachedData
|
val currentData = cachedData
|
||||||
if (currentData != null) {
|
if (currentData != null) {
|
||||||
|
val currentText = text ?: textProvider?.invoke(currentData)
|
||||||
|
var cachedText by remember { mutableStateOf(currentText) }
|
||||||
|
if (currentText != null) {
|
||||||
|
cachedText = currentText
|
||||||
|
}
|
||||||
|
|
||||||
AppAlertDialog(
|
AppAlertDialog(
|
||||||
show = data != null,
|
show = data != null,
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
title = title,
|
title = title,
|
||||||
text = text,
|
text = currentText ?: cachedText,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
confirmText = confirmText,
|
confirmText = confirmText,
|
||||||
onConfirm = onConfirm?.let { { it(currentData) } },
|
onConfirm = onConfirm?.let { { it(currentData) } },
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import io.legado.app.data.entities.SearchBook
|
|||||||
import io.legado.app.domain.model.BookShelfState
|
import io.legado.app.domain.model.BookShelfState
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.widget.components.card.TextCard
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
import io.legado.app.ui.widget.components.cover.CoilBookCover
|
import io.legado.app.ui.widget.components.image.cover.CoilBookCover
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
|
|
||||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
package io.legado.app.ui.widget.components.cover
|
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.RowScope
|
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.Book
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.layout.ContentScale
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import coil.ImageLoader
|
|
||||||
import coil.compose.AsyncImage
|
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
|
||||||
import org.koin.compose.koinInject
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun Cover(
|
|
||||||
path: Any?,
|
|
||||||
modifier: Modifier = Modifier.width(48.dp),
|
|
||||||
badgeContent: (@Composable RowScope.() -> Unit)? = null,
|
|
||||||
loadOnlyWifi: Boolean = false,
|
|
||||||
sourceOrigin: String? = null,
|
|
||||||
imageLoader: ImageLoader = koinInject(),
|
|
||||||
onLoadFinish: (() -> Unit)? = null
|
|
||||||
) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
val boxModifier = modifier
|
|
||||||
.aspectRatio(3f / 4f)
|
|
||||||
.clip(RoundedCornerShape(4.dp))
|
|
||||||
.background(LegadoTheme.colorScheme.surfaceContainer)
|
|
||||||
|
|
||||||
Box(modifier = boxModifier) {
|
|
||||||
if (path == null) {
|
|
||||||
Icon(
|
|
||||||
Icons.Default.Book,
|
|
||||||
contentDescription = null,
|
|
||||||
tint = LegadoTheme.colorScheme.surfaceContainerHighest,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(24.dp)
|
|
||||||
.align(Alignment.Center)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
AsyncImage(
|
|
||||||
model = buildCoverImageRequest(
|
|
||||||
context = context,
|
|
||||||
data = path,
|
|
||||||
sourceOrigin = sourceOrigin,
|
|
||||||
loadOnlyWifi = loadOnlyWifi,
|
|
||||||
crossfade = true,
|
|
||||||
) {
|
|
||||||
listener(
|
|
||||||
onSuccess = { _, _ -> onLoadFinish?.invoke() },
|
|
||||||
onError = { _, _ -> onLoadFinish?.invoke() }
|
|
||||||
)
|
|
||||||
},
|
|
||||||
imageLoader = imageLoader,
|
|
||||||
contentDescription = null,
|
|
||||||
contentScale = ContentScale.Crop,
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (badgeContent != null) {
|
|
||||||
Surface(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.TopEnd)
|
|
||||||
.padding(2.dp),
|
|
||||||
shape = RoundedCornerShape(4.dp),
|
|
||||||
color = LegadoTheme.colorScheme.secondaryContainer,
|
|
||||||
contentColor = LegadoTheme.colorScheme.onSecondaryContainer,
|
|
||||||
tonalElevation = 2.dp
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.padding(2.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.Center,
|
|
||||||
content = badgeContent
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+4
-12
@@ -10,13 +10,9 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowRight
|
|
||||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
||||||
import androidx.compose.material.icons.automirrored.filled.OpenInNew
|
|
||||||
import androidx.compose.material.icons.filled.KeyboardArrowDown
|
|
||||||
import androidx.compose.material.icons.filled.Refresh
|
import androidx.compose.material.icons.filled.Refresh
|
||||||
import androidx.compose.material.icons.filled.UnfoldMore
|
import androidx.compose.material.icons.filled.UnfoldMore
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
@@ -25,32 +21,28 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.LayoutDirection
|
import androidx.compose.ui.unit.LayoutDirection
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.legado.app.App
|
|
||||||
import io.legado.app.data.entities.rule.ExploreKind
|
import io.legado.app.data.entities.rule.ExploreKind
|
||||||
import io.legado.app.ui.widget.components.explore.ExploreKindUiUseCase
|
import io.legado.app.domain.usecase.ExploreKindUiUseCase
|
||||||
import io.legado.app.help.source.getExploreInfoMap
|
import io.legado.app.help.source.getExploreInfoMap
|
||||||
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
|
import io.legado.app.ui.widget.components.icon.AppIcon
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
import io.legado.app.ui.widget.dialog.TextDialog
|
import io.legado.app.ui.widget.dialog.TextDialog
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
|
||||||
import io.legado.app.ui.widget.components.icon.AppIcon
|
|
||||||
import io.legado.app.utils.showDialogFragment
|
import io.legado.app.utils.showDialogFragment
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import top.yukonga.miuix.kmp.icon.MiuixIcons
|
|
||||||
import top.yukonga.miuix.kmp.icon.basic.ArrowUpDown
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ExploreKindMultiTypeItem(
|
fun ExploreKindMultiTypeItem(
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
package io.legado.app.ui.widget.components.cover
|
package io.legado.app.ui.widget.components.image.cover
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibilityScope
|
import androidx.compose.animation.AnimatedVisibilityScope
|
||||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||||
@@ -14,8 +14,8 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
import io.legado.app.ui.widget.components.progressIndicator.AppLinearProgressIndicator
|
|
||||||
import io.legado.app.ui.widget.components.card.TextCard
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
|
import io.legado.app.ui.widget.components.progressIndicator.AppLinearProgressIndicator
|
||||||
|
|
||||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
+7
-4
@@ -1,4 +1,4 @@
|
|||||||
package io.legado.app.ui.widget.components.cover
|
package io.legado.app.ui.widget.components.image.cover
|
||||||
|
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
@@ -15,7 +15,6 @@ import androidx.compose.foundation.isSystemInDarkTheme
|
|||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
@@ -122,7 +121,9 @@ fun CoilBookCover(
|
|||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
imageLoader = koinInject(),
|
imageLoader = koinInject(),
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.clip(RoundedCornerShape(4.dp))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +139,9 @@ fun CoilBookCover(
|
|||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
imageLoader = koinInject(),
|
imageLoader = koinInject(),
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.clip(RoundedCornerShape(4.dp)),
|
||||||
onSuccess = {
|
onSuccess = {
|
||||||
isOnlineCoverLoaded = true
|
isOnlineCoverLoaded = true
|
||||||
onLoadFinish?.invoke()
|
onLoadFinish?.invoke()
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.legado.app.ui.widget.components.cover
|
package io.legado.app.ui.widget.components.image.cover
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.legado.app.ui.widget.components
|
package io.legado.app.ui.widget.components.image.sourceIcon
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -87,6 +87,7 @@ private fun AppTab(
|
|||||||
text = title,
|
text = title,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
style = LegadoTheme.typography.labelLargeEmphasized,
|
||||||
modifier = Modifier.padding(horizontal = 8.dp),
|
modifier = Modifier.padding(horizontal = 8.dp),
|
||||||
color = if (selected) LegadoTheme.colorScheme.primary else LegadoTheme.colorScheme.onSurfaceVariant
|
color = if (selected) LegadoTheme.colorScheme.primary else LegadoTheme.colorScheme.onSurfaceVariant
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in new issue
Block a user