Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Manga Notes #428

Open
wants to merge 34 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
2f7db31
Initial markdown render test
imkunet Feb 18, 2024
cd6432a
Add the text editor
imkunet Feb 18, 2024
9cfb52e
Polishing off note editor
imkunet Feb 19, 2024
d374a52
Added tablet notes
imkunet Feb 19, 2024
d2aca57
Make the edit notes button edit directly
imkunet Feb 19, 2024
4d31f83
Added fade transition between states
imkunet Feb 19, 2024
6dede4f
Make cursor jump to end by default
imkunet Feb 19, 2024
80b45ec
Fixed padding
imkunet Feb 19, 2024
378ad99
Impose note editor length limit
imkunet Feb 20, 2024
4a8566f
Fixes to pass relevant testing
imkunet Mar 5, 2024
37e662d
Add migration to add notes to manga
imkunet Sep 19, 2024
2834aa8
Make spotless
imkunet Sep 19, 2024
d5d9fcc
Design revision
imkunet Sep 19, 2024
45e06ee
Design revision 2
imkunet Sep 19, 2024
0c87a7c
Spotless
imkunet Sep 19, 2024
eb030bf
Abandon markdown for rich text
imkunet Sep 20, 2024
4834887
Rename composable from example name
imkunet Sep 20, 2024
70cd477
Reduce char limit, switch encoding
imkunet Sep 20, 2024
b6983fb
Bump richeditor and fix character count
imkunet Jan 19, 2025
2df33f1
Edit strings
imkunet Jan 19, 2025
df646ae
Resolve strange initialization pattern
imkunet Jan 27, 2025
7ce1bf7
Removed note nullity, tidied up model
imkunet Jan 27, 2025
dbc10a0
Changed strings to review recommendation
imkunet Jan 27, 2025
55d4016
Removed unnecessary code modification
imkunet Jan 27, 2025
062adac
Animate out all bumps caused by updating
imkunet Jan 27, 2025
97b4092
Fix characters remaining indicator
imkunet Jan 27, 2025
31042c7
Update domain/src/main/java/tachiyomi/domain/manga/interactor/SetMang…
imkunet Jan 30, 2025
9586543
Update app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt
imkunet Jan 30, 2025
df0dd5c
Spotless
imkunet Jan 30, 2025
32b639f
Fix awaitSetNotes parameter
imkunet Jan 30, 2025
8f0b459
Put state and model into the screen
imkunet Jan 30, 2025
af1d5ba
Update app/src/main/java/eu/kanade/tachiyomi/ui/manga/notes/MangaNote…
imkunet Jan 30, 2025
468b9ce
Update app/src/main/java/eu/kanade/tachiyomi/ui/manga/notes/MangaNote…
imkunet Jan 30, 2025
5c36cd3
Cleanup MangaNotesDisplay
imkunet Jan 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ dependencies {
}
implementation(libs.insetter)
implementation(libs.bundles.richtext)
implementation(libs.richeditor.compose)
implementation(libs.aboutLibraries.compose)
implementation(libs.bundles.voyager)
implementation(libs.compose.materialmotion)
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/eu/kanade/domain/DomainModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import tachiyomi.domain.manga.interactor.GetMangaWithChapters
import tachiyomi.domain.manga.interactor.NetworkToLocalManga
import tachiyomi.domain.manga.interactor.ResetViewerFlags
import tachiyomi.domain.manga.interactor.SetMangaChapterFlags
import tachiyomi.domain.manga.interactor.SetMangaNotes
import tachiyomi.domain.manga.repository.MangaRepository
import tachiyomi.domain.release.interactor.GetApplicationRelease
import tachiyomi.domain.release.service.ReleaseService
Expand Down Expand Up @@ -124,6 +125,7 @@ class DomainModule : InjektModule {
addFactory { GetUpcomingManga(get()) }
addFactory { ResetViewerFlags(get()) }
addFactory { SetMangaChapterFlags(get()) }
addFactory { SetMangaNotes(get()) }
addFactory { FetchInterval(get()) }
addFactory { SetMangaDefaultChapterFlags(get(), get(), get()) }
addFactory { SetMangaViewerFlags(get()) }
Expand Down
57 changes: 57 additions & 0 deletions app/src/main/java/eu/kanade/presentation/manga/MangaNotesScreen.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package eu.kanade.presentation.manga

import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarTitle
import eu.kanade.presentation.manga.components.MangaNotesTextArea
import eu.kanade.tachiyomi.ui.manga.notes.MangaNotesScreen
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource

@Composable
fun MangaNotesScreen(
state: MangaNotesScreen.State,
navigateUp: () -> Unit,
onSave: (String) -> Unit,
modifier: Modifier = Modifier,
) {
Scaffold(
topBar = { scrollBehavior ->
AppBar(
titleContent = {
AppBarTitle(title = stringResource(MR.strings.action_notes), subtitle = state.manga.title)
},
navigateUp = navigateUp,
scrollBehavior = scrollBehavior,
)
},
modifier = modifier
.imePadding(),
) { paddingValues ->
MangaNotesTextArea(
state = state,
onSave = onSave,
modifier = Modifier
.padding(
top = paddingValues.calculateTopPadding() + MaterialTheme.padding.small,
bottom = MaterialTheme.padding.small,
)
.padding(horizontal = MaterialTheme.padding.small)
.windowInsetsPadding(
WindowInsets.navigationBars
.only(WindowInsetsSides.Bottom),
),
)
}
}
11 changes: 11 additions & 0 deletions app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ fun MangaScreen(
onEditCategoryClicked: (() -> Unit)?,
onEditFetchIntervalClicked: (() -> Unit)?,
onMigrateClicked: (() -> Unit)?,
onNotesClicked: () -> Unit,

// For bottom action menu
onMultiBookmarkClicked: (List<Chapter>, bookmarked: Boolean) -> Unit,
Expand Down Expand Up @@ -160,6 +161,7 @@ fun MangaScreen(
onEditCategoryClicked = onEditCategoryClicked,
onEditIntervalClicked = onEditFetchIntervalClicked,
onMigrateClicked = onMigrateClicked,
onNotesClicked = onNotesClicked,
onMultiBookmarkClicked = onMultiBookmarkClicked,
onMultiMarkAsReadClicked = onMultiMarkAsReadClicked,
onMarkPreviousAsReadClicked = onMarkPreviousAsReadClicked,
Expand Down Expand Up @@ -195,6 +197,7 @@ fun MangaScreen(
onEditCategoryClicked = onEditCategoryClicked,
onEditIntervalClicked = onEditFetchIntervalClicked,
onMigrateClicked = onMigrateClicked,
onNotesClicked = onNotesClicked,
onMultiBookmarkClicked = onMultiBookmarkClicked,
onMultiMarkAsReadClicked = onMultiMarkAsReadClicked,
onMarkPreviousAsReadClicked = onMarkPreviousAsReadClicked,
Expand Down Expand Up @@ -240,6 +243,7 @@ private fun MangaScreenSmallImpl(
onEditCategoryClicked: (() -> Unit)?,
onEditIntervalClicked: (() -> Unit)?,
onMigrateClicked: (() -> Unit)?,
onNotesClicked: () -> Unit,

// For bottom action menu
onMultiBookmarkClicked: (List<Chapter>, bookmarked: Boolean) -> Unit,
Expand Down Expand Up @@ -305,6 +309,7 @@ private fun MangaScreenSmallImpl(
onClickEditCategory = onEditCategoryClicked,
onClickRefresh = onRefresh,
onClickMigrate = onMigrateClicked,
onClickNotes = onNotesClicked,
actionModeCounter = selectedChapterCount,
onSelectAll = { onAllChapterSelected(true) },
onInvertSelection = { onInvertSelection() },
Expand Down Expand Up @@ -414,8 +419,10 @@ private fun MangaScreenSmallImpl(
defaultExpandState = state.isFromSource,
description = state.manga.description,
tagsProvider = { state.manga.genre },
noteContent = state.manga.notes,
onTagSearch = onTagSearch,
onCopyTagToClipboard = onCopyTagToClipboard,
onClickNotes = onNotesClicked,
)
}

Expand Down Expand Up @@ -484,6 +491,7 @@ fun MangaScreenLargeImpl(
onEditCategoryClicked: (() -> Unit)?,
onEditIntervalClicked: (() -> Unit)?,
onMigrateClicked: (() -> Unit)?,
onNotesClicked: () -> Unit,

// For bottom action menu
onMultiBookmarkClicked: (List<Chapter>, bookmarked: Boolean) -> Unit,
Expand Down Expand Up @@ -542,6 +550,7 @@ fun MangaScreenLargeImpl(
onClickEditCategory = onEditCategoryClicked,
onClickRefresh = onRefresh,
onClickMigrate = onMigrateClicked,
onClickNotes = onNotesClicked,
actionModeCounter = selectedChapterCount,
onSelectAll = { onAllChapterSelected(true) },
onInvertSelection = { onInvertSelection() },
Expand Down Expand Up @@ -640,8 +649,10 @@ fun MangaScreenLargeImpl(
defaultExpandState = true,
description = state.manga.description,
tagsProvider = { state.manga.genre },
noteContent = state.manga.notes,
onTagSearch = onTagSearch,
onCopyTagToClipboard = onCopyTagToClipboard,
onClickNotes = onNotesClicked,
)
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,10 @@ fun ExpandableMangaDescription(
defaultExpandState: Boolean,
description: String?,
tagsProvider: () -> List<String>?,
noteContent: String,
onTagSearch: (String) -> Unit,
onCopyTagToClipboard: (tag: String) -> Unit,
onClickNotes: () -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
Expand All @@ -255,6 +257,8 @@ fun ExpandableMangaDescription(
expandedDescription = desc,
shrunkDescription = trimmedDescription,
expanded = expanded,
noteContent = noteContent,
onNotesEditClicked = onClickNotes,
modifier = Modifier
.padding(top = 8.dp)
.padding(horizontal = 16.dp)
Expand Down Expand Up @@ -559,7 +563,9 @@ private fun ColumnScope.MangaContentInfo(
private fun MangaSummary(
expandedDescription: String,
shrunkDescription: String,
noteContent: String,
expanded: Boolean,
onNotesEditClicked: () -> Unit,
modifier: Modifier = Modifier,
) {
val animProgress by animateFloatAsState(
Expand All @@ -571,27 +577,43 @@ private fun MangaSummary(
contents = listOf(
{
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.isBlank()) "\n\n" else "\n\n\n\n\n",
style = MaterialTheme.typography.bodyMedium,
)
},
{
Text(
text = expandedDescription,
style = MaterialTheme.typography.bodyMedium,
)
},
{
SelectionContainer {
Column {
MangaNotesSection(
content = noteContent,
expanded = true,
onClickNotes = onNotesEditClicked,
)
Text(
text = if (expanded) expandedDescription else shrunkDescription,
maxLines = Int.MAX_VALUE,
text = expandedDescription,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.secondaryItemAlpha(),
)
}
},
{
Column {
MangaNotesSection(
content = noteContent,
expanded = expanded,
onClickNotes = onNotesEditClicked,
)
SelectionContainer {
Text(
text = if (expanded) expandedDescription else shrunkDescription,
maxLines = Int.MAX_VALUE,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.secondaryItemAlpha(),
)
}
}
},
{
val colors = listOf(Color.Transparent, MaterialTheme.colorScheme.background)
Box(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package eu.kanade.presentation.manga.components

import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.tween
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import com.mohamedrejeb.richeditor.model.rememberRichTextState
import com.mohamedrejeb.richeditor.ui.material3.RichText

private val FADE_TIME = tween<Float>(500)

@Composable
fun MangaNotesDisplay(
content: String,
modifier: Modifier,
) {
val alpha = remember { Animatable(1f) }
var contentUpdatedOnce by remember { mutableStateOf(false) }

val richTextState = rememberRichTextState()
val primaryColor = MaterialTheme.colorScheme.primary
LaunchedEffect(content) {
richTextState.setMarkdown(markdown = content)

if (!contentUpdatedOnce) {
contentUpdatedOnce = true
return@LaunchedEffect
}

alpha.snapTo(targetValue = 0f)
alpha.animateTo(targetValue = 1f, animationSpec = FADE_TIME)
}
LaunchedEffect(Unit) {
richTextState.config.listIndent = 10
}
LaunchedEffect(primaryColor) {
richTextState.config.linkColor = primaryColor
}

SelectionContainer {
RichText(
modifier = modifier
// Only animate size if the notes changes
.then(if (contentUpdatedOnce) Modifier.animateContentSize() else Modifier)
.alpha(alpha.value),
style = MaterialTheme.typography.bodyMedium,
state = richTextState,
)
}
}
Loading