[优化] 修复订阅源问题
This commit is contained in:
@@ -19,7 +19,9 @@ object ShortCuts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun buildBookShelfShortCutInfo(context: Context): ShortcutInfoCompat {
|
private fun buildBookShelfShortCutInfo(context: Context): ShortcutInfoCompat {
|
||||||
val bookShelfIntent = buildIntent<MainActivity>(context)
|
val bookShelfIntent = MainActivity.createHomeIntent(context).apply {
|
||||||
|
action = Intent.ACTION_VIEW
|
||||||
|
}
|
||||||
return ShortcutInfoCompat.Builder(context, "bookshelf")
|
return ShortcutInfoCompat.Builder(context, "bookshelf")
|
||||||
.setShortLabel(context.getString(R.string.bookshelf))
|
.setShortLabel(context.getString(R.string.bookshelf))
|
||||||
.setLongLabel(context.getString(R.string.bookshelf))
|
.setLongLabel(context.getString(R.string.bookshelf))
|
||||||
@@ -29,7 +31,9 @@ object ShortCuts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun buildReadBookShortCutInfo(context: Context): ShortcutInfoCompat {
|
private fun buildReadBookShortCutInfo(context: Context): ShortcutInfoCompat {
|
||||||
val bookShelfIntent = buildIntent<MainActivity>(context)
|
val bookShelfIntent = MainActivity.createHomeIntent(context).apply {
|
||||||
|
action = Intent.ACTION_VIEW
|
||||||
|
}
|
||||||
val readBookIntent = buildIntent<ReadBookActivity>(context)
|
val readBookIntent = buildIntent<ReadBookActivity>(context)
|
||||||
return ShortcutInfoCompat.Builder(context, "lastRead")
|
return ShortcutInfoCompat.Builder(context, "lastRead")
|
||||||
.setShortLabel(context.getString(R.string.last_read))
|
.setShortLabel(context.getString(R.string.last_read))
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import android.os.Bundle
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import io.legado.app.ui.book.search.SearchActivity
|
import io.legado.app.ui.book.search.SearchActivity
|
||||||
import io.legado.app.ui.main.MainActivity
|
import io.legado.app.ui.main.MainActivity
|
||||||
import io.legado.app.utils.startActivity
|
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
|
|
||||||
class SharedReceiverActivity : AppCompatActivity() {
|
class SharedReceiverActivity : AppCompatActivity() {
|
||||||
@@ -52,7 +51,7 @@ class SharedReceiverActivity : AppCompatActivity() {
|
|||||||
result.append("\n").append(url.trim { it <= ' ' })
|
result.append("\n").append(url.trim { it <= ' ' })
|
||||||
}
|
}
|
||||||
if (result.length > 1) {
|
if (result.length > 1) {
|
||||||
startActivity<MainActivity>()
|
startActivity(MainActivity.createHomeIntent(this))
|
||||||
} else {
|
} else {
|
||||||
SearchActivity.start(this, text)
|
SearchActivity.start(this, text)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ import io.legado.app.ui.config.otherConfig.OtherConfigScreen
|
|||||||
import io.legado.app.ui.config.readConfig.ReadConfigScreen
|
import io.legado.app.ui.config.readConfig.ReadConfigScreen
|
||||||
import io.legado.app.ui.config.themeConfig.ThemeConfigScreen
|
import io.legado.app.ui.config.themeConfig.ThemeConfigScreen
|
||||||
import io.legado.app.ui.rss.article.MainRouteRssSort
|
import io.legado.app.ui.rss.article.MainRouteRssSort
|
||||||
import io.legado.app.ui.rss.navigation.RssMainNavContract
|
|
||||||
import io.legado.app.ui.rss.article.RssSortRouteScreen
|
import io.legado.app.ui.rss.article.RssSortRouteScreen
|
||||||
import io.legado.app.ui.rss.read.MainRouteRssRead
|
import io.legado.app.ui.rss.read.MainRouteRssRead
|
||||||
import io.legado.app.ui.rss.read.RssReadRouteScreen
|
import io.legado.app.ui.rss.read.RssReadRouteScreen
|
||||||
@@ -83,13 +82,70 @@ open class MainActivity : BaseComposeActivity() {
|
|||||||
private const val ROUTE_SETTINGS_BACKUP = "settings/backup"
|
private const val ROUTE_SETTINGS_BACKUP = "settings/backup"
|
||||||
private const val ROUTE_IMPORT_LOCAL = "import/local"
|
private const val ROUTE_IMPORT_LOCAL = "import/local"
|
||||||
private const val ROUTE_IMPORT_REMOTE = "import/remote"
|
private const val ROUTE_IMPORT_REMOTE = "import/remote"
|
||||||
|
private const val ROUTE_RSS_SORT = "rss/sort"
|
||||||
|
private const val ROUTE_RSS_READ = "rss/read"
|
||||||
|
|
||||||
|
private const val EXTRA_RSS_SOURCE_URL = "extra_rss_source_url"
|
||||||
|
private const val EXTRA_RSS_SORT_URL = "extra_rss_sort_url"
|
||||||
|
private const val EXTRA_RSS_KEY = "extra_rss_key"
|
||||||
|
|
||||||
|
private const val EXTRA_RSS_READ_TITLE = "extra_rss_read_title"
|
||||||
|
private const val EXTRA_RSS_READ_ORIGIN = "extra_rss_read_origin"
|
||||||
|
private const val EXTRA_RSS_READ_LINK = "extra_rss_read_link"
|
||||||
|
private const val EXTRA_RSS_READ_OPEN_URL = "extra_rss_read_open_url"
|
||||||
|
|
||||||
|
fun createLauncherIntent(context: Context): Intent {
|
||||||
|
val launcherComponent =
|
||||||
|
context.packageManager.getLaunchIntentForPackage(context.packageName)?.component
|
||||||
|
return if (launcherComponent != null) {
|
||||||
|
Intent().setComponent(launcherComponent)
|
||||||
|
} else {
|
||||||
|
Intent(context, MainActivity::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createHomeIntent(context: Context): Intent {
|
||||||
|
return createLauncherIntent(context).apply {
|
||||||
|
putExtra(EXTRA_START_ROUTE, ROUTE_MAIN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun createIntent(context: Context, configTag: String? = null): Intent {
|
fun createIntent(context: Context, configTag: String? = null): Intent {
|
||||||
return Intent(context, MainActivity::class.java).apply {
|
return createLauncherIntent(context).apply {
|
||||||
putExtra(EXTRA_START_ROUTE, routeForConfigTag(configTag))
|
putExtra(EXTRA_START_ROUTE, routeForConfigTag(configTag))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createRssSortIntent(
|
||||||
|
context: Context,
|
||||||
|
sourceUrl: String,
|
||||||
|
sortUrl: String? = null,
|
||||||
|
key: String? = null
|
||||||
|
): Intent {
|
||||||
|
return createLauncherIntent(context).apply {
|
||||||
|
putExtra(EXTRA_START_ROUTE, ROUTE_RSS_SORT)
|
||||||
|
putExtra(EXTRA_RSS_SOURCE_URL, sourceUrl)
|
||||||
|
putExtra(EXTRA_RSS_SORT_URL, sortUrl)
|
||||||
|
putExtra(EXTRA_RSS_KEY, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createRssReadIntent(
|
||||||
|
context: Context,
|
||||||
|
title: String? = null,
|
||||||
|
origin: String,
|
||||||
|
link: String? = null,
|
||||||
|
openUrl: String? = null
|
||||||
|
): Intent {
|
||||||
|
return createLauncherIntent(context).apply {
|
||||||
|
putExtra(EXTRA_START_ROUTE, ROUTE_RSS_READ)
|
||||||
|
putExtra(EXTRA_RSS_READ_TITLE, title)
|
||||||
|
putExtra(EXTRA_RSS_READ_ORIGIN, origin)
|
||||||
|
putExtra(EXTRA_RSS_READ_LINK, link)
|
||||||
|
putExtra(EXTRA_RSS_READ_OPEN_URL, openUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun routeForConfigTag(configTag: String?): String {
|
private fun routeForConfigTag(configTag: String?): String {
|
||||||
return when (configTag) {
|
return when (configTag) {
|
||||||
ConfigTag.OTHER_CONFIG -> ROUTE_SETTINGS_OTHER
|
ConfigTag.OTHER_CONFIG -> ROUTE_SETTINGS_OTHER
|
||||||
@@ -291,6 +347,17 @@ open class MainActivity : BaseComposeActivity() {
|
|||||||
key = key
|
key = key
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
onNavigateToRssRead = { title, origin, link, openUrl ->
|
||||||
|
navigateToRoute(
|
||||||
|
backStack,
|
||||||
|
MainRouteRssRead(
|
||||||
|
title = title,
|
||||||
|
origin = origin,
|
||||||
|
link = link,
|
||||||
|
openUrl = openUrl
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -342,7 +409,18 @@ open class MainActivity : BaseComposeActivity() {
|
|||||||
RssSortRouteScreen(
|
RssSortRouteScreen(
|
||||||
sourceUrl = route.sourceUrl,
|
sourceUrl = route.sourceUrl,
|
||||||
initialSortUrl = route.sortUrl,
|
initialSortUrl = route.sortUrl,
|
||||||
onBackClick = { navigateBack(backStack) }
|
onBackClick = { navigateBack(backStack) },
|
||||||
|
onOpenRead = { title, origin, link, openUrl ->
|
||||||
|
navigateToRoute(
|
||||||
|
backStack,
|
||||||
|
MainRouteRssRead(
|
||||||
|
title = title,
|
||||||
|
origin = origin,
|
||||||
|
link = link,
|
||||||
|
openUrl = openUrl
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +490,7 @@ open class MainActivity : BaseComposeActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
is MainRouteRssRead -> {
|
is MainRouteRssRead -> {
|
||||||
if (currentRoute == MainRouteHome) {
|
if (currentRoute == MainRouteHome || currentRoute is MainRouteRssSort) {
|
||||||
backStack.add(route)
|
backStack.add(route)
|
||||||
} else {
|
} else {
|
||||||
backStack.clear()
|
backStack.clear()
|
||||||
@@ -543,10 +621,43 @@ open class MainActivity : BaseComposeActivity() {
|
|||||||
|
|
||||||
private fun resolveStartRoute(intent: Intent?): NavKey {
|
private fun resolveStartRoute(intent: Intent?): NavKey {
|
||||||
val route = intent?.getStringExtra(EXTRA_START_ROUTE)
|
val route = intent?.getStringExtra(EXTRA_START_ROUTE)
|
||||||
RssMainNavContract.resolveStartRoute(route, intent)?.let { return it }
|
resolveRssStartRoute(route, intent)?.let { return it }
|
||||||
return resolveStartRoute(route)
|
return resolveStartRoute(route)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun resolveRssStartRoute(route: String?, intent: Intent?): NavKey? {
|
||||||
|
return when (route) {
|
||||||
|
ROUTE_RSS_SORT -> {
|
||||||
|
val sourceUrl = intent?.getStringExtra(EXTRA_RSS_SOURCE_URL)
|
||||||
|
if (sourceUrl.isNullOrBlank()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
MainRouteRssSort(
|
||||||
|
sourceUrl = sourceUrl,
|
||||||
|
sortUrl = intent.getStringExtra(EXTRA_RSS_SORT_URL),
|
||||||
|
key = intent.getStringExtra(EXTRA_RSS_KEY)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ROUTE_RSS_READ -> {
|
||||||
|
val origin = intent?.getStringExtra(EXTRA_RSS_READ_ORIGIN)
|
||||||
|
if (origin.isNullOrBlank()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
MainRouteRssRead(
|
||||||
|
title = intent.getStringExtra(EXTRA_RSS_READ_TITLE),
|
||||||
|
origin = origin,
|
||||||
|
link = intent.getStringExtra(EXTRA_RSS_READ_LINK),
|
||||||
|
openUrl = intent.getStringExtra(EXTRA_RSS_READ_OPEN_URL)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun resolveStartRoute(route: String?): MainRoute {
|
private fun resolveStartRoute(route: String?): MainRoute {
|
||||||
return when (route) {
|
return when (route) {
|
||||||
"main" -> MainRouteHome
|
"main" -> MainRouteHome
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ fun MainScreen(
|
|||||||
onOpenSettings: () -> Unit,
|
onOpenSettings: () -> Unit,
|
||||||
onNavigateToRemoteImport: () -> Unit,
|
onNavigateToRemoteImport: () -> Unit,
|
||||||
onNavigateToLocalImport: () -> Unit,
|
onNavigateToLocalImport: () -> Unit,
|
||||||
onNavigateToRssSort: (sourceUrl: String, sortUrl: String?, key: String?) -> Unit
|
onNavigateToRssSort: (sourceUrl: String, sortUrl: String?, key: String?) -> Unit,
|
||||||
|
onNavigateToRssRead: (title: String?, origin: String, link: String?, openUrl: String?) -> Unit
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
@@ -384,6 +385,9 @@ fun MainScreen(
|
|||||||
MainDestination.Rss -> RssScreen(
|
MainDestination.Rss -> RssScreen(
|
||||||
onOpenSort = { sourceUrl, sortUrl, key ->
|
onOpenSort = { sourceUrl, sortUrl, key ->
|
||||||
onNavigateToRssSort(sourceUrl, sortUrl, key)
|
onNavigateToRssSort(sourceUrl, sortUrl, key)
|
||||||
|
},
|
||||||
|
onOpenRead = { title, origin, link, openUrl ->
|
||||||
|
onNavigateToRssRead(title, origin, link, openUrl)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
MainDestination.My -> MyScreen(
|
MainDestination.My -> MyScreen(
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ import androidx.compose.ui.unit.dp
|
|||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.data.entities.RssSource
|
import io.legado.app.data.entities.RssSource
|
||||||
import io.legado.app.ui.login.SourceLoginActivity
|
import io.legado.app.ui.login.SourceLoginActivity
|
||||||
import io.legado.app.ui.rss.navigation.RssMainNavContract
|
|
||||||
import io.legado.app.ui.rss.favorites.RssFavoritesActivity
|
import io.legado.app.ui.rss.favorites.RssFavoritesActivity
|
||||||
import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
|
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
|
||||||
@@ -73,7 +72,8 @@ import org.koin.androidx.compose.koinViewModel
|
|||||||
@Composable
|
@Composable
|
||||||
fun RssScreen(
|
fun RssScreen(
|
||||||
viewModel: RssViewModel = koinViewModel(),
|
viewModel: RssViewModel = koinViewModel(),
|
||||||
onOpenSort: (sourceUrl: String, sortUrl: String?, key: String?) -> Unit
|
onOpenSort: (sourceUrl: String, sortUrl: String?, key: String?) -> Unit,
|
||||||
|
onOpenRead: (title: String?, origin: String, link: String?, openUrl: String?) -> Unit
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val uiState by viewModel.uiState.collectAsState()
|
val uiState by viewModel.uiState.collectAsState()
|
||||||
@@ -83,12 +83,11 @@ fun RssScreen(
|
|||||||
if (rssSource.singleUrl) {
|
if (rssSource.singleUrl) {
|
||||||
viewModel.getSingleUrl(rssSource) { url ->
|
viewModel.getSingleUrl(rssSource) { url ->
|
||||||
if (url.startsWith("http", true)) {
|
if (url.startsWith("http", true)) {
|
||||||
context.startActivity(
|
onOpenRead(
|
||||||
RssMainNavContract.createRssReadIntent(
|
rssSource.sourceName,
|
||||||
context = context,
|
url,
|
||||||
title = rssSource.sourceName,
|
null,
|
||||||
origin = url
|
null
|
||||||
)
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
context.openUrl(url)
|
context.openUrl(url)
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
package io.legado.app.ui.rss.article
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.platform.ComposeView
|
|
||||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import io.legado.app.data.entities.RssArticle
|
|
||||||
import io.legado.app.ui.rss.navigation.RssMainNavContract
|
|
||||||
import io.legado.app.ui.theme.AppTheme
|
|
||||||
import io.legado.app.utils.startActivity
|
|
||||||
import org.koin.androidx.viewmodel.ext.android.activityViewModel
|
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
|
||||||
|
|
||||||
class RssArticlesFragment() : Fragment() {
|
|
||||||
|
|
||||||
constructor(sortName: String, sortUrl: String) : this() {
|
|
||||||
arguments = Bundle().apply {
|
|
||||||
putString("sortName", sortName)
|
|
||||||
putString("sortUrl", sortUrl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val activityViewModel: RssSortViewModel by activityViewModel()
|
|
||||||
private val viewModel: RssArticlesViewModel by viewModel()
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
return ComposeView(requireContext()).apply {
|
|
||||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
|
||||||
setContent {
|
|
||||||
AppTheme {
|
|
||||||
Content()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Content() {
|
|
||||||
val sortName = arguments?.getString("sortName").orEmpty()
|
|
||||||
val sortUrl = arguments?.getString("sortUrl").orEmpty()
|
|
||||||
|
|
||||||
RssArticlesPage(
|
|
||||||
sortName = sortName,
|
|
||||||
sortUrl = sortUrl,
|
|
||||||
articleStyle = activityViewModel.currentArticleStyle(),
|
|
||||||
rssUrl = activityViewModel.url,
|
|
||||||
rssSource = activityViewModel.rssSource,
|
|
||||||
viewModel = viewModel,
|
|
||||||
onRead = ::readRss
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun readRss(rssArticle: RssArticle) {
|
|
||||||
activityViewModel.read(rssArticle)
|
|
||||||
requireContext().startActivity(
|
|
||||||
RssMainNavContract.createRssReadIntent(
|
|
||||||
context = requireContext(),
|
|
||||||
title = rssArticle.title,
|
|
||||||
origin = rssArticle.origin,
|
|
||||||
link = rssArticle.link
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,7 +17,6 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.data.entities.RssReadRecord
|
import io.legado.app.data.entities.RssReadRecord
|
||||||
import io.legado.app.ui.login.SourceLoginActivity
|
import io.legado.app.ui.login.SourceLoginActivity
|
||||||
import io.legado.app.ui.rss.navigation.RssMainNavContract
|
|
||||||
import io.legado.app.ui.rss.read.RedirectPolicy
|
import io.legado.app.ui.rss.read.RedirectPolicy
|
||||||
import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
|
import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
|
||||||
import io.legado.app.ui.widget.dialog.VariableDialog
|
import io.legado.app.ui.widget.dialog.VariableDialog
|
||||||
@@ -36,6 +35,7 @@ fun RssSortRouteScreen(
|
|||||||
sourceUrl: String?,
|
sourceUrl: String?,
|
||||||
initialSortUrl: String?,
|
initialSortUrl: String?,
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
|
onOpenRead: (title: String?, origin: String, link: String?, openUrl: String?) -> Unit,
|
||||||
viewModel: RssSortViewModel = koinViewModel()
|
viewModel: RssSortViewModel = koinViewModel()
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
@@ -143,14 +143,7 @@ fun RssSortRouteScreen(
|
|||||||
if (openOrigin.isBlank()) {
|
if (openOrigin.isBlank()) {
|
||||||
context.toastOnUi(context.getString(R.string.error))
|
context.toastOnUi(context.getString(R.string.error))
|
||||||
} else {
|
} else {
|
||||||
context.startActivity(
|
onOpenRead(record.title, openOrigin, null, record.record)
|
||||||
RssMainNavContract.createRssReadIntent(
|
|
||||||
context = context,
|
|
||||||
title = record.title,
|
|
||||||
origin = openOrigin,
|
|
||||||
openUrl = record.record
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onClearArticles = { viewModel.clearArticles() },
|
onClearArticles = { viewModel.clearArticles() },
|
||||||
@@ -174,14 +167,7 @@ fun RssSortRouteScreen(
|
|||||||
viewModel = pageViewModel,
|
viewModel = pageViewModel,
|
||||||
onRead = { article ->
|
onRead = { article ->
|
||||||
viewModel.read(article)
|
viewModel.read(article)
|
||||||
context.startActivity(
|
onOpenRead(article.title, article.origin, article.link, null)
|
||||||
RssMainNavContract.createRssReadIntent(
|
|
||||||
context = context,
|
|
||||||
title = article.title,
|
|
||||||
origin = article.origin,
|
|
||||||
link = article.link
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,12 @@ package io.legado.app.ui.rss.favorites
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import io.legado.app.base.BaseComposeActivity
|
import io.legado.app.base.BaseComposeActivity
|
||||||
|
import io.legado.app.ui.rss.read.RssReadRouteScreen
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 收藏夹
|
* 收藏夹
|
||||||
@@ -15,8 +20,33 @@ class RssFavoritesActivity : BaseComposeActivity() {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
var readArgs by remember {
|
||||||
|
mutableStateOf<ReadArgs?>(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
val currentReadArgs = readArgs
|
||||||
|
if (currentReadArgs == null) {
|
||||||
RssFavoritesScreen(
|
RssFavoritesScreen(
|
||||||
onBackClick = { finish() }
|
onBackClick = { finish() },
|
||||||
|
onOpenRead = { title, origin, link, openUrl ->
|
||||||
|
readArgs = ReadArgs(title, origin, link, openUrl)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
RssReadRouteScreen(
|
||||||
|
title = currentReadArgs.title,
|
||||||
|
origin = currentReadArgs.origin,
|
||||||
|
link = currentReadArgs.link,
|
||||||
|
openUrl = currentReadArgs.openUrl,
|
||||||
|
onBackClick = { readArgs = null }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private data class ReadArgs(
|
||||||
|
val title: String?,
|
||||||
|
val origin: String,
|
||||||
|
val link: String?,
|
||||||
|
val openUrl: String?
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,13 +26,11 @@ 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.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
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 androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.data.entities.RssStar
|
import io.legado.app.data.entities.RssStar
|
||||||
import io.legado.app.ui.rss.navigation.RssMainNavContract
|
|
||||||
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.SourceIcon
|
||||||
@@ -42,15 +40,14 @@ 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.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 io.legado.app.utils.startActivity
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun RssFavoritesScreen(
|
fun RssFavoritesScreen(
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
|
onOpenRead: (title: String?, origin: String, link: String?, openUrl: String?) -> Unit,
|
||||||
viewModel: RssFavoritesViewModel = viewModel()
|
viewModel: RssFavoritesViewModel = viewModel()
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
|
||||||
val state by viewModel.state.collectAsState()
|
val state by viewModel.state.collectAsState()
|
||||||
val groups by viewModel.groups.collectAsState()
|
val groups by viewModel.groups.collectAsState()
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
@@ -224,14 +221,7 @@ fun RssFavoritesScreen(
|
|||||||
} else null,
|
} else null,
|
||||||
trailingAction = {
|
trailingAction = {
|
||||||
val openAction = {
|
val openAction = {
|
||||||
context.startActivity(
|
onOpenRead(rssStar.title, rssStar.origin, rssStar.link, null)
|
||||||
RssMainNavContract.createRssReadIntent(
|
|
||||||
context = context,
|
|
||||||
title = rssStar.title,
|
|
||||||
origin = rssStar.origin,
|
|
||||||
link = rssStar.link
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
SmallIconButton(
|
SmallIconButton(
|
||||||
onClick = openAction,
|
onClick = openAction,
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
package io.legado.app.ui.rss.navigation
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import androidx.navigation3.runtime.NavKey
|
|
||||||
import io.legado.app.ui.main.MainActivity
|
|
||||||
import io.legado.app.ui.rss.article.MainRouteRssSort
|
|
||||||
import io.legado.app.ui.rss.read.MainRouteRssRead
|
|
||||||
|
|
||||||
object RssMainNavContract {
|
|
||||||
|
|
||||||
private const val ROUTE_RSS_SORT = "rss/sort"
|
|
||||||
private const val ROUTE_RSS_READ = "rss/read"
|
|
||||||
|
|
||||||
private const val EXTRA_RSS_SOURCE_URL = "extra_rss_source_url"
|
|
||||||
private const val EXTRA_RSS_SORT_URL = "extra_rss_sort_url"
|
|
||||||
private const val EXTRA_RSS_KEY = "extra_rss_key"
|
|
||||||
|
|
||||||
private const val EXTRA_RSS_READ_TITLE = "extra_rss_read_title"
|
|
||||||
private const val EXTRA_RSS_READ_ORIGIN = "extra_rss_read_origin"
|
|
||||||
private const val EXTRA_RSS_READ_LINK = "extra_rss_read_link"
|
|
||||||
private const val EXTRA_RSS_READ_OPEN_URL = "extra_rss_read_open_url"
|
|
||||||
|
|
||||||
fun createRssSortIntent(
|
|
||||||
context: Context,
|
|
||||||
sourceUrl: String,
|
|
||||||
sortUrl: String? = null,
|
|
||||||
key: String? = null
|
|
||||||
): Intent {
|
|
||||||
return Intent(context, MainActivity::class.java).apply {
|
|
||||||
putExtra(MainActivity.EXTRA_START_ROUTE, ROUTE_RSS_SORT)
|
|
||||||
putExtra(EXTRA_RSS_SOURCE_URL, sourceUrl)
|
|
||||||
putExtra(EXTRA_RSS_SORT_URL, sortUrl)
|
|
||||||
putExtra(EXTRA_RSS_KEY, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createRssReadIntent(
|
|
||||||
context: Context,
|
|
||||||
title: String? = null,
|
|
||||||
origin: String,
|
|
||||||
link: String? = null,
|
|
||||||
openUrl: String? = null
|
|
||||||
): Intent {
|
|
||||||
return Intent(context, MainActivity::class.java).apply {
|
|
||||||
putExtra(MainActivity.EXTRA_START_ROUTE, ROUTE_RSS_READ)
|
|
||||||
putExtra(EXTRA_RSS_READ_TITLE, title)
|
|
||||||
putExtra(EXTRA_RSS_READ_ORIGIN, origin)
|
|
||||||
putExtra(EXTRA_RSS_READ_LINK, link)
|
|
||||||
putExtra(EXTRA_RSS_READ_OPEN_URL, openUrl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun resolveStartRoute(route: String?, intent: Intent?): NavKey? {
|
|
||||||
return when (route) {
|
|
||||||
ROUTE_RSS_SORT -> {
|
|
||||||
val sourceUrl = intent?.getStringExtra(EXTRA_RSS_SOURCE_URL)
|
|
||||||
if (sourceUrl.isNullOrBlank()) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
MainRouteRssSort(
|
|
||||||
sourceUrl = sourceUrl,
|
|
||||||
sortUrl = intent.getStringExtra(EXTRA_RSS_SORT_URL),
|
|
||||||
key = intent.getStringExtra(EXTRA_RSS_KEY)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ROUTE_RSS_READ -> {
|
|
||||||
val origin = intent?.getStringExtra(EXTRA_RSS_READ_ORIGIN)
|
|
||||||
if (origin.isNullOrBlank()) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
MainRouteRssRead(
|
|
||||||
title = intent.getStringExtra(EXTRA_RSS_READ_TITLE),
|
|
||||||
origin = origin,
|
|
||||||
link = intent.getStringExtra(EXTRA_RSS_READ_LINK),
|
|
||||||
openUrl = intent.getStringExtra(EXTRA_RSS_READ_OPEN_URL)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,7 +13,7 @@ import io.legado.app.ui.association.AddToBookshelfDialog
|
|||||||
import io.legado.app.ui.book.explore.ExploreShowActivity
|
import io.legado.app.ui.book.explore.ExploreShowActivity
|
||||||
import io.legado.app.ui.book.search.SearchActivity
|
import io.legado.app.ui.book.search.SearchActivity
|
||||||
import io.legado.app.ui.login.SourceLoginActivity
|
import io.legado.app.ui.login.SourceLoginActivity
|
||||||
import io.legado.app.ui.rss.navigation.RssMainNavContract
|
import io.legado.app.ui.main.MainActivity
|
||||||
import io.legado.app.ui.widget.dialog.PhotoDialog
|
import io.legado.app.ui.widget.dialog.PhotoDialog
|
||||||
import io.legado.app.utils.isJsonObject
|
import io.legado.app.utils.isJsonObject
|
||||||
import io.legado.app.utils.showDialogFragment
|
import io.legado.app.utils.showDialogFragment
|
||||||
@@ -128,7 +128,7 @@ open class RssJsExtensions(activity: AppCompatActivity?, source: BaseSource?) :
|
|||||||
val sourceUrl = toSource.sourceUrl
|
val sourceUrl = toSource.sourceUrl
|
||||||
withContext(Main) {
|
withContext(Main) {
|
||||||
activity.startActivity(
|
activity.startActivity(
|
||||||
RssMainNavContract.createRssSortIntent(
|
MainActivity.createRssSortIntent(
|
||||||
context = activity,
|
context = activity,
|
||||||
sourceUrl = sourceUrl,
|
sourceUrl = sourceUrl,
|
||||||
sortUrl = sortUrl
|
sortUrl = sortUrl
|
||||||
@@ -155,7 +155,7 @@ open class RssJsExtensions(activity: AppCompatActivity?, source: BaseSource?) :
|
|||||||
appDb.rssReadRecordDao.insertRecord(rssReadRecord) //留下历史记录
|
appDb.rssReadRecordDao.insertRecord(rssReadRecord) //留下历史记录
|
||||||
withContext(Main) {
|
withContext(Main) {
|
||||||
activity.startActivity(
|
activity.startActivity(
|
||||||
RssMainNavContract.createRssReadIntent(
|
MainActivity.createRssReadIntent(
|
||||||
context = activity,
|
context = activity,
|
||||||
title = title,
|
title = title,
|
||||||
origin = sourceUrl,
|
origin = sourceUrl,
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import io.legado.app.base.BaseActivity
|
|||||||
import io.legado.app.databinding.ActivityWelcomeBinding
|
import io.legado.app.databinding.ActivityWelcomeBinding
|
||||||
import io.legado.app.help.config.LocalConfig
|
import io.legado.app.help.config.LocalConfig
|
||||||
import io.legado.app.ui.main.MainActivity
|
import io.legado.app.ui.main.MainActivity
|
||||||
import io.legado.app.utils.startActivity
|
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||||
|
|
||||||
class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
|
class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
|
||||||
@@ -98,7 +97,7 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun finishSetup() {
|
private fun finishSetup() {
|
||||||
startActivity<MainActivity>()
|
startActivity(MainActivity.createHomeIntent(this))
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.zIndex
|
import androidx.compose.ui.zIndex
|
||||||
@@ -31,6 +32,7 @@ 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.SelectionActions
|
import io.legado.app.ui.widget.components.SelectionActions
|
||||||
import io.legado.app.ui.widget.components.SelectionBottomBar
|
import io.legado.app.ui.widget.components.SelectionBottomBar
|
||||||
|
import io.legado.app.ui.widget.components.icon.AppIcons
|
||||||
import io.legado.app.ui.widget.components.topbar.DynamicTopAppBar
|
import io.legado.app.ui.widget.components.topbar.DynamicTopAppBar
|
||||||
import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults
|
import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults
|
||||||
import io.legado.app.ui.widget.components.topbar.GlassTopAppBarScrollBehavior
|
import io.legado.app.ui.widget.components.topbar.GlassTopAppBarScrollBehavior
|
||||||
@@ -42,6 +44,8 @@ fun <T> ListScaffold(
|
|||||||
state: ListUiState<T>,
|
state: ListUiState<T>,
|
||||||
subtitle: String? = null,
|
subtitle: String? = null,
|
||||||
onBackClick: (() -> Unit)? = null,
|
onBackClick: (() -> Unit)? = null,
|
||||||
|
backNavigationIcon: ImageVector = AppIcons.Back,
|
||||||
|
showSearchAction: Boolean = true,
|
||||||
onSearchToggle: (Boolean) -> Unit,
|
onSearchToggle: (Boolean) -> Unit,
|
||||||
onSearchQueryChange: (String) -> Unit,
|
onSearchQueryChange: (String) -> Unit,
|
||||||
searchPlaceholder: String = "搜索...",
|
searchPlaceholder: String = "搜索...",
|
||||||
@@ -85,6 +89,8 @@ fun <T> ListScaffold(
|
|||||||
state = state,
|
state = state,
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
onBackClick = onBackClick,
|
onBackClick = onBackClick,
|
||||||
|
backNavigationIcon = backNavigationIcon,
|
||||||
|
showSearchAction = showSearchAction,
|
||||||
onSearchToggle = onSearchToggle,
|
onSearchToggle = onSearchToggle,
|
||||||
onSearchQueryChange = onSearchQueryChange,
|
onSearchQueryChange = onSearchQueryChange,
|
||||||
searchPlaceholder = searchPlaceholder,
|
searchPlaceholder = searchPlaceholder,
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ fun <T> DynamicTopAppBar(
|
|||||||
state: ListUiState<T>,
|
state: ListUiState<T>,
|
||||||
scrollBehavior: GlassTopAppBarScrollBehavior,
|
scrollBehavior: GlassTopAppBarScrollBehavior,
|
||||||
onBackClick: (() -> Unit)? = null,
|
onBackClick: (() -> Unit)? = null,
|
||||||
|
backNavigationIcon: ImageVector = AppIcons.Back,
|
||||||
|
showSearchAction: Boolean = true,
|
||||||
onSearchToggle: (Boolean) -> Unit,
|
onSearchToggle: (Boolean) -> Unit,
|
||||||
onSearchQueryChange: (String) -> Unit,
|
onSearchQueryChange: (String) -> Unit,
|
||||||
searchPlaceholder: String,
|
searchPlaceholder: String,
|
||||||
@@ -66,18 +68,20 @@ fun <T> DynamicTopAppBar(
|
|||||||
if (isSelecting || onBackClick != null) {
|
if (isSelecting || onBackClick != null) {
|
||||||
TopBarNavigationButton(
|
TopBarNavigationButton(
|
||||||
onClick = { if (isSelecting) onClearSelection() else onBackClick?.invoke() },
|
onClick = { if (isSelecting) onClearSelection() else onBackClick?.invoke() },
|
||||||
imageVector = if (isSelecting) AppIcons.Close else AppIcons.Back,
|
imageVector = if (isSelecting) AppIcons.Close else backNavigationIcon,
|
||||||
contentDescription = if (isSelecting) "取消选择" else "返回"
|
contentDescription = if (isSelecting) "取消选择" else "返回"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
if (!isSelecting) {
|
if (!isSelecting) {
|
||||||
|
if (showSearchAction) {
|
||||||
TopBarActionButton(
|
TopBarActionButton(
|
||||||
onClick = { onSearchToggle(!state.isSearch) },
|
onClick = { onSearchToggle(!state.isSearch) },
|
||||||
imageVector = AppIcons.Search,
|
imageVector = AppIcons.Search,
|
||||||
contentDescription = "搜索"
|
contentDescription = "搜索"
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
topBarActions()
|
topBarActions()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user