Move more components

(cherry picked from commit dd71c76a8f0b760ec806e71be77998bbc2da61a3)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt
This commit is contained in:
arkon
2023-02-18 17:04:32 -05:00
committed by Jobobby04
parent 4db8fa8f12
commit 586068d720
21 changed files with 36 additions and 37 deletions
@@ -40,7 +40,6 @@ import eu.kanade.presentation.browse.components.BaseBrowseItem
import eu.kanade.presentation.browse.components.ExtensionIcon
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
import eu.kanade.presentation.theme.header
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.extension.model.InstallStep
@@ -54,6 +53,7 @@ import tachiyomi.presentation.core.components.LoadingScreen
import tachiyomi.presentation.core.components.material.PullRefresh
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.components.material.topSmallPaddingValues
import tachiyomi.presentation.core.theme.header
import tachiyomi.presentation.core.util.plus
import tachiyomi.presentation.core.util.secondaryItemAlpha
@@ -28,7 +28,6 @@ import eu.kanade.domain.source.interactor.SetMigrateSorting
import eu.kanade.presentation.browse.components.BaseSourceItem
import eu.kanade.presentation.browse.components.SourceIcon
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.theme.header
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrateSourceState
import eu.kanade.tachiyomi.util.system.copyToClipboard
@@ -40,6 +39,7 @@ import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.Scroller.STICKY_HEADER_KEY_PREFIX
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.components.material.topSmallPaddingValues
import tachiyomi.presentation.core.theme.header
import tachiyomi.presentation.core.util.plus
import tachiyomi.presentation.core.util.secondaryItemAlpha
@@ -30,7 +30,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.browse.components.BaseSourceItem
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.theme.header
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.ui.browse.source.SourcesState
@@ -42,6 +41,7 @@ import tachiyomi.presentation.core.components.LoadingScreen
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.components.material.topSmallPaddingValues
import tachiyomi.presentation.core.theme.header
import tachiyomi.presentation.core.util.plus
@Composable
@@ -1,4 +1,4 @@
package eu.kanade.presentation.components.dialogs
package eu.kanade.presentation.category
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
@@ -22,7 +22,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import eu.kanade.core.prefs.CheckboxState
import eu.kanade.presentation.category.visualName
import eu.kanade.tachiyomi.R
import tachiyomi.domain.category.model.Category
import tachiyomi.presentation.core.components.material.TextButton
@@ -276,18 +276,16 @@ fun SearchToolbar(
visualTransformation = visualTransformation,
interactionSource = interactionSource,
placeholder = {
(placeholderText ?: stringResource(R.string.action_search_hint)).let { placeholderText ->
Text(
modifier = Modifier.secondaryItemAlpha(),
text = placeholderText,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.titleMedium.copy(
fontSize = 18.sp,
fontWeight = FontWeight.Normal,
),
)
}
Text(
modifier = Modifier.secondaryItemAlpha(),
text = (placeholderText ?: stringResource(R.string.action_search_hint)),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.titleMedium.copy(
fontSize = 18.sp,
fontWeight = FontWeight.Normal,
),
)
},
)
},
@@ -1,260 +0,0 @@
package eu.kanade.presentation.components
import androidx.compose.foundation.gestures.FlingBehavior
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.LazyListItemInfo
import androidx.compose.foundation.lazy.LazyListLayoutInfo
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.listSaver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Density
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastMaxBy
import androidx.compose.ui.util.fastSumBy
import kotlinx.coroutines.flow.distinctUntilChanged
import tachiyomi.presentation.core.components.LazyColumn
@Composable
fun HorizontalPager(
count: Int,
modifier: Modifier = Modifier,
state: PagerState = rememberPagerState(),
key: ((page: Int) -> Any)? = null,
contentPadding: PaddingValues = PaddingValues(),
verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
userScrollEnabled: Boolean = true,
content: @Composable BoxScope.(page: Int) -> Unit,
) {
Pager(
count = count,
modifier = modifier,
state = state,
isVertical = false,
key = key,
contentPadding = contentPadding,
verticalAlignment = verticalAlignment,
userScrollEnabled = userScrollEnabled,
content = content,
)
}
@Composable
private fun Pager(
count: Int,
modifier: Modifier,
state: PagerState,
isVertical: Boolean,
key: ((page: Int) -> Any)?,
contentPadding: PaddingValues,
userScrollEnabled: Boolean,
verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
horizontalAlignment: Alignment.Horizontal = Alignment.CenterHorizontally,
content: @Composable BoxScope.(page: Int) -> Unit,
) {
LaunchedEffect(count) {
state.currentPage = minOf(count - 1, state.currentPage).coerceAtLeast(0)
}
LaunchedEffect(state) {
snapshotFlow { state.mostVisiblePageLayoutInfo?.index }
.distinctUntilChanged()
.collect { state.updateCurrentPageBasedOnLazyListState() }
}
if (isVertical) {
LazyColumn(
modifier = modifier,
state = state.lazyListState,
contentPadding = contentPadding,
horizontalAlignment = horizontalAlignment,
verticalArrangement = Arrangement.aligned(verticalAlignment),
userScrollEnabled = userScrollEnabled,
flingBehavior = rememberLazyListSnapFlingBehavior(lazyListState = state.lazyListState),
) {
items(
count = count,
key = key,
) { page ->
Box(
modifier = Modifier
.fillParentMaxHeight()
.wrapContentSize(),
) {
content(this, page)
}
}
}
} else {
LazyRow(
modifier = modifier,
state = state.lazyListState,
contentPadding = contentPadding,
verticalAlignment = verticalAlignment,
horizontalArrangement = Arrangement.aligned(horizontalAlignment),
userScrollEnabled = userScrollEnabled,
flingBehavior = rememberLazyListSnapFlingBehavior(lazyListState = state.lazyListState),
) {
items(
count = count,
key = key,
) { page ->
Box(
modifier = Modifier
.fillParentMaxWidth()
.wrapContentSize(),
) {
content(this, page)
}
}
}
}
}
@Composable
fun rememberPagerState(
initialPage: Int = 0,
) = rememberSaveable(saver = PagerState.Saver) {
PagerState(currentPage = initialPage)
}
@Stable
class PagerState(
currentPage: Int = 0,
) {
init { check(currentPage >= 0) { "currentPage cannot be less than zero" } }
val lazyListState = LazyListState(firstVisibleItemIndex = currentPage)
private var _currentPage by mutableStateOf(currentPage)
var currentPage: Int
get() = _currentPage
set(value) {
if (value != _currentPage) {
_currentPage = value
}
}
val mostVisiblePageLayoutInfo: LazyListItemInfo?
get() {
val layoutInfo = lazyListState.layoutInfo
return layoutInfo.visibleItemsInfo.fastMaxBy {
val start = maxOf(it.offset, 0)
val end = minOf(
it.offset + it.size,
layoutInfo.viewportEndOffset - layoutInfo.afterContentPadding,
)
end - start
}
}
fun updateCurrentPageBasedOnLazyListState() {
mostVisiblePageLayoutInfo?.let {
currentPage = it.index
}
}
suspend fun animateScrollToPage(page: Int) {
lazyListState.animateScrollToItem(index = page)
}
suspend fun scrollToPage(page: Int) {
lazyListState.scrollToItem(index = page)
updateCurrentPageBasedOnLazyListState()
}
companion object {
val Saver: Saver<PagerState, *> = listSaver(
save = { listOf(it.currentPage) },
restore = { PagerState(it[0]) },
)
}
}
// https://android.googlesource.com/platform/frameworks/support/+/refs/changes/78/2160778/35/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
private fun lazyListSnapLayoutInfoProvider(
lazyListState: LazyListState,
positionInLayout: (layoutSize: Float, itemSize: Float) -> Float = { layoutSize, itemSize ->
layoutSize / 2f - itemSize / 2f
},
) = object : SnapLayoutInfoProvider {
private val layoutInfo: LazyListLayoutInfo
get() = lazyListState.layoutInfo
// Single page snapping is the default
override fun Density.calculateApproachOffset(initialVelocity: Float): Float = 0f
override fun Density.calculateSnappingOffsetBounds(): ClosedFloatingPointRange<Float> {
var lowerBoundOffset = Float.NEGATIVE_INFINITY
var upperBoundOffset = Float.POSITIVE_INFINITY
layoutInfo.visibleItemsInfo.fastForEach { item ->
val offset =
calculateDistanceToDesiredSnapPosition(layoutInfo, item, positionInLayout)
// Find item that is closest to the center
if (offset <= 0 && offset > lowerBoundOffset) {
lowerBoundOffset = offset
}
// Find item that is closest to center, but after it
if (offset >= 0 && offset < upperBoundOffset) {
upperBoundOffset = offset
}
}
return lowerBoundOffset.rangeTo(upperBoundOffset)
}
override fun Density.calculateSnapStepSize(): Float = with(layoutInfo) {
if (visibleItemsInfo.isNotEmpty()) {
visibleItemsInfo.fastSumBy { it.size } / visibleItemsInfo.size.toFloat()
} else {
0f
}
}
}
@Composable
private fun rememberLazyListSnapFlingBehavior(lazyListState: LazyListState): FlingBehavior {
val snappingLayout = remember(lazyListState) { lazyListSnapLayoutInfoProvider(lazyListState) }
return rememberSnapFlingBehavior(snappingLayout)
}
private fun calculateDistanceToDesiredSnapPosition(
layoutInfo: LazyListLayoutInfo,
item: LazyListItemInfo,
positionInLayout: (layoutSize: Float, itemSize: Float) -> Float,
): Float {
val containerSize =
with(layoutInfo) { singleAxisViewportSize - beforeContentPadding - afterContentPadding }
val desiredDistance =
positionInLayout(containerSize.toFloat(), item.size.toFloat())
val itemCurrentPosition = item.offset
return itemCurrentPosition - desiredDistance
}
private val LazyListLayoutInfo.singleAxisViewportSize: Int
get() = if (orientation == Orientation.Vertical) viewportSize.height else viewportSize.width
@@ -31,8 +31,10 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEachIndexed
import eu.kanade.tachiyomi.R
import kotlinx.coroutines.launch
import tachiyomi.presentation.core.components.HorizontalPager
import tachiyomi.presentation.core.components.material.Divider
import tachiyomi.presentation.core.components.material.TabIndicator
import tachiyomi.presentation.core.components.rememberPagerState
object TabbedDialogPaddings {
val Horizontal = 24.dp
@@ -21,9 +21,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
import kotlinx.coroutines.launch
import tachiyomi.presentation.core.components.HorizontalPager
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.TabIndicator
import tachiyomi.presentation.core.components.material.TabText
import tachiyomi.presentation.core.components.rememberPagerState
@Composable
fun TabbedScreen(
@@ -1,4 +1,4 @@
package eu.kanade.presentation.components.dialogs
package eu.kanade.presentation.library
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
@@ -16,7 +16,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
import eu.kanade.core.prefs.PreferenceMutableState
import eu.kanade.presentation.components.rememberPagerState
import eu.kanade.tachiyomi.ui.library.LibraryItem
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -24,6 +23,7 @@ import tachiyomi.domain.category.model.Category
import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.presentation.core.components.material.PullRefresh
import tachiyomi.presentation.core.components.rememberPagerState
import kotlin.time.Duration.Companion.seconds
@Composable
@@ -18,12 +18,12 @@ import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp
import eu.kanade.core.prefs.PreferenceMutableState
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.HorizontalPager
import eu.kanade.presentation.components.PagerState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.LibraryItem
import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.presentation.core.components.HorizontalPager
import tachiyomi.presentation.core.components.PagerState
import tachiyomi.presentation.core.util.plus
@Composable
@@ -23,9 +23,9 @@ import androidx.compose.ui.unit.sp
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.OverflowMenu
import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.theme.active
import eu.kanade.tachiyomi.R
import tachiyomi.presentation.core.components.Pill
import tachiyomi.presentation.core.theme.active
@Composable
fun LibraryToolbar(
@@ -1,4 +1,4 @@
package eu.kanade.presentation.components.dialogs
package eu.kanade.presentation.manga
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@@ -29,8 +29,8 @@ import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.DownloadDropdownMenu
import eu.kanade.presentation.components.OverflowMenu
import eu.kanade.presentation.manga.DownloadAction
import eu.kanade.presentation.theme.active
import eu.kanade.tachiyomi.R
import tachiyomi.presentation.core.theme.active
@Composable
fun MangaToolbar(
@@ -1,12 +0,0 @@
package eu.kanade.presentation.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.ColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
val ColorScheme.active: Color
@Composable
get() {
return if (isSystemInDarkTheme()) Color(255, 235, 59) else Color(255, 193, 7)
}
@@ -9,7 +9,6 @@ import androidx.compose.ui.platform.LocalLayoutDirection
import com.google.accompanist.themeadapter.material3.createMdc3Theme
import eu.kanade.domain.ui.model.AppTheme
import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegate
import uy.kohesive.injekt.api.get
@Composable
fun TachiyomiTheme(content: @Composable () -> Unit) {
@@ -1,14 +0,0 @@
package eu.kanade.presentation.theme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Typography
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
val Typography.header: TextStyle
@Composable
get() = bodyMedium.copy(
color = MaterialTheme.colorScheme.onSurfaceVariant,
fontWeight = FontWeight.SemiBold,
)
@@ -45,8 +45,8 @@ import eu.kanade.presentation.browse.components.FailedToLoadSavedSearchDialog
import eu.kanade.presentation.browse.components.RemoveMangaDialog
import eu.kanade.presentation.browse.components.SavedSearchCreateDialog
import eu.kanade.presentation.browse.components.SavedSearchDeleteDialog
import eu.kanade.presentation.components.dialogs.ChangeCategoryDialog
import eu.kanade.presentation.components.dialogs.DuplicateMangaDialog
import eu.kanade.presentation.category.ChangeCategoryDialog
import eu.kanade.presentation.manga.DuplicateMangaDialog
import eu.kanade.presentation.util.AssistContentScreen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.CatalogueSource
@@ -31,10 +31,10 @@ import cafe.adriel.voyager.navigator.tab.TabOptions
import eu.kanade.domain.UnsortedPreferences
import eu.kanade.domain.library.model.LibraryGroup
import eu.kanade.domain.manga.model.isLocal
import eu.kanade.presentation.category.ChangeCategoryDialog
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.EmptyScreenAction
import eu.kanade.presentation.components.dialogs.ChangeCategoryDialog
import eu.kanade.presentation.components.dialogs.DeleteLibraryMangaDialog
import eu.kanade.presentation.library.DeleteLibraryMangaDialog
import eu.kanade.presentation.library.components.LibraryContent
import eu.kanade.presentation.library.components.LibraryToolbar
import eu.kanade.presentation.library.components.SyncFavoritesConfirmDialog
@@ -28,10 +28,10 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.domain.UnsortedPreferences
import eu.kanade.domain.manga.model.hasCustomCover
import eu.kanade.domain.manga.model.toSManga
import eu.kanade.presentation.category.ChangeCategoryDialog
import eu.kanade.presentation.components.NavigatorAdaptiveSheet
import eu.kanade.presentation.components.dialogs.ChangeCategoryDialog
import eu.kanade.presentation.components.dialogs.DuplicateMangaDialog
import eu.kanade.presentation.manga.ChapterSettingsDialog
import eu.kanade.presentation.manga.DuplicateMangaDialog
import eu.kanade.presentation.manga.EditCoverAction
import eu.kanade.presentation.manga.MangaScreen
import eu.kanade.presentation.manga.components.DeleteChaptersDialog
@@ -19,8 +19,8 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.browse.BrowseSourceContent
import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
import eu.kanade.presentation.browse.components.RemoveMangaDialog
import eu.kanade.presentation.components.dialogs.ChangeCategoryDialog
import eu.kanade.presentation.components.dialogs.DuplicateMangaDialog
import eu.kanade.presentation.category.ChangeCategoryDialog
import eu.kanade.presentation.manga.DuplicateMangaDialog
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel
import eu.kanade.tachiyomi.ui.category.CategoryScreen