Design revision

see the Discord for more details
This commit is contained in:
imkunet 2024-09-19 06:16:22 -04:00
parent 0e0a9aac5b
commit 170c000d65
No known key found for this signature in database
GPG Key ID: 32E0ECFB90A68C42
5 changed files with 176 additions and 108 deletions

View File

@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Check
@ -123,6 +124,7 @@ fun MangaNotesScreen(
enter = fadeIn(), enter = fadeIn(),
exit = fadeOut(), exit = fadeOut(),
) { ) {
SelectionContainer {
RichText( RichText(
modifier = Modifier modifier = Modifier
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
@ -141,4 +143,5 @@ fun MangaNotesScreen(
} }
} }
} }
}
} }

View File

@ -5,6 +5,7 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
@ -25,6 +26,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.PlayArrow import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHost
@ -44,6 +46,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastAll import androidx.compose.ui.util.fastAll
import androidx.compose.ui.util.fastAny import androidx.compose.ui.util.fastAny
import androidx.compose.ui.util.fastMap import androidx.compose.ui.util.fastMap
@ -55,7 +58,6 @@ import eu.kanade.presentation.manga.components.MangaActionRow
import eu.kanade.presentation.manga.components.MangaBottomActionMenu import eu.kanade.presentation.manga.components.MangaBottomActionMenu
import eu.kanade.presentation.manga.components.MangaChapterListItem import eu.kanade.presentation.manga.components.MangaChapterListItem
import eu.kanade.presentation.manga.components.MangaInfoBox import eu.kanade.presentation.manga.components.MangaInfoBox
import eu.kanade.presentation.manga.components.MangaNotesSection
import eu.kanade.presentation.manga.components.MangaToolbar import eu.kanade.presentation.manga.components.MangaToolbar
import eu.kanade.presentation.manga.components.MissingChapterCountListItem import eu.kanade.presentation.manga.components.MissingChapterCountListItem
import eu.kanade.presentation.util.formatChapterNumber import eu.kanade.presentation.util.formatChapterNumber
@ -336,6 +338,23 @@ private fun MangaScreenSmallImpl(
}, },
snackbarHost = { SnackbarHost(hostState = snackbarHostState) }, snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
floatingActionButton = { floatingActionButton = {
Column(
horizontalAlignment = Alignment.End,
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
AnimatedVisibility(
visible = !isAnySelected,
enter = fadeIn(),
exit = fadeOut(),
) {
ExtendedFloatingActionButton(
text = { Text(stringResource(MR.strings.action_notes)) },
icon = { Icon(imageVector = Icons.Filled.Edit, contentDescription = null) },
onClick = onNotesEditClicked,
expanded = chapterListState.shouldExpandFAB(),
)
}
val isFABVisible = remember(chapters) { val isFABVisible = remember(chapters) {
chapters.fastAny { !it.chapter.read } && !isAnySelected chapters.fastAny { !it.chapter.read } && !isAnySelected
} }
@ -350,7 +369,9 @@ private fun MangaScreenSmallImpl(
state.chapters.fastAny { it.chapter.read } state.chapters.fastAny { it.chapter.read }
} }
Text( Text(
text = stringResource(if (isReading) MR.strings.action_resume else MR.strings.action_start), text = stringResource(
if (isReading) MR.strings.action_resume else MR.strings.action_start,
),
) )
}, },
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) }, icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
@ -358,6 +379,7 @@ private fun MangaScreenSmallImpl(
expanded = chapterListState.shouldExpandFAB(), expanded = chapterListState.shouldExpandFAB(),
) )
} }
}
}, },
) { contentPadding -> ) { contentPadding ->
val topPadding = contentPadding.calculateTopPadding() val topPadding = contentPadding.calculateTopPadding()
@ -424,18 +446,10 @@ private fun MangaScreenSmallImpl(
defaultExpandState = state.isFromSource, defaultExpandState = state.isFromSource,
description = state.manga.description, description = state.manga.description,
tagsProvider = { state.manga.genre }, tagsProvider = { state.manga.genre },
noteContent = state.manga.notes,
onTagSearch = onTagSearch, onTagSearch = onTagSearch,
onCopyTagToClipboard = onCopyTagToClipboard, onCopyTagToClipboard = onCopyTagToClipboard,
)
}
item(
key = MangaScreenItem.NOTES_SECTION,
contentType = MangaScreenItem.NOTES_SECTION,
) {
MangaNotesSection(
onClickNotes = onNotesEditClicked, onClickNotes = onNotesEditClicked,
content = state.manga.notes,
) )
} }
@ -599,6 +613,23 @@ fun MangaScreenLargeImpl(
enter = fadeIn(), enter = fadeIn(),
exit = fadeOut(), exit = fadeOut(),
) { ) {
Column(
horizontalAlignment = Alignment.End,
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
AnimatedVisibility(
visible = !isAnySelected,
enter = fadeIn(),
exit = fadeOut(),
) {
ExtendedFloatingActionButton(
text = { Text(stringResource(MR.strings.action_notes)) },
icon = { Icon(imageVector = Icons.Filled.Edit, contentDescription = null) },
onClick = onNotesEditClicked,
expanded = chapterListState.shouldExpandFAB(),
)
}
ExtendedFloatingActionButton( ExtendedFloatingActionButton(
text = { text = {
val isReading = remember(state.chapters) { val isReading = remember(state.chapters) {
@ -615,6 +646,7 @@ fun MangaScreenLargeImpl(
expanded = chapterListState.shouldExpandFAB(), expanded = chapterListState.shouldExpandFAB(),
) )
} }
}
}, },
) { contentPadding -> ) { contentPadding ->
PullRefresh( PullRefresh(
@ -663,12 +695,10 @@ fun MangaScreenLargeImpl(
defaultExpandState = true, defaultExpandState = true,
description = state.manga.description, description = state.manga.description,
tagsProvider = { state.manga.genre }, tagsProvider = { state.manga.genre },
noteContent = state.manga.notes,
onTagSearch = onTagSearch, onTagSearch = onTagSearch,
onCopyTagToClipboard = onCopyTagToClipboard, onCopyTagToClipboard = onCopyTagToClipboard,
)
MangaNotesSection(
onClickNotes = onNotesEditClicked, onClickNotes = onNotesEditClicked,
content = state.manga.notes,
) )
} }
}, },
@ -788,6 +818,7 @@ private fun LazyListScope.sharedChapterItems(
is ChapterList.MissingCount -> { is ChapterList.MissingCount -> {
MissingChapterCountListItem(count = item.count) MissingChapterCountListItem(count = item.count)
} }
is ChapterList.Item -> { is ChapterList.Item -> {
MangaChapterListItem( MangaChapterListItem(
title = if (manga.displayMode == Manga.CHAPTER_DISPLAY_NUMBER) { title = if (manga.displayMode == Manga.CHAPTER_DISPLAY_NUMBER) {

View File

@ -17,7 +17,6 @@ enum class MangaScreenItem {
INFO_BOX, INFO_BOX,
ACTION_ROW, ACTION_ROW,
DESCRIPTION_WITH_TAG, DESCRIPTION_WITH_TAG,
NOTES_SECTION,
CHAPTER_HEADER, CHAPTER_HEADER,
CHAPTER, CHAPTER,
} }

View File

@ -236,8 +236,10 @@ fun ExpandableMangaDescription(
defaultExpandState: Boolean, defaultExpandState: Boolean,
description: String?, description: String?,
tagsProvider: () -> List<String>?, tagsProvider: () -> List<String>?,
noteContent: String?,
onTagSearch: (String) -> Unit, onTagSearch: (String) -> Unit,
onCopyTagToClipboard: (tag: String) -> Unit, onCopyTagToClipboard: (tag: String) -> Unit,
onClickNotes: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column(modifier = modifier) { Column(modifier = modifier) {
@ -255,6 +257,8 @@ fun ExpandableMangaDescription(
expandedDescription = desc, expandedDescription = desc,
shrunkDescription = trimmedDescription, shrunkDescription = trimmedDescription,
expanded = expanded, expanded = expanded,
noteContent = noteContent,
onNotesEditClicked = onClickNotes,
modifier = Modifier modifier = Modifier
.padding(top = 8.dp) .padding(top = 8.dp)
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)
@ -559,7 +563,9 @@ private fun ColumnScope.MangaContentInfo(
private fun MangaSummary( private fun MangaSummary(
expandedDescription: String, expandedDescription: String,
shrunkDescription: String, shrunkDescription: String,
noteContent: String?,
expanded: Boolean, expanded: Boolean,
onNotesEditClicked: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val animProgress by animateFloatAsState( val animProgress by animateFloatAsState(
@ -571,18 +577,33 @@ private fun MangaSummary(
contents = listOf( contents = listOf(
{ {
Text( Text(
text = "\n\n", // Shows at least 3 lines // Shows at least 3 lines if no notes
// when there are notes show 6
text = if (noteContent.isNullOrBlank()) "\n\n" else "\n\n\n\n\n",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
) )
}, },
{ {
Column {
MangaNotesSection(
content = noteContent,
expanded = true,
onClickNotes = onNotesEditClicked,
)
Text( Text(
text = expandedDescription, text = expandedDescription,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
) )
}
}, },
{ {
SelectionContainer { SelectionContainer {
Column {
MangaNotesSection(
content = noteContent,
expanded = expanded,
onClickNotes = onNotesEditClicked,
)
Text( Text(
text = if (expanded) expandedDescription else shrunkDescription, text = if (expanded) expandedDescription else shrunkDescription,
maxLines = Int.MAX_VALUE, maxLines = Int.MAX_VALUE,
@ -591,6 +612,7 @@ private fun MangaSummary(
modifier = Modifier.secondaryItemAlpha(), modifier = Modifier.secondaryItemAlpha(),
) )
} }
}
}, },
{ {
val colors = listOf(Color.Transparent, MaterialTheme.colorScheme.background) val colors = listOf(Color.Transparent, MaterialTheme.colorScheme.background)

View File

@ -1,5 +1,7 @@
package eu.kanade.presentation.manga.components package eu.kanade.presentation.manga.components
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.spring
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@ -9,6 +11,7 @@ import androidx.compose.foundation.layout.size
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.outlined.Edit import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -31,8 +34,9 @@ import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun MangaNotesSection( fun MangaNotesSection(
onClickNotes: () -> Unit,
content: String?, content: String?,
expanded: Boolean,
onClickNotes: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column(modifier.fillMaxWidth()) { Column(modifier.fillMaxWidth()) {
@ -42,20 +46,14 @@ fun MangaNotesSection(
.fillMaxWidth(), .fillMaxWidth(),
) { ) {
if (!content.isNullOrBlank()) { if (!content.isNullOrBlank()) {
RichText( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .animateContentSize(
.padding(MaterialTheme.padding.medium), animationSpec = spring(),
style = RichTextStyle( alignment = Alignment.Center,
stringStyle = RichTextStringStyle(
linkStyle = SpanStyle(color = MaterialTheme.colorScheme.primary),
),
), ),
) { ) {
Markdown(content = content) if (expanded) {
}
}
Button( Button(
onClick = onClickNotes, onClick = onClickNotes,
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
@ -77,18 +75,32 @@ fun MangaNotesSection(
.size(16.dp), .size(16.dp),
) )
Text( Text(
stringResource( stringResource(MR.strings.action_edit_notes),
if (content.isNullOrBlank()) {
MR.strings.action_add_notes
} else {
MR.strings.action_edit_notes
},
),
) )
} }
} }
} }
} }
RichText(
modifier = Modifier
.fillMaxWidth(),
style = RichTextStyle(
stringStyle = RichTextStringStyle(
linkStyle = SpanStyle(color = MaterialTheme.colorScheme.primary),
),
),
) {
Markdown(content = content)
}
HorizontalDivider(
modifier = Modifier
.padding(vertical = 16.dp),
)
}
}
}
} }
@PreviewLightDark @PreviewLightDark
@ -96,6 +108,7 @@ fun MangaNotesSection(
private fun MangaNotesSectionPreview() { private fun MangaNotesSectionPreview() {
MangaNotesSection( MangaNotesSection(
onClickNotes = {}, onClickNotes = {},
expanded = true,
content = "# Hello world\ntest1234 hi there!", content = "# Hello world\ntest1234 hi there!",
) )
} }