Skip to content

Commit

Permalink
improved manga support
Browse files Browse the repository at this point in the history
  • Loading branch information
DatL4g committed May 19, 2024
1 parent 9f340d3 commit b104331
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import dev.datlag.aniflow.anilist.type.MediaListStatus
import dev.datlag.aniflow.anilist.type.MediaStatus
import dev.datlag.aniflow.anilist.type.MediaType
import dev.datlag.aniflow.other.Series
import dev.datlag.aniflow.settings.model.AppSettings
import dev.datlag.aniflow.ui.navigation.Component
import dev.datlag.aniflow.ui.navigation.ContentHolderComponent
import dev.datlag.aniflow.ui.navigation.DialogComponent
import kotlinx.coroutines.flow.Flow
Expand All @@ -38,10 +36,9 @@ interface MediumComponent : ContentHolderComponent {
val genres: Flow<Set<String>>

val format: Flow<MediaFormat>
val episodes: Flow<Int>
val episodesOrChapters: Flow<Int>
val duration: Flow<Int>
val status: Flow<MediaStatus>
val chapters: Flow<Int>
val volumes: Flow<Int>

val rated: Flow<Medium.Ranking?>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ class MediumScreenComponent(
}

@OptIn(ExperimentalCoroutinesApi::class)
override val episodes: Flow<Int> = mediumSuccessState.mapLatest {
it.medium.episodes
override val episodesOrChapters: Flow<Int> = mediumSuccessState.mapLatest {
it.medium.episodesOrChapters
}.distinctUntilChanged()

@OptIn(ExperimentalCoroutinesApi::class)
Expand Down Expand Up @@ -186,11 +186,6 @@ class MediumScreenComponent(
initialValue = initialMedium.entry?.status ?: MediaListStatus.UNKNOWN__
)

@OptIn(ExperimentalCoroutinesApi::class)
override val chapters: Flow<Int> = mediumSuccessState.mapLatest {
it.medium.chapters
}

@OptIn(ExperimentalCoroutinesApi::class)
override val volumes: Flow<Int> = mediumSuccessState.mapLatest {
it.medium.volumes
Expand Down Expand Up @@ -256,13 +251,14 @@ class MediumScreenComponent(
is DialogConfig.Edit -> EditDialogComponent(
componentContext = context,
di = di,
episodes = episodes,
episodesOrChapters = episodesOrChapters,
progress = watchProgress,
listStatus = listStatus,
repeatCount = watchRepeat,
episodeStartDate = mediumSuccessState.mapLatest {
it.medium.startDate
},
type = type,
onDismiss = dialogNavigation::dismiss,
onSave = { status, progress, repeat ->
dialogNavigation.dismiss {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ package dev.datlag.aniflow.ui.navigation.screen.medium.component

import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.List
import androidx.compose.material.icons.automirrored.rounded.List
import androidx.compose.material.icons.filled.NoAdultContent
import androidx.compose.material.icons.filled.OndemandVideo
import androidx.compose.material.icons.filled.RssFeed
import androidx.compose.material.icons.filled.Timelapse
import androidx.compose.material.icons.rounded.*
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
Expand All @@ -22,17 +17,14 @@ import coil3.compose.AsyncImage
import coil3.compose.rememberAsyncImagePainter
import dev.datlag.aniflow.SharedRes
import dev.datlag.aniflow.anilist.model.Medium
import dev.datlag.aniflow.anilist.type.MediaFormat
import dev.datlag.aniflow.anilist.type.MediaStatus
import dev.datlag.aniflow.anilist.type.MediaType
import dev.datlag.aniflow.common.icon
import dev.datlag.aniflow.common.text
import dev.datlag.aniflow.ui.navigation.screen.medium.MediumComponent
import dev.datlag.tooling.compose.ifTrue
import dev.datlag.tooling.decompose.lifecycle.collectAsStateWithLifecycle
import dev.icerock.moko.resources.compose.pluralStringResource
import dev.icerock.moko.resources.compose.stringResource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow

@Composable
fun CoverSection(
Expand Down Expand Up @@ -84,11 +76,10 @@ fun CoverSection(
verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically)
) {
val format by component.format.collectAsStateWithLifecycle(component.initialMedium.format)
val episodes by component.episodes.collectAsStateWithLifecycle(component.initialMedium.episodes)
val episodes by component.episodesOrChapters.collectAsStateWithLifecycle(component.initialMedium.episodes)
val duration by component.duration.collectAsStateWithLifecycle(component.initialMedium.avgEpisodeDurationInMin)
val status by component.status.collectAsStateWithLifecycle(component.initialMedium.status)
val isAdult by component.isAdult.collectAsStateWithLifecycle(component.initialMedium.isAdult)
val chapters by component.chapters.collectAsStateWithLifecycle(component.initialMedium.chapters)
val volumes by component.volumes.collectAsStateWithLifecycle(component.initialMedium.volumes)

Row(
Expand Down Expand Up @@ -121,25 +112,19 @@ fun CoverSection(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
val type by component.type.collectAsStateWithLifecycle(MediaType.UNKNOWN__)
val (icon, stringRes) = remember(type) {
when (type) {
MediaType.MANGA -> Icons.Rounded.AutoStories to SharedRes.plurals.chapters
else -> Icons.AutoMirrored.Rounded.List to SharedRes.plurals.episodes
}
}

Icon(
imageVector = Icons.AutoMirrored.Rounded.List,
imageVector = icon,
contentDescription = null
)
Text(text = pluralStringResource(SharedRes.plurals.episodes, episodes, episodes))
}
} else {
if (chapters > -1) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
imageVector = Icons.Rounded.AutoStories,
contentDescription = null
)
Text(text = pluralStringResource(SharedRes.plurals.chapters, chapters, chapters))
}
Text(text = pluralStringResource(stringRes, episodes, episodes))
}
}
if (duration > -1) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package dev.datlag.aniflow.ui.navigation.screen.medium.dialog.edit

import dev.datlag.aniflow.anilist.type.MediaListStatus
import dev.datlag.aniflow.anilist.type.MediaType
import dev.datlag.aniflow.ui.navigation.DialogComponent
import kotlinx.coroutines.flow.Flow
import kotlinx.datetime.LocalDate

interface EditComponent : DialogComponent {
val episodes: Flow<Int>
val episodesOrChapters: Flow<Int>
val progress: Flow<Int?>
val listStatus: Flow<MediaListStatus>
val repeatCount: Flow<Int?>
val episodeStartDate: Flow<LocalDate?>
val type: Flow<MediaType>

fun save(editState: EditState)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,24 @@ package dev.datlag.aniflow.ui.navigation.screen.medium.dialog.edit

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
import com.maxkeppeler.sheets.calendar.CalendarDialog
import com.maxkeppeler.sheets.calendar.models.CalendarConfig
import com.maxkeppeler.sheets.calendar.models.CalendarSelection
import dev.datlag.aniflow.LocalEdgeToEdge
import dev.datlag.aniflow.SharedRes
import dev.datlag.aniflow.anilist.type.MediaListStatus
import dev.datlag.aniflow.anilist.type.MediaType
import dev.datlag.aniflow.common.icon
import dev.datlag.aniflow.common.merge
import dev.datlag.aniflow.ui.navigation.screen.medium.dialog.edit.component.TopSection
import dev.datlag.tooling.decompose.lifecycle.collectAsStateWithLifecycle
import dev.icerock.moko.resources.compose.stringResource
import io.github.aakira.napier.Napier
import kotlinx.datetime.*
import kotlin.math.max
import kotlin.math.min

@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Composable
Expand All @@ -51,12 +42,13 @@ fun EditDialog(component: EditComponent) {
sheetState = sheetState
) {
val editState = rememberEditState(
mediumEpisodes = component.episodes,
mediumEpisodes = component.episodesOrChapters,
progress = component.progress,
repeat = component.repeatCount,
listStatus = component.listStatus,
)
val currentListStatus by editState.listStatus.collectAsStateWithLifecycle()
val type by component.type.collectAsStateWithLifecycle(MediaType.UNKNOWN__)

LazyColumn(
modifier = Modifier.fillMaxWidth(),
Expand All @@ -83,7 +75,13 @@ fun EditDialog(component: EditComponent) {
item {
Text(
modifier = Modifier.fillParentMaxWidth().padding(top = 32.dp),
text = "Watched Episode",
text = stringResource(
if (type == MediaType.MANGA) {
SharedRes.strings.read_chapter
} else {
SharedRes.strings.watched_episode
}
),
textAlign = TextAlign.Center,
fontWeight = FontWeight.Medium
)
Expand Down Expand Up @@ -115,49 +113,57 @@ fun EditDialog(component: EditComponent) {
}
}
}
item {
val currentEpisode by editState.episode.collectAsStateWithLifecycle()
if (editState.hasEpisodes) {
item {
val currentEpisode by editState.episode.collectAsStateWithLifecycle()

Row(
modifier = Modifier.fillParentMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Button(
onClick = {
editState.minusEpisode()
},
enabled = editState.canRemoveEpisode
) {
Text(text = stringResource(SharedRes.strings.minus_one))
}
OutlinedTextField(
modifier = Modifier.weight(1F),
value = if (currentEpisode <= 0) "" else currentEpisode.toString(),
onValueChange = {
editState.setEpisode(it.toIntOrNull())
},
placeholder = {
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(SharedRes.strings.episode),
textAlign = TextAlign.Center,
style = LocalTextStyle.current.copy(textAlign = TextAlign.Center)
)
},
singleLine = true,
maxLines = 1,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
shape = MaterialTheme.shapes.medium
)
Button(
onClick = {
editState.plusEpisode()
},
enabled = editState.canAddEpisode
Row(
modifier = Modifier.fillParentMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(text = stringResource(SharedRes.strings.plus_one))
Button(
onClick = {
editState.minusEpisode()
},
enabled = editState.canRemoveEpisode
) {
Text(text = stringResource(SharedRes.strings.minus_one))
}
OutlinedTextField(
modifier = Modifier.weight(1F),
value = if (currentEpisode <= 0) "" else currentEpisode.toString(),
onValueChange = {
editState.setEpisode(it.toIntOrNull())
},
placeholder = {
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(
if (type == MediaType.MANGA) {
SharedRes.strings.chapter
} else {
SharedRes.strings.episode
}
),
textAlign = TextAlign.Center,
style = LocalTextStyle.current.copy(textAlign = TextAlign.Center)
)
},
singleLine = true,
maxLines = 1,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
shape = MaterialTheme.shapes.medium
)
Button(
onClick = {
editState.plusEpisode()
},
enabled = editState.canAddEpisode
) {
Text(text = stringResource(SharedRes.strings.plus_one))
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.apollographql.apollo3.ApolloClient
import com.arkivanov.decompose.ComponentContext
import dev.datlag.aniflow.anilist.model.Medium
import dev.datlag.aniflow.anilist.type.MediaListStatus
import dev.datlag.aniflow.anilist.type.MediaType
import dev.datlag.aniflow.common.onRender
import dev.datlag.aniflow.other.BurningSeriesResolver
import dev.datlag.aniflow.other.Constants
Expand All @@ -21,11 +22,12 @@ import org.kodein.di.instance
class EditDialogComponent(
componentContext: ComponentContext,
override val di: DI,
override val episodes: Flow<Int>,
override val episodesOrChapters: Flow<Int>,
override val progress: Flow<Int?>,
override val listStatus: Flow<MediaListStatus>,
override val repeatCount: Flow<Int?>,
override val episodeStartDate: Flow<LocalDate?>,
override val type: Flow<MediaType>,
private val onDismiss: () -> Unit,
private val onSave: (MediaListStatus, Int, Int) -> Unit
) : EditComponent, ComponentContext by componentContext {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class EditState(
val canAddEpisode: Boolean
get() = episodeState.canAdd

val hasEpisodes: Boolean
get() = episodeState.hasEpisodes

val canRemoveRepeat: Boolean
get() = repeatState.canRemove

Expand Down Expand Up @@ -146,6 +149,9 @@ class EditState(
internal val canAdd: Boolean
get() = currentEpisode.value < maxEpisodes

internal val hasEpisodes: Boolean
get() = maxEpisodes > 0

internal fun plus(
value: Int = 1,
onNotComplete: (Boolean) -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fun TopSection(
}
Text(
modifier = Modifier.weight(1F),
text = "Edit",
text = stringResource(SharedRes.strings.edit),
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
Expand Down
3 changes: 3 additions & 0 deletions composeApp/src/commonMain/moko-resources/base/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,7 @@
<string name="repeat">Repeat</string>
<string name="open_source_licenses">Open-Source Licenses</string>
<string name="open_source_licenses_text">This is a list of (all) libraries used in this project and it\'s licenses</string>
<string name="chapter">Chapter</string>
<string name="watched_episode">Watched Episode</string>
<string name="read_chapter">Read Chapter</string>
</resources>
3 changes: 3 additions & 0 deletions composeApp/src/commonMain/moko-resources/de-DE/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,7 @@
<string name="repeat">Wiederholung</string>
<string name="open_source_licenses">Open-Source Lizenzen</string>
<string name="open_source_licenses_text">Das ist eine Liste von (allen) Bibliotheken, die in diesem Projekt verwendet werden und deren Lizenzen</string>
<string name="chapter">Kapitel</string>
<string name="watched_episode">Gesehene Folge</string>
<string name="read_chapter">Gelesenes Kapitel</string>
</resources>

0 comments on commit b104331

Please sign in to comment.