Add new manga screen variant
This commit is contained in:
@@ -1,14 +1,9 @@
|
|||||||
package org.xtimms.shirizu.core.components
|
package org.xtimms.shirizu.core.components
|
||||||
|
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.RowScope
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.FavoriteBorder
|
|
||||||
import androidx.compose.material.icons.filled.MoreVert
|
import androidx.compose.material.icons.filled.MoreVert
|
||||||
import androidx.compose.material.icons.filled.Share
|
import androidx.compose.material.icons.filled.Share
|
||||||
import androidx.compose.material.icons.outlined.Download
|
import androidx.compose.material.icons.outlined.Download
|
||||||
@@ -32,13 +27,12 @@ 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.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clipToBounds
|
|
||||||
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
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun DetailsToolbar(
|
fun ModernDetailsToolbar(
|
||||||
title: String,
|
title: String,
|
||||||
titleAlphaProvider: () -> Float,
|
titleAlphaProvider: () -> Float,
|
||||||
navigateBack: () -> Unit,
|
navigateBack: () -> Unit,
|
||||||
@@ -118,4 +112,76 @@ fun DetailsToolbar(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun ClassicDetailsToolbar(
|
||||||
|
title: String,
|
||||||
|
titleAlphaProvider: () -> Float,
|
||||||
|
navigateBack: () -> Unit,
|
||||||
|
navigateToWebBrowser: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
backgroundAlphaProvider: () -> Float = titleAlphaProvider
|
||||||
|
) {
|
||||||
|
|
||||||
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = modifier
|
||||||
|
) {
|
||||||
|
TopAppBar(
|
||||||
|
navigationIcon = {
|
||||||
|
BackIconButton(
|
||||||
|
onClick = navigateBack
|
||||||
|
)
|
||||||
|
},
|
||||||
|
title = {
|
||||||
|
Text(
|
||||||
|
text = title,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
color = LocalContentColor.current.copy(alpha = titleAlphaProvider()),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
actions = {
|
||||||
|
IconButton(
|
||||||
|
onClick = { expanded = true }
|
||||||
|
) {
|
||||||
|
Icon(imageVector = Icons.Default.MoreVert, contentDescription = null)
|
||||||
|
}
|
||||||
|
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text("Share") },
|
||||||
|
onClick = { /*TODO*/ },
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(imageVector = Icons.Default.Share, contentDescription = null)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text("Download") },
|
||||||
|
onClick = { /*TODO*/ },
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(imageVector = Icons.Outlined.Download, contentDescription = null)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text("Open in web browser") },
|
||||||
|
onClick = {
|
||||||
|
navigateToWebBrowser()
|
||||||
|
expanded = false
|
||||||
|
},
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(imageVector = Icons.Outlined.Language, contentDescription = null)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = TopAppBarDefaults.topAppBarColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme
|
||||||
|
.surfaceColorAtElevation(3.dp)
|
||||||
|
.copy(alpha = backgroundAlphaProvider())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -27,9 +27,9 @@ fun SettingTitle(text: String) {
|
|||||||
Text(
|
Text(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = 32.dp)
|
.padding(top = 32.dp)
|
||||||
.padding(horizontal = 20.dp, vertical = 16.dp),
|
.padding(horizontal = 16.dp, vertical = 16.dp),
|
||||||
text = text,
|
text = text,
|
||||||
style = MaterialTheme.typography.displaySmall
|
style = MaterialTheme.typography.headlineLarge
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import androidx.compose.foundation.lazy.LazyRow
|
|||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.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.filled.QueryStats
|
|
||||||
import androidx.compose.material.icons.outlined.MoreVert
|
import androidx.compose.material.icons.outlined.MoreVert
|
||||||
|
import androidx.compose.material.icons.outlined.QueryStats
|
||||||
import androidx.compose.material.icons.outlined.RssFeed
|
import androidx.compose.material.icons.outlined.RssFeed
|
||||||
import androidx.compose.material.icons.outlined.Search
|
import androidx.compose.material.icons.outlined.Search
|
||||||
import androidx.compose.material.icons.outlined.SentimentSatisfiedAlt
|
import androidx.compose.material.icons.outlined.SentimentSatisfiedAlt
|
||||||
@@ -41,6 +41,7 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.material3.MediumTopAppBar
|
import androidx.compose.material3.MediumTopAppBar
|
||||||
import androidx.compose.material3.SuggestionChip
|
import androidx.compose.material3.SuggestionChip
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||||
import androidx.compose.material3.surfaceColorAtElevation
|
import androidx.compose.material3.surfaceColorAtElevation
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -63,6 +64,7 @@ import org.xtimms.shirizu.R
|
|||||||
import org.xtimms.shirizu.core.DURATION_ENTER
|
import org.xtimms.shirizu.core.DURATION_ENTER
|
||||||
import org.xtimms.shirizu.core.DURATION_EXIT
|
import org.xtimms.shirizu.core.DURATION_EXIT
|
||||||
import org.xtimms.shirizu.core.initialOffset
|
import org.xtimms.shirizu.core.initialOffset
|
||||||
|
import org.xtimms.shirizu.core.prefs.AppSettings
|
||||||
import org.xtimms.shirizu.core.toEasing
|
import org.xtimms.shirizu.core.toEasing
|
||||||
import org.xtimms.shirizu.sections.explore.EXPLORE_DESTINATION
|
import org.xtimms.shirizu.sections.explore.EXPLORE_DESTINATION
|
||||||
import org.xtimms.shirizu.sections.feed.FEED_DESTINATION
|
import org.xtimms.shirizu.sections.feed.FEED_DESTINATION
|
||||||
@@ -167,53 +169,76 @@ fun TopAppBar(
|
|||||||
Row(
|
Row(
|
||||||
modifier = modifier.padding(end = 16.dp),
|
modifier = modifier.padding(end = 16.dp),
|
||||||
) {
|
) {
|
||||||
IconButton(
|
if (AppSettings.isTrackerEnabled()) {
|
||||||
onClick = { navController.navigate(FEED_DESTINATION) },
|
IconButton(
|
||||||
modifier = Modifier.padding(0.dp),
|
onClick = { navController.navigate(FEED_DESTINATION) },
|
||||||
) {
|
modifier = Modifier.padding(0.dp),
|
||||||
Icon(
|
) {
|
||||||
Icons.Outlined.RssFeed,
|
Icon(
|
||||||
contentDescription = stringResource(id = R.string.feed),
|
Icons.Outlined.RssFeed,
|
||||||
tint = MaterialTheme.colorScheme.outline
|
contentDescription = stringResource(id = R.string.feed),
|
||||||
)
|
tint = MaterialTheme.colorScheme.outline
|
||||||
}
|
)
|
||||||
IconButton(
|
}
|
||||||
onClick = { expanded = true },
|
IconButton(
|
||||||
modifier = Modifier.padding(0.dp),
|
onClick = { expanded = true },
|
||||||
) {
|
modifier = Modifier.padding(0.dp),
|
||||||
Icon(
|
) {
|
||||||
Icons.Outlined.MoreVert,
|
Icon(
|
||||||
contentDescription = stringResource(id = R.string.open_menu),
|
Icons.Outlined.MoreVert,
|
||||||
tint = MaterialTheme.colorScheme.outline
|
contentDescription = stringResource(id = R.string.open_menu),
|
||||||
)
|
tint = MaterialTheme.colorScheme.outline
|
||||||
}
|
)
|
||||||
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
|
}
|
||||||
DropdownMenuItem(
|
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
|
||||||
text = { Text(text = stringResource(id = R.string.statistics)) },
|
DropdownMenuItem(
|
||||||
onClick = {
|
text = { Text(text = stringResource(id = R.string.statistics)) },
|
||||||
navController.navigate(STATS_DESTINATION)
|
onClick = {
|
||||||
expanded = false
|
navController.navigate(STATS_DESTINATION)
|
||||||
},
|
expanded = false
|
||||||
leadingIcon = {
|
},
|
||||||
Icon(
|
leadingIcon = {
|
||||||
imageVector = Icons.Default.QueryStats,
|
Icon(
|
||||||
contentDescription = stringResource(id = R.string.statistics)
|
imageVector = Icons.Outlined.QueryStats,
|
||||||
)
|
contentDescription = stringResource(id = R.string.statistics)
|
||||||
}
|
)
|
||||||
)
|
}
|
||||||
DropdownMenuItem(
|
)
|
||||||
text = { Text(text = stringResource(id = R.string.settings)) },
|
DropdownMenuItem(
|
||||||
onClick = {
|
text = { Text(text = stringResource(id = R.string.settings)) },
|
||||||
navController.navigate(SETTINGS_DESTINATION)
|
onClick = {
|
||||||
expanded = false
|
navController.navigate(SETTINGS_DESTINATION)
|
||||||
},
|
expanded = false
|
||||||
leadingIcon = {
|
},
|
||||||
Icon(
|
leadingIcon = {
|
||||||
imageVector = Icons.Outlined.Settings,
|
Icon(
|
||||||
contentDescription = stringResource(id = R.string.settings)
|
imageVector = Icons.Outlined.Settings,
|
||||||
)
|
contentDescription = stringResource(id = R.string.settings)
|
||||||
}
|
)
|
||||||
)
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
IconButton(
|
||||||
|
onClick = { navController.navigate(STATS_DESTINATION) },
|
||||||
|
modifier = Modifier.padding(0.dp),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Outlined.QueryStats,
|
||||||
|
contentDescription = stringResource(id = R.string.statistics),
|
||||||
|
tint = MaterialTheme.colorScheme.outline
|
||||||
|
)
|
||||||
|
}
|
||||||
|
IconButton(
|
||||||
|
onClick = { navController.navigate(SETTINGS_DESTINATION) },
|
||||||
|
modifier = Modifier.padding(0.dp),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Outlined.Settings,
|
||||||
|
contentDescription = stringResource(id = R.string.settings),
|
||||||
|
tint = MaterialTheme.colorScheme.outline
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,18 +296,36 @@ fun SmallTopAppBarWithChips(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val path = Path().apply {
|
||||||
|
moveTo(0f,0f)
|
||||||
|
lineTo(0.7f, 0.1f)
|
||||||
|
cubicTo(0.7f, 0.1f, .95F, .5F, 1F, 1F)
|
||||||
|
moveTo(1f,1f)
|
||||||
|
}
|
||||||
|
|
||||||
|
val fraction: (Float) -> Float = { PathInterpolator(path).getInterpolation(it) }
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SmallTopAppBar(
|
fun SmallTopAppBar(
|
||||||
title: String,
|
modifier: Modifier = Modifier,
|
||||||
scrollBehavior: TopAppBarScrollBehavior? = null,
|
titleText: String = "",
|
||||||
navigateBack: () -> Unit,
|
scrollBehavior: TopAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(),
|
||||||
|
title: @Composable () -> Unit = {
|
||||||
|
Text(
|
||||||
|
text = titleText,
|
||||||
|
color = MaterialTheme.colorScheme.onSurface.copy(alpha = fraction(scrollBehavior.state.overlappedFraction)),
|
||||||
|
maxLines = 1
|
||||||
|
)
|
||||||
|
},
|
||||||
|
navigationIcon: @Composable () -> Unit = {},
|
||||||
|
actions: @Composable RowScope.() -> Unit = {},
|
||||||
) {
|
) {
|
||||||
MediumTopAppBar(
|
androidx.compose.material3.TopAppBar(
|
||||||
title = { Text(text = title) },
|
modifier = modifier,
|
||||||
navigationIcon = {
|
title = title,
|
||||||
BackIconButton(onClick = navigateBack)
|
navigationIcon = navigationIcon,
|
||||||
},
|
actions = actions,
|
||||||
scrollBehavior = scrollBehavior
|
scrollBehavior = scrollBehavior
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ const val RELATED = "related"
|
|||||||
const val TRACKER = "tracker"
|
const val TRACKER = "tracker"
|
||||||
const val CELLULAR_DOWNLOAD = "cellular_download"
|
const val CELLULAR_DOWNLOAD = "cellular_download"
|
||||||
const val STATISTICS = "statistics"
|
const val STATISTICS = "statistics"
|
||||||
|
const val MODERN_VIEW = "modern_view"
|
||||||
|
|
||||||
const val PROXY_TYPE = "proxy_type"
|
const val PROXY_TYPE = "proxy_type"
|
||||||
const val PROXY_ADDRESS = "proxy_address"
|
const val PROXY_ADDRESS = "proxy_address"
|
||||||
@@ -170,6 +171,8 @@ object AppSettings {
|
|||||||
|
|
||||||
fun isStatisticsEnabled() = STATISTICS.getBoolean()
|
fun isStatisticsEnabled() = STATISTICS.getBoolean()
|
||||||
|
|
||||||
|
fun isModernViewEnabled() = MODERN_VIEW.getBoolean(true)
|
||||||
|
|
||||||
fun getGridColumnsCount(columns: Int = GRID_COLUMNS.getInt()): Float {
|
fun getGridColumnsCount(columns: Int = GRID_COLUMNS.getInt()): Float {
|
||||||
return when (columns) {
|
return when (columns) {
|
||||||
1 -> 1f
|
1 -> 1f
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.shirizu.core.screens
|
package org.xtimms.shirizu.core.ui.screens
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.shirizu.core.screens
|
package org.xtimms.shirizu.core.ui.screens
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.animation.AnimatedContent
|
||||||
import androidx.compose.animation.core.RepeatMode
|
import androidx.compose.animation.core.RepeatMode
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.shirizu.core.screens
|
package org.xtimms.shirizu.core.ui.screens
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -19,7 +19,7 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import org.acra.ktx.sendWithAcra
|
import org.acra.ktx.sendWithAcra
|
||||||
import org.xtimms.shirizu.R
|
import org.xtimms.shirizu.R
|
||||||
import org.xtimms.shirizu.core.screens.InfoScreen
|
import org.xtimms.shirizu.core.ui.screens.InfoScreen
|
||||||
import org.xtimms.shirizu.ui.theme.ShirizuTheme
|
import org.xtimms.shirizu.ui.theme.ShirizuTheme
|
||||||
import org.xtimms.shirizu.utils.system.toast
|
import org.xtimms.shirizu.utils.system.toast
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,244 @@
|
|||||||
|
package org.xtimms.shirizu.sections.details
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.sizeIn
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.alpha
|
||||||
|
import androidx.compose.ui.draw.blur
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.draw.drawWithContent
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.semantics.Role
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import coil.ImageLoader
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||||
|
import org.xtimms.shirizu.R
|
||||||
|
import org.xtimms.shirizu.core.AsyncImageImpl
|
||||||
|
import org.xtimms.shirizu.core.components.MangaCover
|
||||||
|
import org.xtimms.shirizu.sections.details.data.ReadingTime
|
||||||
|
import org.xtimms.shirizu.sections.details.model.HistoryInfo
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ClassicDetailsInfoBox(
|
||||||
|
coil: ImageLoader,
|
||||||
|
imageUrl: String,
|
||||||
|
favicon: Uri,
|
||||||
|
title: String,
|
||||||
|
altTitle: String,
|
||||||
|
author: String,
|
||||||
|
isNsfw: Boolean,
|
||||||
|
state: MangaState?,
|
||||||
|
source: MangaSource,
|
||||||
|
historyInfo: HistoryInfo,
|
||||||
|
readingTime: ReadingTime?,
|
||||||
|
isTabletUi: Boolean,
|
||||||
|
appBarPadding: Dp,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
onCoverClick: () -> Unit,
|
||||||
|
isInShelf: Boolean,
|
||||||
|
onAddToShelfClicked: () -> Unit,
|
||||||
|
onSourceClicked: () -> Unit,
|
||||||
|
onDownloadClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
|
||||||
|
Box(modifier = modifier) {
|
||||||
|
// Backdrop
|
||||||
|
val backdropGradientColors = listOf(
|
||||||
|
Color.Transparent,
|
||||||
|
MaterialTheme.colorScheme.background,
|
||||||
|
)
|
||||||
|
AsyncImageImpl(
|
||||||
|
coil = coil,
|
||||||
|
model = imageUrl,
|
||||||
|
contentDescription = null,
|
||||||
|
contentScale = ContentScale.Crop,
|
||||||
|
modifier = Modifier
|
||||||
|
.matchParentSize()
|
||||||
|
.drawWithContent {
|
||||||
|
drawContent()
|
||||||
|
drawRect(
|
||||||
|
brush = Brush.verticalGradient(colors = backdropGradientColors),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.blur(3.dp)
|
||||||
|
.alpha(0.33f),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Manga & source info
|
||||||
|
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
|
||||||
|
if (!isTabletUi) {
|
||||||
|
MangaInfoSmall(
|
||||||
|
coil = coil,
|
||||||
|
appBarPadding = appBarPadding,
|
||||||
|
imageUrl = imageUrl,
|
||||||
|
favicon = favicon,
|
||||||
|
title = title,
|
||||||
|
altTitle = altTitle,
|
||||||
|
author = author,
|
||||||
|
state = state,
|
||||||
|
source = source,
|
||||||
|
isInShelf = isInShelf,
|
||||||
|
onAddToShelfClicked = onAddToShelfClicked,
|
||||||
|
onCoverClick = onCoverClick,
|
||||||
|
onSourceClicked = onSourceClicked,
|
||||||
|
historyInfo = historyInfo,
|
||||||
|
readingTime = readingTime,
|
||||||
|
onDownloadClick = onDownloadClick
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
MangaInfoLarge(
|
||||||
|
coil = coil,
|
||||||
|
appBarPadding = appBarPadding,
|
||||||
|
imageUrl = imageUrl,
|
||||||
|
favicon = favicon,
|
||||||
|
title = title,
|
||||||
|
altTitle = altTitle,
|
||||||
|
author = author,
|
||||||
|
state = state,
|
||||||
|
source = source,
|
||||||
|
isInShelf = isInShelf,
|
||||||
|
onAddToShelfClicked = onAddToShelfClicked,
|
||||||
|
onCoverClick = onCoverClick,
|
||||||
|
onSourceClicked = onSourceClicked,
|
||||||
|
historyInfo = historyInfo,
|
||||||
|
readingTime = readingTime,
|
||||||
|
onDownloadClick = onDownloadClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MangaInfoLarge(
|
||||||
|
coil: ImageLoader,
|
||||||
|
appBarPadding: Dp,
|
||||||
|
imageUrl: String,
|
||||||
|
favicon: Uri,
|
||||||
|
title: String,
|
||||||
|
altTitle: String,
|
||||||
|
author: String,
|
||||||
|
source: MangaSource,
|
||||||
|
state: MangaState?,
|
||||||
|
historyInfo: HistoryInfo,
|
||||||
|
readingTime: ReadingTime?,
|
||||||
|
isInShelf: Boolean,
|
||||||
|
onAddToShelfClicked: () -> Unit,
|
||||||
|
onCoverClick: () -> Unit,
|
||||||
|
onSourceClicked: () -> Unit,
|
||||||
|
onDownloadClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 16.dp, top = appBarPadding + 16.dp, end = 16.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
MangaCover.Book(
|
||||||
|
coil = coil,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(0.65f)
|
||||||
|
.clickable(
|
||||||
|
role = Role.Button,
|
||||||
|
onClick = onCoverClick
|
||||||
|
),
|
||||||
|
data = imageUrl,
|
||||||
|
contentDescription = stringResource(R.string.manga_cover),
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
DetailsContentInfo(
|
||||||
|
coil = coil,
|
||||||
|
favicon = favicon,
|
||||||
|
title = title,
|
||||||
|
altTitle = altTitle,
|
||||||
|
author = author,
|
||||||
|
state = state,
|
||||||
|
source = source.title,
|
||||||
|
isInShelf = isInShelf,
|
||||||
|
onAddToShelfClicked = onAddToShelfClicked,
|
||||||
|
onSourceClicked = onSourceClicked,
|
||||||
|
historyInfo = historyInfo,
|
||||||
|
readingTime = readingTime,
|
||||||
|
onDownloadClick = onDownloadClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MangaInfoSmall(
|
||||||
|
coil: ImageLoader,
|
||||||
|
appBarPadding: Dp,
|
||||||
|
imageUrl: String,
|
||||||
|
favicon: Uri,
|
||||||
|
title: String,
|
||||||
|
altTitle: String,
|
||||||
|
author: String,
|
||||||
|
state: MangaState?,
|
||||||
|
source: MangaSource,
|
||||||
|
historyInfo: HistoryInfo,
|
||||||
|
readingTime: ReadingTime?,
|
||||||
|
isInShelf: Boolean,
|
||||||
|
onAddToShelfClicked: () -> Unit,
|
||||||
|
onCoverClick: () -> Unit,
|
||||||
|
onSourceClicked: () -> Unit,
|
||||||
|
onDownloadClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = appBarPadding + 32.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
AsyncImageImpl(
|
||||||
|
coil = coil,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.sizeIn(maxWidth = 54.dp)
|
||||||
|
.align(Alignment.Start)
|
||||||
|
.aspectRatio(1f)
|
||||||
|
.clip(CircleShape)
|
||||||
|
.clickable(
|
||||||
|
role = Role.Button,
|
||||||
|
onClick = onCoverClick
|
||||||
|
),
|
||||||
|
model = imageUrl,
|
||||||
|
contentDescription = stringResource(R.string.manga_cover),
|
||||||
|
)
|
||||||
|
DetailsContentInfo(
|
||||||
|
coil = coil,
|
||||||
|
favicon = favicon,
|
||||||
|
title = title,
|
||||||
|
altTitle = altTitle,
|
||||||
|
author = author,
|
||||||
|
state = state,
|
||||||
|
source = source.title,
|
||||||
|
isInShelf = isInShelf,
|
||||||
|
onAddToShelfClicked = onAddToShelfClicked,
|
||||||
|
onSourceClicked = onSourceClicked,
|
||||||
|
historyInfo = historyInfo,
|
||||||
|
readingTime = readingTime,
|
||||||
|
onDownloadClick = onDownloadClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,33 +15,26 @@ import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
|
|||||||
import androidx.compose.animation.graphics.vector.AnimatedImageVector
|
import androidx.compose.animation.graphics.vector.AnimatedImageVector
|
||||||
import androidx.compose.foundation.BorderStroke
|
import androidx.compose.foundation.BorderStroke
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
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.ExperimentalLayoutApi
|
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||||
import androidx.compose.foundation.layout.FlowRow
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.RowScope
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
|
||||||
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.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.wrapContentSize
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.outlined.MenuBook
|
|
||||||
import androidx.compose.material.icons.outlined.Block
|
import androidx.compose.material.icons.outlined.Block
|
||||||
import androidx.compose.material.icons.outlined.Close
|
import androidx.compose.material.icons.outlined.Close
|
||||||
import androidx.compose.material.icons.outlined.DoneAll
|
import androidx.compose.material.icons.outlined.DoneAll
|
||||||
import androidx.compose.material.icons.outlined.FileDownload
|
import androidx.compose.material.icons.outlined.FileDownload
|
||||||
import androidx.compose.material.icons.outlined.KeyboardArrowDown
|
import androidx.compose.material.icons.outlined.KeyboardArrowDown
|
||||||
import androidx.compose.material.icons.outlined.Language
|
|
||||||
import androidx.compose.material.icons.outlined.LocalLibrary
|
import androidx.compose.material.icons.outlined.LocalLibrary
|
||||||
import androidx.compose.material.icons.outlined.Pause
|
import androidx.compose.material.icons.outlined.Pause
|
||||||
import androidx.compose.material.icons.outlined.Person
|
import androidx.compose.material.icons.outlined.Person
|
||||||
@@ -49,20 +42,16 @@ import androidx.compose.material.icons.outlined.Schedule
|
|||||||
import androidx.compose.material.icons.outlined.Sync
|
import androidx.compose.material.icons.outlined.Sync
|
||||||
import androidx.compose.material.icons.outlined.Upcoming
|
import androidx.compose.material.icons.outlined.Upcoming
|
||||||
import androidx.compose.material3.AssistChip
|
import androidx.compose.material3.AssistChip
|
||||||
import androidx.compose.material3.AssistChipDefaults
|
|
||||||
import androidx.compose.material3.DropdownMenu
|
import androidx.compose.material3.DropdownMenu
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.ElevatedAssistChip
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.InputChip
|
import androidx.compose.material3.InputChip
|
||||||
import androidx.compose.material3.LocalContentColor
|
|
||||||
import androidx.compose.material3.LocalMinimumInteractiveComponentEnforcement
|
import androidx.compose.material3.LocalMinimumInteractiveComponentEnforcement
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedIconButton
|
import androidx.compose.material3.OutlinedIconButton
|
||||||
import androidx.compose.material3.ProvideTextStyle
|
|
||||||
import androidx.compose.material3.SuggestionChip
|
import androidx.compose.material3.SuggestionChip
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -82,14 +71,11 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.layout.Layout
|
import androidx.compose.ui.layout.Layout
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.Role
|
|
||||||
import androidx.compose.ui.text.SpanStyle
|
import androidx.compose.ui.text.SpanStyle
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextDecoration
|
import androidx.compose.ui.text.style.TextDecoration
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.Constraints
|
import androidx.compose.ui.unit.Constraints
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@@ -105,10 +91,8 @@ import org.xtimms.shirizu.core.components.ButtonType
|
|||||||
import org.xtimms.shirizu.core.components.HtmlTextField
|
import org.xtimms.shirizu.core.components.HtmlTextField
|
||||||
import org.xtimms.shirizu.core.components.MangaCover
|
import org.xtimms.shirizu.core.components.MangaCover
|
||||||
import org.xtimms.shirizu.core.components.ReadButton
|
import org.xtimms.shirizu.core.components.ReadButton
|
||||||
import org.xtimms.shirizu.core.parser.favicon.faviconUri
|
|
||||||
import org.xtimms.shirizu.sections.details.data.ReadingTime
|
import org.xtimms.shirizu.sections.details.data.ReadingTime
|
||||||
import org.xtimms.shirizu.sections.details.model.HistoryInfo
|
import org.xtimms.shirizu.sections.details.model.HistoryInfo
|
||||||
import org.xtimms.shirizu.ui.theme.ShirizuTheme
|
|
||||||
import org.xtimms.shirizu.utils.composable.clickableNoIndication
|
import org.xtimms.shirizu.utils.composable.clickableNoIndication
|
||||||
import org.xtimms.shirizu.utils.composable.secondaryItemAlpha
|
import org.xtimms.shirizu.utils.composable.secondaryItemAlpha
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@@ -116,106 +100,7 @@ import kotlin.math.roundToInt
|
|||||||
private val whitespaceLineRegex = Regex("[\\r\\n]{2,}", setOf(RegexOption.MULTILINE))
|
private val whitespaceLineRegex = Regex("[\\r\\n]{2,}", setOf(RegexOption.MULTILINE))
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DetailsInfoBox(
|
fun MangaAndSourceTitlesLarge(
|
||||||
coil: ImageLoader,
|
|
||||||
imageUrl: String,
|
|
||||||
favicon: Uri,
|
|
||||||
title: String,
|
|
||||||
altTitle: String,
|
|
||||||
author: String,
|
|
||||||
isNsfw: Boolean,
|
|
||||||
state: MangaState?,
|
|
||||||
source: MangaSource,
|
|
||||||
historyInfo: HistoryInfo,
|
|
||||||
readingTime: ReadingTime?,
|
|
||||||
isTabletUi: Boolean,
|
|
||||||
appBarPadding: Dp,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
onCoverClick: () -> Unit,
|
|
||||||
isInShelf: Boolean,
|
|
||||||
onAddToShelfClicked: () -> Unit,
|
|
||||||
onSourceClicked: () -> Unit,
|
|
||||||
onDownloadClick: () -> Unit,
|
|
||||||
) {
|
|
||||||
Column(modifier = modifier) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth(),
|
|
||||||
contentAlignment = Alignment.BottomEnd,
|
|
||||||
) {
|
|
||||||
AsyncImageImpl(
|
|
||||||
coil = coil,
|
|
||||||
model = imageUrl,
|
|
||||||
contentDescription = null,
|
|
||||||
contentScale = ContentScale.Crop,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(start = 16.dp, end = 16.dp)
|
|
||||||
.aspectRatio(1f)
|
|
||||||
.clickable(
|
|
||||||
role = Role.Button,
|
|
||||||
onClick = onCoverClick
|
|
||||||
)
|
|
||||||
.clip(MaterialTheme.shapes.large)
|
|
||||||
)
|
|
||||||
if (isNsfw) {
|
|
||||||
ElevatedAssistChip(
|
|
||||||
modifier = Modifier.padding(end = 32.dp, bottom = 8.dp),
|
|
||||||
onClick = { /*TODO*/ },
|
|
||||||
label = {
|
|
||||||
Text(
|
|
||||||
text = "18+",
|
|
||||||
color = MaterialTheme.colorScheme.onErrorContainer
|
|
||||||
)
|
|
||||||
},
|
|
||||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.errorContainer),
|
|
||||||
colors = AssistChipDefaults.elevatedAssistChipColors()
|
|
||||||
.copy(containerColor = MaterialTheme.colorScheme.errorContainer)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
|
|
||||||
if (!isTabletUi) {
|
|
||||||
MangaAndSourceTitlesSmall(
|
|
||||||
coil = coil,
|
|
||||||
favicon = favicon,
|
|
||||||
title = title,
|
|
||||||
altTitle = altTitle,
|
|
||||||
author = author,
|
|
||||||
state = state,
|
|
||||||
source = source,
|
|
||||||
isInShelf = isInShelf,
|
|
||||||
onAddToShelfClicked = onAddToShelfClicked,
|
|
||||||
onSourceClicked = onSourceClicked,
|
|
||||||
historyInfo = historyInfo,
|
|
||||||
readingTime = readingTime,
|
|
||||||
onDownloadClick = onDownloadClick
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
MangaAndSourceTitlesLarge(
|
|
||||||
coil = coil,
|
|
||||||
appBarPadding = appBarPadding,
|
|
||||||
imageUrl = imageUrl,
|
|
||||||
favicon = favicon,
|
|
||||||
title = title,
|
|
||||||
altTitle = altTitle,
|
|
||||||
author = author,
|
|
||||||
state = state,
|
|
||||||
source = source,
|
|
||||||
isInShelf = isInShelf,
|
|
||||||
onAddToShelfClicked = onAddToShelfClicked,
|
|
||||||
onSourceClicked = onSourceClicked,
|
|
||||||
historyInfo = historyInfo,
|
|
||||||
readingTime = readingTime,
|
|
||||||
onDownloadClick = onDownloadClick
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun MangaAndSourceTitlesLarge(
|
|
||||||
coil: ImageLoader,
|
coil: ImageLoader,
|
||||||
appBarPadding: Dp,
|
appBarPadding: Dp,
|
||||||
imageUrl: String,
|
imageUrl: String,
|
||||||
@@ -264,7 +149,7 @@ private fun MangaAndSourceTitlesLarge(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun MangaAndSourceTitlesSmall(
|
fun MangaAndSourceTitlesSmall(
|
||||||
coil: ImageLoader,
|
coil: ImageLoader,
|
||||||
favicon: Uri,
|
favicon: Uri,
|
||||||
title: String,
|
title: String,
|
||||||
@@ -288,15 +173,6 @@ private fun MangaAndSourceTitlesSmall(
|
|||||||
.padding(top = 8.dp),
|
.padding(top = 8.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||||
) {
|
) {
|
||||||
/*AsyncImage(
|
|
||||||
model = imageUrl,
|
|
||||||
contentDescription = null,
|
|
||||||
contentScale = ContentScale.Crop,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(PaddingValues(bottom = 8.dp))
|
|
||||||
.clip(RoundedCornerShape(100))
|
|
||||||
.size(48.dp),
|
|
||||||
)*/
|
|
||||||
DetailsContentInfo(
|
DetailsContentInfo(
|
||||||
coil = coil,
|
coil = coil,
|
||||||
favicon = favicon,
|
favicon = favicon,
|
||||||
@@ -321,7 +197,7 @@ private fun MangaAndSourceTitlesSmall(
|
|||||||
ExperimentalMaterial3Api::class
|
ExperimentalMaterial3Api::class
|
||||||
)
|
)
|
||||||
@Composable
|
@Composable
|
||||||
private fun DetailsContentInfo(
|
fun DetailsContentInfo(
|
||||||
coil: ImageLoader,
|
coil: ImageLoader,
|
||||||
favicon: Uri,
|
favicon: Uri,
|
||||||
title: String,
|
title: String,
|
||||||
@@ -528,23 +404,6 @@ private fun DetailsContentInfo(
|
|||||||
}
|
}
|
||||||
HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
|
HorizontalDivider(modifier = Modifier.padding(vertical = 16.dp))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Row(modifier = Modifier
|
|
||||||
.weight(.5f)
|
|
||||||
.padding(start = 4.dp, end = 16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
|
||||||
AnimatedButton(
|
|
||||||
modifier = Modifier.size(54.dp),
|
|
||||||
type = KeyboardButtonType.PRIMARY,
|
|
||||||
icon = Icons.Outlined.FavoriteBorder
|
|
||||||
)
|
|
||||||
AnimatedButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.height(54.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
type = KeyboardButtonType.TERTIARY,
|
|
||||||
icon = Icons.Outlined.PlayArrow
|
|
||||||
)
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -621,7 +480,7 @@ fun ExpandableMangaDescription(
|
|||||||
) {
|
) {
|
||||||
tags.forEach {
|
tags.forEach {
|
||||||
TagsChip(
|
TagsChip(
|
||||||
modifier = DefaultTagChipModifier,
|
modifier = modifier.padding(vertical = 4.dp),
|
||||||
tag = it,
|
tag = it,
|
||||||
onClick = {
|
onClick = {
|
||||||
tagSelected = it.title
|
tagSelected = it.title
|
||||||
@@ -645,8 +504,6 @@ private fun MangaSummary(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val uriHandler = LocalUriHandler.current
|
|
||||||
|
|
||||||
val animProgress by animateFloatAsState(
|
val animProgress by animateFloatAsState(
|
||||||
targetValue = if (expanded) 1f else 0f,
|
targetValue = if (expanded) 1f else 0f,
|
||||||
label = "summary",
|
label = "summary",
|
||||||
@@ -728,8 +585,6 @@ private fun MangaSummary(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val DefaultTagChipModifier = Modifier.padding(vertical = 4.dp)
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun TagsChip(
|
private fun TagsChip(
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ import androidx.compose.foundation.layout.WindowInsets
|
|||||||
import androidx.compose.foundation.layout.calculateEndPadding
|
import androidx.compose.foundation.layout.calculateEndPadding
|
||||||
import androidx.compose.foundation.layout.calculateStartPadding
|
import androidx.compose.foundation.layout.calculateStartPadding
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
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.sizeIn
|
import androidx.compose.foundation.layout.sizeIn
|
||||||
@@ -62,12 +60,12 @@ import kotlinx.coroutines.flow.collectLatest
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||||
import org.koitharu.kotatsu.parsers.model.RATING_UNKNOWN
|
|
||||||
import org.xtimms.shirizu.LocalWindowWidthState
|
import org.xtimms.shirizu.LocalWindowWidthState
|
||||||
import org.xtimms.shirizu.R
|
import org.xtimms.shirizu.R
|
||||||
import org.xtimms.shirizu.core.HapticFeedback.slightHapticFeedback
|
import org.xtimms.shirizu.core.HapticFeedback.slightHapticFeedback
|
||||||
import org.xtimms.shirizu.core.components.DetailsToolbar
|
import org.xtimms.shirizu.core.components.ClassicDetailsToolbar
|
||||||
import org.xtimms.shirizu.core.components.MangaHorizontalItem
|
import org.xtimms.shirizu.core.components.MangaHorizontalItem
|
||||||
|
import org.xtimms.shirizu.core.components.ModernDetailsToolbar
|
||||||
import org.xtimms.shirizu.core.parser.favicon.faviconUri
|
import org.xtimms.shirizu.core.parser.favicon.faviconUri
|
||||||
import org.xtimms.shirizu.core.prefs.AppSettings
|
import org.xtimms.shirizu.core.prefs.AppSettings
|
||||||
import org.xtimms.shirizu.core.prefs.AppSettings.getBoolean
|
import org.xtimms.shirizu.core.prefs.AppSettings.getBoolean
|
||||||
@@ -115,6 +113,7 @@ fun DetailsView(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else null
|
} else null
|
||||||
|
val isModernView = AppSettings.isModernViewEnabled()
|
||||||
|
|
||||||
val checkNetworkOrDownload = {
|
val checkNetworkOrDownload = {
|
||||||
if (!AppSettings.isNetworkAvailableForDownload()) {
|
if (!AppSettings.isNetworkAvailableForDownload()) {
|
||||||
@@ -224,13 +223,23 @@ fun DetailsView(
|
|||||||
if (!isFirstItemVisible || isFirstItemScrolled) 1f else 0f,
|
if (!isFirstItemVisible || isFirstItemScrolled) 1f else 0f,
|
||||||
label = "Top Bar Background",
|
label = "Top Bar Background",
|
||||||
)
|
)
|
||||||
DetailsToolbar(
|
if (isModernView) {
|
||||||
title = viewModel.details.value?.toManga()?.title.orEmpty(),
|
ModernDetailsToolbar(
|
||||||
titleAlphaProvider = { animatedTitleAlpha },
|
title = viewModel.details.value?.toManga()?.title.orEmpty(),
|
||||||
backgroundAlphaProvider = { animatedBgAlpha },
|
titleAlphaProvider = { animatedTitleAlpha },
|
||||||
navigateBack = { navigateBack() },
|
backgroundAlphaProvider = { animatedBgAlpha },
|
||||||
navigateToWebBrowser = { openUrl(viewModel.details.value?.toManga()?.publicUrl.orEmpty()) },
|
navigateBack = { navigateBack() },
|
||||||
)
|
navigateToWebBrowser = { openUrl(viewModel.details.value?.toManga()?.publicUrl.orEmpty()) },
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ClassicDetailsToolbar(
|
||||||
|
title = viewModel.details.value?.toManga()?.title.orEmpty(),
|
||||||
|
titleAlphaProvider = { animatedTitleAlpha },
|
||||||
|
backgroundAlphaProvider = { animatedBgAlpha },
|
||||||
|
navigateBack = { navigateBack() },
|
||||||
|
navigateToWebBrowser = { openUrl(viewModel.details.value?.toManga()?.publicUrl.orEmpty()) },
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
snackbarHost = {
|
snackbarHost = {
|
||||||
SnackbarHost(
|
SnackbarHost(
|
||||||
@@ -245,7 +254,7 @@ fun DetailsView(
|
|||||||
modifier = Modifier.fillMaxHeight(),
|
modifier = Modifier.fillMaxHeight(),
|
||||||
state = chapterListState,
|
state = chapterListState,
|
||||||
contentPadding = PaddingValues(
|
contentPadding = PaddingValues(
|
||||||
top = contentPadding.calculateTopPadding() - 60.dp,
|
top = if (isModernView) contentPadding.calculateTopPadding() - 60.dp else 0.dp,
|
||||||
start = contentPadding.calculateStartPadding(layoutDirection),
|
start = contentPadding.calculateStartPadding(layoutDirection),
|
||||||
end = contentPadding.calculateEndPadding(layoutDirection),
|
end = contentPadding.calculateEndPadding(layoutDirection),
|
||||||
bottom = contentPadding.calculateBottomPadding(),
|
bottom = contentPadding.calculateBottomPadding(),
|
||||||
@@ -256,38 +265,73 @@ fun DetailsView(
|
|||||||
key = DetailsViewItem.INFO_BOX,
|
key = DetailsViewItem.INFO_BOX,
|
||||||
contentType = DetailsViewItem.INFO_BOX
|
contentType = DetailsViewItem.INFO_BOX
|
||||||
) {
|
) {
|
||||||
DetailsInfoBox(
|
if (isModernView) {
|
||||||
coil = coil,
|
ModernDetailsInfoBox(
|
||||||
imageUrl = manga?.largeCoverUrl ?: manga?.coverUrl.orEmpty(),
|
coil = coil,
|
||||||
favicon = manga?.source?.faviconUri() ?: Uri.EMPTY,
|
imageUrl = manga?.largeCoverUrl ?: manga?.coverUrl.orEmpty(),
|
||||||
title = manga?.title.orEmpty(),
|
favicon = manga?.source?.faviconUri() ?: Uri.EMPTY,
|
||||||
altTitle = manga?.altTitle.orEmpty(),
|
title = manga?.title.orEmpty(),
|
||||||
author = manga?.author.orEmpty(),
|
altTitle = manga?.altTitle.orEmpty(),
|
||||||
isNsfw = manga?.isNsfw ?: true,
|
author = manga?.author.orEmpty(),
|
||||||
state = manga?.state ?: MangaState.FINISHED,
|
isNsfw = manga?.isNsfw ?: true,
|
||||||
source = manga?.source ?: MangaSource.DUMMY,
|
state = manga?.state ?: MangaState.FINISHED,
|
||||||
isTabletUi = false,
|
source = manga?.source ?: MangaSource.DUMMY,
|
||||||
appBarPadding = topPadding,
|
isTabletUi = false,
|
||||||
onCoverClick = {
|
appBarPadding = topPadding,
|
||||||
navigateToFullImage(
|
onCoverClick = {
|
||||||
arrayOf(
|
navigateToFullImage(
|
||||||
manga?.largeCoverUrl ?: manga?.coverUrl.orEmpty(),
|
arrayOf(
|
||||||
).toNavArgument()
|
manga?.largeCoverUrl ?: manga?.coverUrl.orEmpty(),
|
||||||
)
|
).toNavArgument()
|
||||||
},
|
)
|
||||||
historyInfo = historyInfo,
|
},
|
||||||
readingTime = readingTime,
|
historyInfo = historyInfo,
|
||||||
isInShelf = favouriteCategories,
|
readingTime = readingTime,
|
||||||
onAddToShelfClicked = {
|
isInShelf = favouriteCategories,
|
||||||
openCategoriesBottomSheet = !openCategoriesBottomSheet
|
onAddToShelfClicked = {
|
||||||
},
|
openCategoriesBottomSheet = !openCategoriesBottomSheet
|
||||||
onSourceClicked = {
|
},
|
||||||
navigateToSource(
|
onSourceClicked = {
|
||||||
manga?.source ?: MangaSource.DUMMY
|
navigateToSource(
|
||||||
)
|
manga?.source ?: MangaSource.DUMMY
|
||||||
},
|
)
|
||||||
onDownloadClick = downloadCallback
|
},
|
||||||
)
|
onDownloadClick = downloadCallback
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ClassicDetailsInfoBox(
|
||||||
|
coil = coil,
|
||||||
|
imageUrl = manga?.largeCoverUrl ?: manga?.coverUrl.orEmpty(),
|
||||||
|
favicon = manga?.source?.faviconUri() ?: Uri.EMPTY,
|
||||||
|
title = manga?.title.orEmpty(),
|
||||||
|
altTitle = manga?.altTitle.orEmpty(),
|
||||||
|
author = manga?.author.orEmpty(),
|
||||||
|
isNsfw = manga?.isNsfw ?: true,
|
||||||
|
state = manga?.state ?: MangaState.FINISHED,
|
||||||
|
source = manga?.source ?: MangaSource.DUMMY,
|
||||||
|
isTabletUi = false,
|
||||||
|
appBarPadding = topPadding,
|
||||||
|
onCoverClick = {
|
||||||
|
navigateToFullImage(
|
||||||
|
arrayOf(
|
||||||
|
manga?.largeCoverUrl ?: manga?.coverUrl.orEmpty(),
|
||||||
|
).toNavArgument()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
historyInfo = historyInfo,
|
||||||
|
readingTime = readingTime,
|
||||||
|
isInShelf = favouriteCategories,
|
||||||
|
onAddToShelfClicked = {
|
||||||
|
openCategoriesBottomSheet = !openCategoriesBottomSheet
|
||||||
|
},
|
||||||
|
onSourceClicked = {
|
||||||
|
navigateToSource(
|
||||||
|
manga?.source ?: MangaSource.DUMMY
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onDownloadClick = downloadCallback
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item(
|
item(
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
package org.xtimms.shirizu.sections.details
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.AssistChipDefaults
|
||||||
|
import androidx.compose.material3.ElevatedAssistChip
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
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.semantics.Role
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import coil.ImageLoader
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||||
|
import org.xtimms.shirizu.core.AsyncImageImpl
|
||||||
|
import org.xtimms.shirizu.sections.details.data.ReadingTime
|
||||||
|
import org.xtimms.shirizu.sections.details.model.HistoryInfo
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ModernDetailsInfoBox(
|
||||||
|
coil: ImageLoader,
|
||||||
|
imageUrl: String,
|
||||||
|
favicon: Uri,
|
||||||
|
title: String,
|
||||||
|
altTitle: String,
|
||||||
|
author: String,
|
||||||
|
isNsfw: Boolean,
|
||||||
|
state: MangaState?,
|
||||||
|
source: MangaSource,
|
||||||
|
historyInfo: HistoryInfo,
|
||||||
|
readingTime: ReadingTime?,
|
||||||
|
isTabletUi: Boolean,
|
||||||
|
appBarPadding: Dp,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
onCoverClick: () -> Unit,
|
||||||
|
isInShelf: Boolean,
|
||||||
|
onAddToShelfClicked: () -> Unit,
|
||||||
|
onSourceClicked: () -> Unit,
|
||||||
|
onDownloadClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
Column(modifier = modifier) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(),
|
||||||
|
contentAlignment = Alignment.BottomEnd,
|
||||||
|
) {
|
||||||
|
AsyncImageImpl(
|
||||||
|
coil = coil,
|
||||||
|
model = imageUrl,
|
||||||
|
contentDescription = null,
|
||||||
|
contentScale = ContentScale.Crop,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 16.dp, end = 16.dp)
|
||||||
|
.aspectRatio(1f)
|
||||||
|
.clickable(
|
||||||
|
role = Role.Button,
|
||||||
|
onClick = onCoverClick
|
||||||
|
)
|
||||||
|
.clip(MaterialTheme.shapes.large)
|
||||||
|
)
|
||||||
|
if (isNsfw) {
|
||||||
|
ElevatedAssistChip(
|
||||||
|
modifier = Modifier.padding(end = 32.dp, bottom = 8.dp),
|
||||||
|
onClick = { /*TODO*/ },
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = "18+",
|
||||||
|
color = MaterialTheme.colorScheme.onErrorContainer
|
||||||
|
)
|
||||||
|
},
|
||||||
|
border = BorderStroke(1.dp, MaterialTheme.colorScheme.errorContainer),
|
||||||
|
colors = AssistChipDefaults.elevatedAssistChipColors()
|
||||||
|
.copy(containerColor = MaterialTheme.colorScheme.errorContainer)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
|
||||||
|
if (!isTabletUi) {
|
||||||
|
MangaAndSourceTitlesSmall(
|
||||||
|
coil = coil,
|
||||||
|
favicon = favicon,
|
||||||
|
title = title,
|
||||||
|
altTitle = altTitle,
|
||||||
|
author = author,
|
||||||
|
state = state,
|
||||||
|
source = source,
|
||||||
|
isInShelf = isInShelf,
|
||||||
|
onAddToShelfClicked = onAddToShelfClicked,
|
||||||
|
onSourceClicked = onSourceClicked,
|
||||||
|
historyInfo = historyInfo,
|
||||||
|
readingTime = readingTime,
|
||||||
|
onDownloadClick = onDownloadClick
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
MangaAndSourceTitlesLarge(
|
||||||
|
coil = coil,
|
||||||
|
appBarPadding = appBarPadding,
|
||||||
|
imageUrl = imageUrl,
|
||||||
|
favicon = favicon,
|
||||||
|
title = title,
|
||||||
|
altTitle = altTitle,
|
||||||
|
author = author,
|
||||||
|
state = state,
|
||||||
|
source = source,
|
||||||
|
isInShelf = isInShelf,
|
||||||
|
onAddToShelfClicked = onAddToShelfClicked,
|
||||||
|
onSourceClicked = onSourceClicked,
|
||||||
|
historyInfo = historyInfo,
|
||||||
|
readingTime = readingTime,
|
||||||
|
onDownloadClick = onDownloadClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,7 +45,7 @@ import org.xtimms.shirizu.core.components.effects.RowEntity
|
|||||||
import org.xtimms.shirizu.core.components.effects.RowEntityType
|
import org.xtimms.shirizu.core.components.effects.RowEntityType
|
||||||
import org.xtimms.shirizu.core.components.effects.animatedItemsIndexed
|
import org.xtimms.shirizu.core.components.effects.animatedItemsIndexed
|
||||||
import org.xtimms.shirizu.core.components.effects.updateAnimatedItemsState
|
import org.xtimms.shirizu.core.components.effects.updateAnimatedItemsState
|
||||||
import org.xtimms.shirizu.core.screens.EmptyScreen
|
import org.xtimms.shirizu.core.ui.screens.EmptyScreen
|
||||||
import org.xtimms.shirizu.core.tracker.model.TrackingLogItem
|
import org.xtimms.shirizu.core.tracker.model.TrackingLogItem
|
||||||
import org.xtimms.shirizu.sections.feed.model.toFeedItem
|
import org.xtimms.shirizu.sections.feed.model.toFeedItem
|
||||||
import org.xtimms.shirizu.utils.lang.calculateTimeAgo
|
import org.xtimms.shirizu.utils.lang.calculateTimeAgo
|
||||||
|
|||||||
@@ -1,24 +1,17 @@
|
|||||||
package org.xtimms.shirizu.sections.history
|
package org.xtimms.shirizu.sections.history
|
||||||
|
|
||||||
//noinspection UsingMaterialAndMaterial3Libraries
|
//noinspection UsingMaterialAndMaterial3Libraries
|
||||||
import androidx.compose.animation.core.Animatable
|
|
||||||
import androidx.compose.animation.core.AnimationVector1D
|
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.foundation.gestures.ScrollableState
|
|
||||||
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.IntrinsicSize
|
import androidx.compose.foundation.layout.IntrinsicSize
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.calculateEndPadding
|
|
||||||
import androidx.compose.foundation.layout.calculateStartPadding
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
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.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.DismissDirection
|
import androidx.compose.material.DismissDirection
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
@@ -43,14 +36,12 @@ import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
|||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.min
|
import androidx.compose.ui.unit.min
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import org.xtimms.shirizu.R
|
import org.xtimms.shirizu.R
|
||||||
import org.xtimms.shirizu.core.collapsable
|
|
||||||
import org.xtimms.shirizu.core.components.ListGroupHeader
|
import org.xtimms.shirizu.core.components.ListGroupHeader
|
||||||
import org.xtimms.shirizu.core.components.effects.RowEntity
|
import org.xtimms.shirizu.core.components.effects.RowEntity
|
||||||
import org.xtimms.shirizu.core.components.effects.RowEntityType
|
import org.xtimms.shirizu.core.components.effects.RowEntityType
|
||||||
@@ -58,8 +49,8 @@ import org.xtimms.shirizu.core.components.effects.animatedItemsIndexed
|
|||||||
import org.xtimms.shirizu.core.components.effects.updateAnimatedItemsState
|
import org.xtimms.shirizu.core.components.effects.updateAnimatedItemsState
|
||||||
import org.xtimms.shirizu.core.prefs.AppSettings
|
import org.xtimms.shirizu.core.prefs.AppSettings
|
||||||
import org.xtimms.shirizu.core.prefs.SWIPE_TUTORIAL
|
import org.xtimms.shirizu.core.prefs.SWIPE_TUTORIAL
|
||||||
import org.xtimms.shirizu.core.screens.EmptyScreen
|
import org.xtimms.shirizu.core.ui.screens.EmptyScreen
|
||||||
import org.xtimms.shirizu.core.screens.LoadingScreen
|
import org.xtimms.shirizu.core.ui.screens.LoadingScreen
|
||||||
import org.xtimms.shirizu.utils.lang.calculateTimeAgo
|
import org.xtimms.shirizu.utils.lang.calculateTimeAgo
|
||||||
import org.xtimms.shirizu.utils.lang.isSameDay
|
import org.xtimms.shirizu.utils.lang.isSameDay
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import org.xtimms.shirizu.R
|
import org.xtimms.shirizu.R
|
||||||
import org.xtimms.shirizu.core.components.BackIconButton
|
import org.xtimms.shirizu.core.components.BackIconButton
|
||||||
import org.xtimms.shirizu.core.screens.EmptyScreen
|
import org.xtimms.shirizu.core.ui.screens.EmptyScreen
|
||||||
import org.xtimms.shirizu.ui.theme.ShirizuTheme
|
import org.xtimms.shirizu.ui.theme.ShirizuTheme
|
||||||
|
|
||||||
const val SEARCH_DESTINATION = "search"
|
const val SEARCH_DESTINATION = "search"
|
||||||
|
|||||||
@@ -15,8 +15,11 @@ import androidx.compose.animation.fadeOut
|
|||||||
import androidx.compose.animation.shrinkVertically
|
import androidx.compose.animation.shrinkVertically
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||||
import androidx.compose.foundation.layout.asPaddingValues
|
import androidx.compose.foundation.layout.asPaddingValues
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.navigationBars
|
import androidx.compose.foundation.layout.navigationBars
|
||||||
|
import androidx.compose.foundation.layout.only
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
@@ -30,6 +33,9 @@ import androidx.compose.material.icons.outlined.Palette
|
|||||||
import androidx.compose.material.icons.outlined.SettingsBackupRestore
|
import androidx.compose.material.icons.outlined.SettingsBackupRestore
|
||||||
import androidx.compose.material.icons.outlined.Storage
|
import androidx.compose.material.icons.outlined.Storage
|
||||||
import androidx.compose.material.icons.outlined.Wifi
|
import androidx.compose.material.icons.outlined.Wifi
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@@ -37,18 +43,22 @@ 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.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import org.xtimms.shirizu.R
|
import org.xtimms.shirizu.R
|
||||||
|
import org.xtimms.shirizu.core.components.BackIconButton
|
||||||
import org.xtimms.shirizu.core.components.PreferencesHintCard
|
import org.xtimms.shirizu.core.components.PreferencesHintCard
|
||||||
import org.xtimms.shirizu.core.components.ScaffoldWithTopAppBar
|
|
||||||
import org.xtimms.shirizu.core.components.SettingItem
|
import org.xtimms.shirizu.core.components.SettingItem
|
||||||
|
import org.xtimms.shirizu.core.components.SettingTitle
|
||||||
|
import org.xtimms.shirizu.core.components.SmallTopAppBar
|
||||||
import org.xtimms.shirizu.utils.FileSize
|
import org.xtimms.shirizu.utils.FileSize
|
||||||
|
|
||||||
const val SETTINGS_DESTINATION = "settings"
|
const val SETTINGS_DESTINATION = "settings"
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@SuppressLint("BatteryLife")
|
@SuppressLint("BatteryLife")
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsView(
|
fun SettingsView(
|
||||||
@@ -76,6 +86,8 @@ fun SettingsView(
|
|||||||
mutableStateOf(!pm.isIgnoringBatteryOptimizations(context.packageName))
|
mutableStateOf(!pm.isIgnoringBatteryOptimizations(context.packageName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
|
||||||
|
|
||||||
val intent =
|
val intent =
|
||||||
Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
|
Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
|
||||||
data = Uri.parse("package:${context.packageName}")
|
data = Uri.parse("package:${context.packageName}")
|
||||||
@@ -96,9 +108,22 @@ fun SettingsView(
|
|||||||
showBatteryHint = !pm.isIgnoringBatteryOptimizations(context.packageName)
|
showBatteryHint = !pm.isIgnoringBatteryOptimizations(context.packageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
ScaffoldWithTopAppBar(
|
Scaffold(
|
||||||
title = stringResource(R.string.settings),
|
modifier = Modifier
|
||||||
navigateBack = navigateBack
|
.fillMaxSize()
|
||||||
|
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
|
topBar = {
|
||||||
|
SmallTopAppBar(
|
||||||
|
titleText = stringResource(id = R.string.settings),
|
||||||
|
navigationIcon = {
|
||||||
|
BackIconButton {
|
||||||
|
navigateBack()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scrollBehavior = scrollBehavior
|
||||||
|
)
|
||||||
|
},
|
||||||
|
contentWindowInsets = WindowInsets.navigationBars.only(WindowInsetsSides.Horizontal),
|
||||||
) { padding ->
|
) { padding ->
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.padding(padding),
|
modifier = Modifier.padding(padding),
|
||||||
@@ -106,6 +131,9 @@ fun SettingsView(
|
|||||||
bottom = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
|
bottom = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
item {
|
||||||
|
SettingTitle(text = stringResource(id = R.string.settings))
|
||||||
|
}
|
||||||
item {
|
item {
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = showBatteryHint && isActivityAvailable,
|
visible = showBatteryHint && isActivityAvailable,
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ import androidx.compose.material.icons.outlined.Check
|
|||||||
import androidx.compose.material.icons.outlined.ColorLens
|
import androidx.compose.material.icons.outlined.ColorLens
|
||||||
import androidx.compose.material.icons.outlined.DarkMode
|
import androidx.compose.material.icons.outlined.DarkMode
|
||||||
import androidx.compose.material.icons.outlined.Language
|
import androidx.compose.material.icons.outlined.Language
|
||||||
|
import androidx.compose.material.icons.outlined.Layers
|
||||||
import androidx.compose.material.icons.outlined.LightMode
|
import androidx.compose.material.icons.outlined.LightMode
|
||||||
import androidx.compose.material.icons.outlined.Timelapse
|
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@@ -72,7 +72,7 @@ import org.xtimms.shirizu.core.components.ScaffoldWithTopAppBar
|
|||||||
import org.xtimms.shirizu.core.prefs.AppSettings
|
import org.xtimms.shirizu.core.prefs.AppSettings
|
||||||
import org.xtimms.shirizu.core.prefs.DarkThemePreference.Companion.OFF
|
import org.xtimms.shirizu.core.prefs.DarkThemePreference.Companion.OFF
|
||||||
import org.xtimms.shirizu.core.prefs.DarkThemePreference.Companion.ON
|
import org.xtimms.shirizu.core.prefs.DarkThemePreference.Companion.ON
|
||||||
import org.xtimms.shirizu.core.prefs.READING_TIME
|
import org.xtimms.shirizu.core.prefs.MODERN_VIEW
|
||||||
import org.xtimms.shirizu.core.prefs.STYLE_MONOCHROME
|
import org.xtimms.shirizu.core.prefs.STYLE_MONOCHROME
|
||||||
import org.xtimms.shirizu.core.prefs.STYLE_TONAL_SPOT
|
import org.xtimms.shirizu.core.prefs.STYLE_TONAL_SPOT
|
||||||
import org.xtimms.shirizu.core.prefs.paletteStyles
|
import org.xtimms.shirizu.core.prefs.paletteStyles
|
||||||
@@ -85,7 +85,6 @@ import org.xtimms.shirizu.ui.monet.TonalPalettes.Companion.toTonalPalettes
|
|||||||
import org.xtimms.shirizu.ui.monet.a1
|
import org.xtimms.shirizu.ui.monet.a1
|
||||||
import org.xtimms.shirizu.ui.monet.a2
|
import org.xtimms.shirizu.ui.monet.a2
|
||||||
import org.xtimms.shirizu.ui.monet.a3
|
import org.xtimms.shirizu.ui.monet.a3
|
||||||
import org.xtimms.shirizu.utils.material.combineColors
|
|
||||||
import org.xtimms.shirizu.utils.system.toDisplayName
|
import org.xtimms.shirizu.utils.system.toDisplayName
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
@@ -101,6 +100,10 @@ fun AppearanceView(
|
|||||||
) {
|
) {
|
||||||
val localDensity = LocalDensity.current
|
val localDensity = LocalDensity.current
|
||||||
|
|
||||||
|
var isModernViewEnabled by remember {
|
||||||
|
mutableStateOf(AppSettings.isModernViewEnabled())
|
||||||
|
}
|
||||||
|
|
||||||
ScaffoldWithTopAppBar(
|
ScaffoldWithTopAppBar(
|
||||||
title = stringResource(R.string.appearance),
|
title = stringResource(R.string.appearance),
|
||||||
navigateBack = navigateBack
|
navigateBack = navigateBack
|
||||||
@@ -246,6 +249,15 @@ fun AppearanceView(
|
|||||||
icon = Icons.Outlined.Language,
|
icon = Icons.Outlined.Language,
|
||||||
description = Locale.getDefault().toDisplayName(),
|
description = Locale.getDefault().toDisplayName(),
|
||||||
onClick = { navigateToLanguages() })
|
onClick = { navigateToLanguages() })
|
||||||
|
PreferenceSubtitle(text = stringResource(id = R.string.user_interface))
|
||||||
|
PreferenceSwitch(
|
||||||
|
icon = Icons.Outlined.Layers,
|
||||||
|
title = stringResource(id = R.string.details_modern_look),
|
||||||
|
isChecked = isModernViewEnabled,
|
||||||
|
) {
|
||||||
|
isModernViewEnabled = !isModernViewEnabled
|
||||||
|
AppSettings.updateValue(MODERN_VIEW, isModernViewEnabled)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -286,8 +298,12 @@ fun RowScope.ColorButtonImpl(
|
|||||||
onClick: () -> Unit = {}
|
onClick: () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val containerSize by animateDpAsState(targetValue = if (isSelected.invoke()) 28.dp else 0.dp)
|
val containerSize by animateDpAsState(targetValue = if (isSelected.invoke()) 28.dp else 0.dp,
|
||||||
val iconSize by animateDpAsState(targetValue = if (isSelected.invoke()) 16.dp else 0.dp)
|
label = "containerSize"
|
||||||
|
)
|
||||||
|
val iconSize by animateDpAsState(targetValue = if (isSelected.invoke()) 16.dp else 0.dp,
|
||||||
|
label = "iconSize"
|
||||||
|
)
|
||||||
|
|
||||||
Surface(
|
Surface(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ import org.xtimms.shirizu.utils.MaskVisualTransformation
|
|||||||
import org.xtimms.shirizu.utils.NumberDefaults.INPUT_LENGTH
|
import org.xtimms.shirizu.utils.NumberDefaults.INPUT_LENGTH
|
||||||
import org.xtimms.shirizu.utils.NumberDefaults.MASK
|
import org.xtimms.shirizu.utils.NumberDefaults.MASK
|
||||||
import org.xtimms.shirizu.utils.NumberDefaults.MAX_PORT
|
import org.xtimms.shirizu.utils.NumberDefaults.MAX_PORT
|
||||||
|
import org.xtimms.shirizu.utils.lang.ifNullOrEmpty
|
||||||
import org.xtimms.shirizu.utils.lang.intState
|
import org.xtimms.shirizu.utils.lang.intState
|
||||||
import java.net.Proxy
|
import java.net.Proxy
|
||||||
|
|
||||||
@@ -175,14 +176,14 @@ fun NetworkView(
|
|||||||
PreferenceItem(
|
PreferenceItem(
|
||||||
enabled = proxy != Proxy.Type.DIRECT.ordinal,
|
enabled = proxy != Proxy.Type.DIRECT.ordinal,
|
||||||
title = stringResource(id = R.string.proxy_address),
|
title = stringResource(id = R.string.proxy_address),
|
||||||
description = address,
|
description = address.ifNullOrEmpty { stringResource(id = R.string.not_set) },
|
||||||
) { showProxyAddressDialog = true }
|
) { showProxyAddressDialog = true }
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
PreferenceItem(
|
PreferenceItem(
|
||||||
enabled = proxy != Proxy.Type.DIRECT.ordinal,
|
enabled = proxy != Proxy.Type.DIRECT.ordinal,
|
||||||
title = stringResource(id = R.string.proxy_port),
|
title = stringResource(id = R.string.proxy_port),
|
||||||
description = port.toString()
|
description = if (port == 0) stringResource(id = R.string.not_set) else port.toString()
|
||||||
) { showProxyPortDialog = true }
|
) { showProxyPortDialog = true }
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
@@ -192,14 +193,14 @@ fun NetworkView(
|
|||||||
PreferenceItem(
|
PreferenceItem(
|
||||||
enabled = proxy != Proxy.Type.DIRECT.ordinal,
|
enabled = proxy != Proxy.Type.DIRECT.ordinal,
|
||||||
title = stringResource(id = R.string.proxy_username),
|
title = stringResource(id = R.string.proxy_username),
|
||||||
description = username,
|
description = username.ifNullOrEmpty { stringResource(id = R.string.not_set) },
|
||||||
) { showProxyUsernameDialog = true }
|
) { showProxyUsernameDialog = true }
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
PreferenceItem(
|
PreferenceItem(
|
||||||
enabled = proxy != Proxy.Type.DIRECT.ordinal,
|
enabled = proxy != Proxy.Type.DIRECT.ordinal,
|
||||||
title = stringResource(id = R.string.proxy_password),
|
title = stringResource(id = R.string.proxy_password),
|
||||||
description = String(CharArray(password.length) { '\u2022' }),
|
description = String(CharArray(password.length) { '\u2022' }).ifNullOrEmpty { stringResource(id = R.string.not_set) },
|
||||||
) { showProxyPasswordDialog = true }
|
) { showProxyPasswordDialog = true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,50 +3,60 @@ package org.xtimms.shirizu.sections.settings.sources.catalog
|
|||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.outlined.Label
|
import androidx.compose.material.icons.automirrored.outlined.Label
|
||||||
|
import androidx.compose.material.icons.outlined.Add
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
import org.xtimms.shirizu.core.AsyncImageImpl
|
import org.xtimms.shirizu.core.AsyncImageImpl
|
||||||
import org.xtimms.shirizu.core.parser.favicon.faviconUri
|
import org.xtimms.shirizu.core.parser.favicon.faviconUri
|
||||||
|
import org.xtimms.shirizu.ui.theme.ShirizuTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SourceCatalogItem(
|
fun SourceCatalogItem(
|
||||||
coil: ImageLoader,
|
coil: ImageLoader,
|
||||||
source: MangaSource,
|
source: MangaSource,
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
Card(
|
Row(
|
||||||
modifier = modifier,
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(8.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
Row(
|
AsyncImageImpl(
|
||||||
|
modifier = Modifier.size(42.dp),
|
||||||
|
coil = coil,
|
||||||
|
contentDescription = null,
|
||||||
|
model = source.faviconUri()
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = source.title,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.padding(start = 16.dp)
|
||||||
.padding(
|
.weight(1f),
|
||||||
start = 16.dp,
|
)
|
||||||
top = 16.dp,
|
IconButton(onClick = { /*TODO*/ }) {
|
||||||
end = 16.dp,
|
Icon(imageVector = Icons.Outlined.Add, contentDescription = null)
|
||||||
),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
AsyncImageImpl(
|
|
||||||
coil = coil,
|
|
||||||
contentDescription = null,
|
|
||||||
model = source.faviconUri()
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = source.title,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(start = 16.dp),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun SourceCatalogItemPreview() {
|
||||||
|
ShirizuTheme {
|
||||||
|
SourceCatalogItem(coil = ImageLoader(LocalContext.current), source = MangaSource.MANGADEX)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.PaddingValues
|
|||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.grid.items
|
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.pager.HorizontalPager
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
import androidx.compose.foundation.pager.PagerState
|
import androidx.compose.foundation.pager.PagerState
|
||||||
@@ -17,14 +16,9 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Alignment
|
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 androidx.compose.ui.util.fastAny
|
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import org.xtimms.shirizu.R
|
import org.xtimms.shirizu.R
|
||||||
import org.xtimms.shirizu.core.components.MangaGridItem
|
import org.xtimms.shirizu.core.ui.screens.EmptyScreen
|
||||||
import org.xtimms.shirizu.core.screens.EmptyScreen
|
|
||||||
import org.xtimms.shirizu.sections.shelf.LazyShelfGrid
|
|
||||||
import org.xtimms.shirizu.sections.shelf.ShelfGrid
|
|
||||||
import org.xtimms.shirizu.sections.shelf.ShelfManga
|
|
||||||
import org.xtimms.shirizu.utils.system.plus
|
import org.xtimms.shirizu.utils.system.plus
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import org.xtimms.shirizu.R
|
import org.xtimms.shirizu.R
|
||||||
import org.xtimms.shirizu.core.prefs.AppSettings
|
import org.xtimms.shirizu.core.prefs.AppSettings
|
||||||
import org.xtimms.shirizu.core.screens.EmptyScreen
|
import org.xtimms.shirizu.core.ui.screens.EmptyScreen
|
||||||
import org.xtimms.shirizu.utils.system.plus
|
import org.xtimms.shirizu.utils.system.plus
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
@@ -306,4 +306,6 @@
|
|||||||
<string name="open_menu">Open menu</string>
|
<string name="open_menu">Open menu</string>
|
||||||
<string name="crash_screen_something_went_wrong">My bad…</string>
|
<string name="crash_screen_something_went_wrong">My bad…</string>
|
||||||
<string name="crash_screen_toast">Logs about this bug have been sent to the developers, thank you.</string>
|
<string name="crash_screen_toast">Logs about this bug have been sent to the developers, thank you.</string>
|
||||||
|
<string name="user_interface">User interface</string>
|
||||||
|
<string name="details_modern_look">Modern look of the manga information screen</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user