代码优化
This commit is contained in:
8 files changed
+97
-91
No files matched your search
@@ -81,7 +81,8 @@
|
|||||||
"Bash(dir /s /b \"D:\\\\AndroidPrj\\\\legado-with-MD3\")",
|
"Bash(dir /s /b \"D:\\\\AndroidPrj\\\\legado-with-MD3\")",
|
||||||
"Bash(findstr /i \"miuix.*\\\\.kt\")",
|
"Bash(findstr /i \"miuix.*\\\\.kt\")",
|
||||||
"Bash(findstr /v \"\\\\\\\\build\\\\\\\\\")",
|
"Bash(findstr /v \"\\\\\\\\build\\\\\\\\\")",
|
||||||
"Bash(dir /s /b \"D:\\\\AndroidPrj\\\\legado-with-MD3\\\\.gradle\\\\*miuix*\")"
|
"Bash(dir /s /b \"D:\\\\AndroidPrj\\\\legado-with-MD3\\\\.gradle\\\\*miuix*\")",
|
||||||
|
"Skill(legado-compose-review)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package io.legado.app.ui.main
|
|||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
|
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
||||||
sealed class MainDestination(
|
sealed class MainDestination(
|
||||||
@@ -32,3 +33,11 @@ sealed class MainDestination(
|
|||||||
val mainDestinations = persistentListOf<MainDestination>(Bookshelf, Explore, Rss, My)
|
val mainDestinations = persistentListOf<MainDestination>(Bookshelf, Explore, Rss, My)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val MainDestination.customIconPath: String
|
||||||
|
get() = when (this) {
|
||||||
|
MainDestination.Bookshelf -> ThemeConfig.navIconBookshelf
|
||||||
|
MainDestination.Explore -> ThemeConfig.navIconExplore
|
||||||
|
MainDestination.Rss -> ThemeConfig.navIconRss
|
||||||
|
MainDestination.My -> ThemeConfig.navIconMy
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package io.legado.app.ui.main
|
package io.legado.app.ui.main
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
@@ -24,7 +23,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.navigationBars
|
import androidx.compose.foundation.layout.navigationBars
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.pager.HorizontalPager
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
@@ -52,24 +50,22 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.runtime.setValue
|
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.graphics.Color
|
||||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.semantics.testTagsAsResourceId
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.core.net.toUri
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import coil.compose.AsyncImage
|
||||||
import com.kyant.backdrop.backdrops.layerBackdrop
|
import com.kyant.backdrop.backdrops.layerBackdrop
|
||||||
import com.kyant.backdrop.backdrops.rememberLayerBackdrop
|
import com.kyant.backdrop.backdrops.rememberLayerBackdrop
|
||||||
import dev.chrisbanes.haze.HazeState
|
import dev.chrisbanes.haze.HazeState
|
||||||
import dev.chrisbanes.haze.hazeSource
|
import dev.chrisbanes.haze.hazeSource
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
|
||||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
||||||
import io.legado.app.ui.main.bookshelf.BookshelfScreen
|
import io.legado.app.ui.main.bookshelf.BookshelfScreen
|
||||||
@@ -78,7 +74,6 @@ import io.legado.app.ui.main.explore.ExploreScreen
|
|||||||
import io.legado.app.ui.main.my.MyScreen
|
import io.legado.app.ui.main.my.MyScreen
|
||||||
import io.legado.app.ui.main.my.PrefClickEvent
|
import io.legado.app.ui.main.my.PrefClickEvent
|
||||||
import io.legado.app.ui.main.rss.RssScreen
|
import io.legado.app.ui.main.rss.RssScreen
|
||||||
import io.legado.app.ui.theme.regularHazeEffect
|
|
||||||
import io.legado.app.ui.widget.components.AppNavigationBar
|
import io.legado.app.ui.widget.components.AppNavigationBar
|
||||||
import io.legado.app.ui.widget.components.AppNavigationBarItem
|
import io.legado.app.ui.widget.components.AppNavigationBarItem
|
||||||
import io.legado.app.ui.widget.components.AppScaffold
|
import io.legado.app.ui.widget.components.AppScaffold
|
||||||
@@ -95,6 +90,7 @@ import io.legado.app.utils.sendToClip
|
|||||||
import io.legado.app.utils.showDialogFragment
|
import io.legado.app.utils.showDialogFragment
|
||||||
import io.legado.app.utils.startActivityForBook
|
import io.legado.app.utils.startActivityForBook
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.koin.androidx.compose.koinViewModel
|
import org.koin.androidx.compose.koinViewModel
|
||||||
@@ -124,20 +120,21 @@ fun MainScreen(
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val mainUiState by viewModel.uiState.collectAsStateWithLifecycle()
|
val mainUiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
|
val defaultHelpTitle = stringResource(R.string.help)
|
||||||
|
|
||||||
LaunchedEffect(viewModel, context) {
|
LaunchedEffect(viewModel, context) {
|
||||||
viewModel.effects.collect { effect ->
|
viewModel.effects.collectLatest { effect ->
|
||||||
when (effect) {
|
when (effect) {
|
||||||
is MainEffect.OpenUrl -> {
|
is MainEffect.OpenUrl -> {
|
||||||
context.startActivity(
|
context.startActivity(
|
||||||
Intent(Intent.ACTION_VIEW, Uri.parse(effect.url))
|
Intent(Intent.ACTION_VIEW, effect.url.toUri())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is MainEffect.CopyUrl -> context.sendToClip(effect.url)
|
is MainEffect.CopyUrl -> context.sendToClip(effect.url)
|
||||||
is MainEffect.ShowMarkdown -> {
|
is MainEffect.ShowMarkdown -> {
|
||||||
val activity = context as? AppCompatActivity ?: return@collect
|
val activity = context as? AppCompatActivity ?: return@collectLatest
|
||||||
val title = effect.title.ifBlank { context.getString(R.string.help) }
|
val title = effect.title.ifBlank { defaultHelpTitle }
|
||||||
val mdText = withContext(Dispatchers.IO) {
|
val mdText = withContext(Dispatchers.IO) {
|
||||||
context.assets
|
context.assets
|
||||||
.open("web/help/md/${effect.path}.md")
|
.open("web/help/md/${effect.path}.md")
|
||||||
@@ -288,12 +285,7 @@ fun MainScreen(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
label = if (labelVisibilityMode != "unlabeled") {
|
label = if (labelVisibilityMode != "unlabeled") {
|
||||||
val hasCustomIcon = when (destination) {
|
val hasCustomIcon = destination.customIconPath.isNotEmpty()
|
||||||
MainDestination.Bookshelf -> ThemeConfig.navIconBookshelf.isNotEmpty()
|
|
||||||
MainDestination.Explore -> ThemeConfig.navIconExplore.isNotEmpty()
|
|
||||||
MainDestination.Rss -> ThemeConfig.navIconRss.isNotEmpty()
|
|
||||||
MainDestination.My -> ThemeConfig.navIconMy.isNotEmpty()
|
|
||||||
}
|
|
||||||
if (hasCustomIcon) null else {{ AppText(stringResource(destination.labelId)) }}
|
if (hasCustomIcon) null else {{ AppText(stringResource(destination.labelId)) }}
|
||||||
} else null
|
} else null
|
||||||
)
|
)
|
||||||
@@ -308,12 +300,7 @@ fun MainScreen(
|
|||||||
AppNavigationBar() {
|
AppNavigationBar() {
|
||||||
destinations.forEachIndexed { index, destination ->
|
destinations.forEachIndexed { index, destination ->
|
||||||
val selected = pagerState.targetPage == index
|
val selected = pagerState.targetPage == index
|
||||||
val customIconPath = when (destination) {
|
val customIconPath = destination.customIconPath
|
||||||
MainDestination.Bookshelf -> ThemeConfig.navIconBookshelf
|
|
||||||
MainDestination.Explore -> ThemeConfig.navIconExplore
|
|
||||||
MainDestination.Rss -> ThemeConfig.navIconRss
|
|
||||||
MainDestination.My -> ThemeConfig.navIconMy
|
|
||||||
}
|
|
||||||
AppNavigationBarItem(
|
AppNavigationBarItem(
|
||||||
modifier = Modifier.semantics(mergeDescendants = true) {
|
modifier = Modifier.semantics(mergeDescendants = true) {
|
||||||
contentDescription = "nav_${destination.route}"
|
contentDescription = "nav_${destination.route}"
|
||||||
@@ -442,22 +429,12 @@ fun MainScreen(
|
|||||||
tabsCount = destinations.size,
|
tabsCount = destinations.size,
|
||||||
isBlurEnabled = useLiquidGlass,
|
isBlurEnabled = useLiquidGlass,
|
||||||
hasCustomIcons = destinations.any { dest ->
|
hasCustomIcons = destinations.any { dest ->
|
||||||
when (dest) {
|
dest.customIconPath.isNotEmpty()
|
||||||
MainDestination.Bookshelf -> ThemeConfig.navIconBookshelf.isNotEmpty()
|
|
||||||
MainDestination.Explore -> ThemeConfig.navIconExplore.isNotEmpty()
|
|
||||||
MainDestination.Rss -> ThemeConfig.navIconRss.isNotEmpty()
|
|
||||||
MainDestination.My -> ThemeConfig.navIconMy.isNotEmpty()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
destinations.forEachIndexed { index, destination ->
|
destinations.forEachIndexed { index, destination ->
|
||||||
val selected = pagerState.targetPage == index
|
val selected = pagerState.targetPage == index
|
||||||
val hasCustomIcon = when (destination) {
|
val hasCustomIcon = destination.customIconPath.isNotEmpty()
|
||||||
MainDestination.Bookshelf -> ThemeConfig.navIconBookshelf.isNotEmpty()
|
|
||||||
MainDestination.Explore -> ThemeConfig.navIconExplore.isNotEmpty()
|
|
||||||
MainDestination.Rss -> ThemeConfig.navIconRss.isNotEmpty()
|
|
||||||
MainDestination.My -> ThemeConfig.navIconMy.isNotEmpty()
|
|
||||||
}
|
|
||||||
FloatingBottomBarItem(
|
FloatingBottomBarItem(
|
||||||
onClick = {
|
onClick = {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
@@ -536,31 +513,13 @@ private fun NavigationIcon(
|
|||||||
selected: Boolean,
|
selected: Boolean,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
val customIconPath = when (destination) {
|
val customIconPath = destination.customIconPath
|
||||||
MainDestination.Bookshelf -> ThemeConfig.navIconBookshelf
|
|
||||||
MainDestination.Explore -> ThemeConfig.navIconExplore
|
|
||||||
MainDestination.Rss -> ThemeConfig.navIconRss
|
|
||||||
MainDestination.My -> ThemeConfig.navIconMy
|
|
||||||
}
|
|
||||||
if (customIconPath.isNotEmpty()) {
|
if (customIconPath.isNotEmpty()) {
|
||||||
val context = LocalContext.current
|
AsyncImage(
|
||||||
val bitmap = remember(customIconPath) {
|
model = customIconPath,
|
||||||
kotlin.runCatching {
|
contentDescription = null,
|
||||||
android.graphics.BitmapFactory.decodeFile(customIconPath)
|
modifier = modifier.size(40.dp)
|
||||||
}.getOrNull()
|
)
|
||||||
}
|
|
||||||
if (bitmap != null) {
|
|
||||||
Image(
|
|
||||||
painter = remember(bitmap) {
|
|
||||||
BitmapPainter(bitmap.asImageBitmap())
|
|
||||||
},
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = modifier.size(40.dp)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val icon = AppIcons.mainDestination(destination, selected)
|
|
||||||
AppIcon(icon, contentDescription = null, modifier = modifier)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
val icon = AppIcons.mainDestination(destination, selected)
|
val icon = AppIcons.mainDestination(destination, selected)
|
||||||
AppIcon(icon, contentDescription = null, modifier = modifier)
|
AppIcon(icon, contentDescription = null, modifier = modifier)
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package io.legado.app.ui.main
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import androidx.compose.runtime.Stable
|
||||||
import io.legado.app.base.BaseViewModel
|
import io.legado.app.base.BaseViewModel
|
||||||
import io.legado.app.constant.PreferKey
|
|
||||||
import io.legado.app.constant.EventBus
|
import io.legado.app.constant.EventBus
|
||||||
|
import io.legado.app.constant.PreferKey
|
||||||
import io.legado.app.domain.usecase.AppStartupMaintenanceUseCase
|
import io.legado.app.domain.usecase.AppStartupMaintenanceUseCase
|
||||||
import io.legado.app.domain.usecase.WebDavBackupUseCase
|
import io.legado.app.domain.usecase.WebDavBackupUseCase
|
||||||
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
||||||
@@ -13,13 +14,13 @@ import io.legado.app.utils.defaultSharedPreferences
|
|||||||
import io.legado.app.utils.eventBus.FlowEventBus
|
import io.legado.app.utils.eventBus.FlowEventBus
|
||||||
import io.legado.app.utils.getPrefBoolean
|
import io.legado.app.utils.getPrefBoolean
|
||||||
import io.legado.app.utils.getPrefString
|
import io.legado.app.utils.getPrefString
|
||||||
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asSharedFlow
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
|
||||||
|
|
||||||
class MainViewModel(
|
class MainViewModel(
|
||||||
application: Application,
|
application: Application,
|
||||||
@@ -133,6 +134,7 @@ sealed interface MainEffect {
|
|||||||
data object NavigateToReadRecord : MainEffect
|
data object NavigateToReadRecord : MainEffect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Stable
|
||||||
data class MainUiState(
|
data class MainUiState(
|
||||||
val destinations: ImmutableList<MainDestination> = MainDestination.mainDestinations,
|
val destinations: ImmutableList<MainDestination> = MainDestination.mainDestinations,
|
||||||
val defaultHomePage: String = "bookshelf",
|
val defaultHomePage: String = "bookshelf",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.legado.app.ui.main.my
|
package io.legado.app.ui.main.my
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import io.legado.app.base.BaseViewModel
|
import io.legado.app.base.BaseViewModel
|
||||||
import io.legado.app.constant.EventBus
|
import io.legado.app.constant.EventBus
|
||||||
@@ -12,6 +13,7 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@Stable
|
||||||
data class MyUiState(
|
data class MyUiState(
|
||||||
val isWebServiceRun: Boolean = false,
|
val isWebServiceRun: Boolean = false,
|
||||||
val webServiceAddress: String = ""
|
val webServiceAddress: String = ""
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import androidx.compose.foundation.combinedClickable
|
|||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@@ -18,27 +17,22 @@ import androidx.compose.foundation.lazy.grid.items
|
|||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.Login
|
import androidx.compose.material.icons.automirrored.filled.Login
|
||||||
import androidx.compose.material.icons.automirrored.outlined.Label
|
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.filled.Edit
|
import androidx.compose.material.icons.filled.Edit
|
||||||
import androidx.compose.material.icons.filled.Group
|
|
||||||
import androidx.compose.material.icons.filled.Settings
|
|
||||||
import androidx.compose.material.icons.filled.Star
|
import androidx.compose.material.icons.filled.Star
|
||||||
import androidx.compose.material.icons.filled.Subscriptions
|
import androidx.compose.material.icons.filled.Subscriptions
|
||||||
import androidx.compose.material.icons.filled.VerticalAlignTop
|
import androidx.compose.material.icons.filled.VerticalAlignTop
|
||||||
import androidx.compose.material3.AlertDialog
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
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.rememberUpdatedState
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
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.clip
|
import androidx.compose.ui.draw.clip
|
||||||
@@ -59,7 +53,6 @@ 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.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.topbar.TopBarActionButton
|
|
||||||
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.list.ListScaffold
|
import io.legado.app.ui.widget.components.list.ListScaffold
|
||||||
@@ -67,6 +60,7 @@ 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
|
||||||
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.components.topbar.TopBarActionButton
|
||||||
import io.legado.app.utils.openUrl
|
import io.legado.app.utils.openUrl
|
||||||
import io.legado.app.utils.startActivity
|
import io.legado.app.utils.startActivity
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
@@ -103,23 +97,35 @@ fun RssScreen(
|
|||||||
is RssEffect.OpenExternalUrl -> {
|
is RssEffect.OpenExternalUrl -> {
|
||||||
currentContext.openUrl(effect.url)
|
currentContext.openUrl(effect.url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is RssEffect.OpenSourceEdit -> {
|
||||||
|
currentContext.startActivity<RssSourceEditActivity> {
|
||||||
|
putExtra("sourceUrl", effect.sourceUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is RssEffect.Login -> {
|
||||||
|
currentContext.startActivity<SourceLoginActivity> {
|
||||||
|
putExtra("type", "rssSource")
|
||||||
|
putExtra("key", effect.sourceUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RssEffect.OpenRuleSub -> {
|
||||||
|
currentContext.startActivity<RuleSubActivity>()
|
||||||
|
}
|
||||||
|
|
||||||
|
RssEffect.OpenFavorites -> {
|
||||||
|
currentContext.startActivity<RssFavoritesActivity>()
|
||||||
|
}
|
||||||
|
|
||||||
|
RssEffect.OpenSourceManage -> {
|
||||||
|
currentContext.startActivity<RssSourceActivity>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val edit: (RssSource) -> Unit = { rssSource ->
|
|
||||||
context.startActivity<RssSourceEditActivity> {
|
|
||||||
putExtra("sourceUrl", rssSource.sourceUrl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val login: (RssSource) -> Unit = { rssSource ->
|
|
||||||
context.startActivity<SourceLoginActivity> {
|
|
||||||
putExtra("type", "rssSource")
|
|
||||||
putExtra("key", rssSource.sourceUrl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ListScaffold(
|
ListScaffold(
|
||||||
title = stringResource(R.string.rss),
|
title = stringResource(R.string.rss),
|
||||||
state = uiState,
|
state = uiState,
|
||||||
@@ -130,12 +136,12 @@ fun RssScreen(
|
|||||||
searchPlaceholder = stringResource(R.string.search_rss_source),
|
searchPlaceholder = stringResource(R.string.search_rss_source),
|
||||||
topBarActions = {
|
topBarActions = {
|
||||||
TopBarActionButton(
|
TopBarActionButton(
|
||||||
onClick = { context.startActivity<RuleSubActivity>() },
|
onClick = { viewModel.openRuleSub() },
|
||||||
imageVector = Icons.Default.Subscriptions,
|
imageVector = Icons.Default.Subscriptions,
|
||||||
contentDescription = stringResource(R.string.rule_subscription)
|
contentDescription = stringResource(R.string.rule_subscription)
|
||||||
)
|
)
|
||||||
TopBarActionButton(
|
TopBarActionButton(
|
||||||
onClick = { context.startActivity<RssFavoritesActivity>() },
|
onClick = { viewModel.openFavorites() },
|
||||||
imageVector = Icons.Default.Star,
|
imageVector = Icons.Default.Star,
|
||||||
contentDescription = stringResource(R.string.favorite)
|
contentDescription = stringResource(R.string.favorite)
|
||||||
)
|
)
|
||||||
@@ -143,7 +149,7 @@ fun RssScreen(
|
|||||||
dropDownMenuContent = { dismiss ->
|
dropDownMenuContent = { dismiss ->
|
||||||
RoundDropdownMenuItem(
|
RoundDropdownMenuItem(
|
||||||
onClick = {
|
onClick = {
|
||||||
context.startActivity<RssSourceActivity>()
|
viewModel.openSourceManage()
|
||||||
dismiss()
|
dismiss()
|
||||||
},
|
},
|
||||||
text = stringResource(R.string.rss_feed_management),
|
text = stringResource(R.string.rss_feed_management),
|
||||||
@@ -183,10 +189,10 @@ fun RssScreen(
|
|||||||
source = source,
|
source = source,
|
||||||
onClick = { viewModel.openSource(source) },
|
onClick = { viewModel.openSource(source) },
|
||||||
onTop = { viewModel.topSource(source) },
|
onTop = { viewModel.topSource(source) },
|
||||||
onEdit = { edit(source) },
|
onEdit = { viewModel.openSourceEdit(source) },
|
||||||
onDelete = { sourceToDeleteUrl = source.sourceUrl },
|
onDelete = { sourceToDeleteUrl = source.sourceUrl },
|
||||||
onDisable = { viewModel.disable(source) },
|
onDisable = { viewModel.disable(source) },
|
||||||
onLogin = { login(source) }
|
onLogin = { viewModel.login(source) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.legado.app.ui.main.rss
|
package io.legado.app.ui.main.rss
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Stable
|
||||||
import io.legado.app.data.entities.RssSource
|
import io.legado.app.data.entities.RssSource
|
||||||
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
|
||||||
@@ -7,6 +8,7 @@ import kotlinx.collections.immutable.ImmutableSet
|
|||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.collections.immutable.persistentSetOf
|
import kotlinx.collections.immutable.persistentSetOf
|
||||||
|
|
||||||
|
@Stable
|
||||||
data class RssUiState(
|
data class RssUiState(
|
||||||
override val items: ImmutableList<RssSource> = persistentListOf(),
|
override val items: ImmutableList<RssSource> = persistentListOf(),
|
||||||
override val selectedIds: ImmutableSet<String> = persistentSetOf(),
|
override val selectedIds: ImmutableSet<String> = persistentSetOf(),
|
||||||
|
|||||||
@@ -116,6 +116,26 @@ class RssViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun openSourceEdit(rssSource: RssSource) {
|
||||||
|
_effects.tryEmit(RssEffect.OpenSourceEdit(rssSource.sourceUrl))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun login(rssSource: RssSource) {
|
||||||
|
_effects.tryEmit(RssEffect.Login(rssSource.sourceUrl))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun openRuleSub() {
|
||||||
|
_effects.tryEmit(RssEffect.OpenRuleSub)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun openFavorites() {
|
||||||
|
_effects.tryEmit(RssEffect.OpenFavorites)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun openSourceManage() {
|
||||||
|
_effects.tryEmit(RssEffect.OpenSourceManage)
|
||||||
|
}
|
||||||
|
|
||||||
fun openSource(rssSource: RssSource) {
|
fun openSource(rssSource: RssSource) {
|
||||||
if (!rssSource.singleUrl) {
|
if (!rssSource.singleUrl) {
|
||||||
_effects.tryEmit(RssEffect.OpenSort(rssSource.sourceUrl, null, null))
|
_effects.tryEmit(RssEffect.OpenSort(rssSource.sourceUrl, null, null))
|
||||||
@@ -186,4 +206,9 @@ sealed interface RssEffect {
|
|||||||
) : RssEffect
|
) : RssEffect
|
||||||
|
|
||||||
data class OpenExternalUrl(val url: String) : RssEffect
|
data class OpenExternalUrl(val url: String) : RssEffect
|
||||||
|
data class OpenSourceEdit(val sourceUrl: String) : RssEffect
|
||||||
|
data class Login(val sourceUrl: String) : RssEffect
|
||||||
|
data object OpenRuleSub : RssEffect
|
||||||
|
data object OpenFavorites : RssEffect
|
||||||
|
data object OpenSourceManage : RssEffect
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user