[dev QoL] Added AndroidStudio previews for [presentation.track] namespace (#10022)
* Created DummyTracker for use in tests and presentation previews * Added previews for TrackerSearch * Added previews for TrackLogoIcon * Added preview for TrackInfoDialogSelector * Added previews for TrackInfoDialogHome
This commit is contained in:
parent
dcc3141080
commit
6d1e520c6c
8 changed files with 367 additions and 0 deletions
|
@ -44,14 +44,17 @@ import androidx.compose.ui.platform.LocalContext
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.domain.track.model.toDbTrack
|
||||
import eu.kanade.presentation.components.DropdownMenu
|
||||
import eu.kanade.presentation.theme.TachiyomiTheme
|
||||
import eu.kanade.presentation.track.components.TrackLogoIcon
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.track.Tracker
|
||||
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import tachiyomi.presentation.core.util.ThemePreviews
|
||||
import java.text.DateFormat
|
||||
|
||||
private const val UnsetStatusTextAlpha = 0.5F
|
||||
|
@ -168,6 +171,7 @@ private fun TrackInfoItem(
|
|||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
)
|
||||
}
|
||||
VerticalDivider()
|
||||
|
@ -254,6 +258,7 @@ private fun TrackDetailsItem(
|
|||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -312,3 +317,12 @@ private fun TrackInfoItemMenu(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun TrackInfoDialogHomePreviews(
|
||||
@PreviewParameter(TrackInfoDialogHomePreviewProvider::class)
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
TachiyomiTheme { content() }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package eu.kanade.presentation.track
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import eu.kanade.tachiyomi.dev.preview.DummyTracker
|
||||
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
||||
import tachiyomi.domain.track.model.Track
|
||||
import java.text.DateFormat
|
||||
|
||||
internal class TrackInfoDialogHomePreviewProvider :
|
||||
PreviewParameterProvider<@Composable () -> Unit> {
|
||||
|
||||
private val aTrack = Track(
|
||||
id = 1L,
|
||||
mangaId = 2L,
|
||||
syncId = 3L,
|
||||
remoteId = 4L,
|
||||
libraryId = null,
|
||||
title = "Manage Name On Tracker Site",
|
||||
lastChapterRead = 2.0,
|
||||
totalChapters = 12L,
|
||||
status = 1L,
|
||||
score = 2.0,
|
||||
remoteUrl = "https://example.com",
|
||||
startDate = 0L,
|
||||
finishDate = 0L,
|
||||
)
|
||||
private val trackItemWithoutTrack = TrackItem(
|
||||
track = null,
|
||||
tracker = DummyTracker(
|
||||
id = 1L,
|
||||
name = "Example Tracker",
|
||||
),
|
||||
)
|
||||
private val trackItemWithTrack = TrackItem(
|
||||
track = aTrack,
|
||||
tracker = DummyTracker(
|
||||
id = 2L,
|
||||
name = "Example Tracker 2",
|
||||
),
|
||||
)
|
||||
|
||||
private val trackersWithAndWithoutTrack = @Composable {
|
||||
TrackInfoDialogHome(
|
||||
trackItems = listOf(
|
||||
trackItemWithoutTrack,
|
||||
trackItemWithTrack,
|
||||
),
|
||||
dateFormat = DateFormat.getDateInstance(),
|
||||
onStatusClick = {},
|
||||
onChapterClick = {},
|
||||
onScoreClick = {},
|
||||
onStartDateEdit = {},
|
||||
onEndDateEdit = {},
|
||||
onNewSearch = {},
|
||||
onOpenInBrowser = {},
|
||||
onRemoved = {},
|
||||
)
|
||||
}
|
||||
|
||||
private val noTrackers = @Composable {
|
||||
TrackInfoDialogHome(
|
||||
trackItems = listOf(),
|
||||
dateFormat = DateFormat.getDateInstance(),
|
||||
onStatusClick = {},
|
||||
onChapterClick = {},
|
||||
onScoreClick = {},
|
||||
onStartDateEdit = {},
|
||||
onEndDateEdit = {},
|
||||
onNewSearch = {},
|
||||
onOpenInBrowser = {},
|
||||
onRemoved = {},
|
||||
)
|
||||
}
|
||||
|
||||
override val values: Sequence<@Composable () -> Unit>
|
||||
get() = sequenceOf(
|
||||
trackersWithAndWithoutTrack,
|
||||
noTrackers,
|
||||
)
|
||||
}
|
|
@ -30,12 +30,14 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.presentation.theme.TachiyomiTheme
|
||||
import eu.kanade.tachiyomi.R
|
||||
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
|
||||
import tachiyomi.presentation.core.components.WheelNumberPicker
|
||||
import tachiyomi.presentation.core.components.WheelTextPicker
|
||||
import tachiyomi.presentation.core.components.material.AlertDialogContent
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.util.ThemePreviews
|
||||
import tachiyomi.presentation.core.util.isScrolledToEnd
|
||||
import tachiyomi.presentation.core.util.isScrolledToStart
|
||||
|
||||
|
@ -218,3 +220,25 @@ private fun BaseSelector(
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun TrackStatusSelectorPreviews() {
|
||||
TachiyomiTheme {
|
||||
TrackStatusSelector(
|
||||
selection = 1,
|
||||
onSelectionChange = {},
|
||||
selections = mapOf(
|
||||
// Anilist values
|
||||
1 to R.string.reading,
|
||||
2 to R.string.plan_to_read,
|
||||
3 to R.string.completed,
|
||||
4 to R.string.on_hold,
|
||||
5 to R.string.dropped,
|
||||
6 to R.string.repeating,
|
||||
),
|
||||
onConfirm = {},
|
||||
onDismissRequest = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,8 +57,10 @@ import androidx.compose.ui.text.input.TextFieldValue
|
|||
import androidx.compose.ui.text.intl.Locale
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.text.toLowerCase
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.presentation.manga.components.MangaCover
|
||||
import eu.kanade.presentation.theme.TachiyomiTheme
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
|
||||
|
@ -66,6 +68,7 @@ import tachiyomi.presentation.core.components.material.Scaffold
|
|||
import tachiyomi.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.screens.EmptyScreen
|
||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||
import tachiyomi.presentation.core.util.ThemePreviews
|
||||
import tachiyomi.presentation.core.util.plus
|
||||
import tachiyomi.presentation.core.util.runOnEnterKeyPressed
|
||||
import tachiyomi.presentation.core.util.secondaryItemAlpha
|
||||
|
@ -316,3 +319,12 @@ private fun SearchResultItemDetails(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun TrackerSearchPreviews(
|
||||
@PreviewParameter(TrackerSearchPreviewProvider::class)
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
TachiyomiTheme { content() }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package eu.kanade.presentation.track
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import java.time.Instant
|
||||
import java.time.temporal.ChronoUnit
|
||||
import kotlin.random.Random
|
||||
|
||||
internal class TrackerSearchPreviewProvider : PreviewParameterProvider<@Composable () -> Unit> {
|
||||
private val fullPageWithSecondSelected = @Composable {
|
||||
val items = someTrackSearches().take(30).toList()
|
||||
TrackerSearch(
|
||||
query = TextFieldValue(text = "search text"),
|
||||
onQueryChange = {},
|
||||
onDispatchQuery = {},
|
||||
queryResult = Result.success(items),
|
||||
selected = items[1],
|
||||
onSelectedChange = {},
|
||||
onConfirmSelection = {},
|
||||
onDismissRequest = {},
|
||||
)
|
||||
}
|
||||
private val fullPageWithoutSelected = @Composable {
|
||||
TrackerSearch(
|
||||
query = TextFieldValue(text = ""),
|
||||
onQueryChange = {},
|
||||
onDispatchQuery = {},
|
||||
queryResult = Result.success(someTrackSearches().take(30).toList()),
|
||||
selected = null,
|
||||
onSelectedChange = {},
|
||||
onConfirmSelection = {},
|
||||
onDismissRequest = {},
|
||||
)
|
||||
}
|
||||
private val loading = @Composable {
|
||||
TrackerSearch(
|
||||
query = TextFieldValue(),
|
||||
onQueryChange = {},
|
||||
onDispatchQuery = {},
|
||||
queryResult = null,
|
||||
selected = null,
|
||||
onSelectedChange = {},
|
||||
onConfirmSelection = {},
|
||||
onDismissRequest = {},
|
||||
)
|
||||
}
|
||||
override val values: Sequence<@Composable () -> Unit> = sequenceOf(
|
||||
fullPageWithSecondSelected,
|
||||
fullPageWithoutSelected,
|
||||
loading,
|
||||
)
|
||||
|
||||
private fun someTrackSearches(): Sequence<TrackSearch> = sequence {
|
||||
while (true) {
|
||||
yield(randTrackSearch())
|
||||
}
|
||||
}
|
||||
|
||||
private fun randTrackSearch() = TrackSearch().let {
|
||||
it.id = Random.nextLong()
|
||||
it.manga_id = Random.nextLong()
|
||||
it.sync_id = Random.nextInt()
|
||||
it.media_id = Random.nextLong()
|
||||
it.library_id = Random.nextLong()
|
||||
it.title = lorem((1..10).random()).joinToString()
|
||||
it.last_chapter_read = (0..100).random().toFloat()
|
||||
it.total_chapters = (100..1000).random()
|
||||
it.score = (0..10).random().toFloat()
|
||||
it.status = Random.nextInt()
|
||||
it.started_reading_date = 0L
|
||||
it.finished_reading_date = 0L
|
||||
it.tracking_url = "https://example.com/tracker-example"
|
||||
it.cover_url = "https://example.com/cover.png"
|
||||
it.start_date = Instant.now().minus((1L..365).random(), ChronoUnit.DAYS).toString()
|
||||
it.summary = lorem((0..40).random()).joinToString()
|
||||
it
|
||||
}
|
||||
|
||||
private fun lorem(words: Int): Sequence<String> =
|
||||
LoremIpsum(words).values
|
||||
}
|
|
@ -11,8 +11,11 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.presentation.theme.TachiyomiTheme
|
||||
import eu.kanade.tachiyomi.data.track.Tracker
|
||||
import tachiyomi.presentation.core.util.ThemePreviews
|
||||
import tachiyomi.presentation.core.util.clickableNoIndication
|
||||
|
||||
@Composable
|
||||
|
@ -39,3 +42,17 @@ fun TrackLogoIcon(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun TrackLogoIconPreviews(
|
||||
@PreviewParameter(TrackLogoIconPreviewProvider::class)
|
||||
tracker: Tracker,
|
||||
) {
|
||||
TachiyomiTheme {
|
||||
TrackLogoIcon(
|
||||
tracker = tracker,
|
||||
onClick = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package eu.kanade.presentation.track.components
|
||||
|
||||
import android.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.track.Tracker
|
||||
import eu.kanade.tachiyomi.dev.preview.DummyTracker
|
||||
|
||||
internal class TrackLogoIconPreviewProvider : PreviewParameterProvider<Tracker> {
|
||||
|
||||
override val values: Sequence<Tracker>
|
||||
get() = sequenceOf(
|
||||
DummyTracker(
|
||||
id = 1L,
|
||||
name = "Dummy Tracker",
|
||||
valLogoColor = Color.rgb(18, 25, 35),
|
||||
valLogo = R.drawable.ic_tracker_anilist,
|
||||
),
|
||||
)
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package eu.kanade.tachiyomi.dev.preview
|
||||
|
||||
import android.graphics.Color
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.track.Tracker
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import okhttp3.OkHttpClient
|
||||
import tachiyomi.domain.track.model.Track
|
||||
|
||||
data class DummyTracker(
|
||||
override val id: Long,
|
||||
override val name: String,
|
||||
override val supportsReadingDates: Boolean = false,
|
||||
override val isLoggedIn: Boolean = false,
|
||||
val valLogoColor: Int = Color.rgb(18, 25, 35),
|
||||
val valLogo: Int = R.drawable.ic_tracker_anilist,
|
||||
val valStatuses: List<Int> = (1..6).toList(),
|
||||
val valReadingStatus: Int = 1,
|
||||
val valRereadingStatus: Int = 1,
|
||||
val valCompletionStatus: Int = 2,
|
||||
val valScoreList: List<String> = (0..10).map(Int::toString),
|
||||
val val10PointScore: Double = 5.4,
|
||||
val valSearchResults: List<TrackSearch> = listOf(),
|
||||
) : Tracker {
|
||||
|
||||
override val client: OkHttpClient
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun getLogoColor(): Int = valLogoColor
|
||||
|
||||
override fun getLogo(): Int = valLogo
|
||||
|
||||
override fun getStatusList(): List<Int> = valStatuses
|
||||
|
||||
override fun getStatus(status: Int): Int? = when (status) {
|
||||
1 -> R.string.reading
|
||||
2 -> R.string.plan_to_read
|
||||
3 -> R.string.completed
|
||||
4 -> R.string.on_hold
|
||||
5 -> R.string.dropped
|
||||
6 -> R.string.repeating
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun getReadingStatus(): Int = valReadingStatus
|
||||
|
||||
override fun getRereadingStatus(): Int = valRereadingStatus
|
||||
|
||||
override fun getCompletionStatus(): Int = valCompletionStatus
|
||||
|
||||
override fun getScoreList(): List<String> = valScoreList
|
||||
|
||||
override fun get10PointScore(track: Track): Double = val10PointScore
|
||||
|
||||
override fun indexToScore(index: Int): Float = getScoreList()[index].toFloat()
|
||||
|
||||
override fun displayScore(track: eu.kanade.tachiyomi.data.database.models.Track): String =
|
||||
track.score.toString()
|
||||
|
||||
override suspend fun update(
|
||||
track: eu.kanade.tachiyomi.data.database.models.Track,
|
||||
didReadChapter: Boolean,
|
||||
): eu.kanade.tachiyomi.data.database.models.Track = track
|
||||
|
||||
override suspend fun bind(
|
||||
track: eu.kanade.tachiyomi.data.database.models.Track,
|
||||
hasReadChapters: Boolean,
|
||||
): eu.kanade.tachiyomi.data.database.models.Track = track
|
||||
|
||||
override suspend fun search(query: String): List<TrackSearch> = valSearchResults
|
||||
|
||||
override suspend fun refresh(
|
||||
track: eu.kanade.tachiyomi.data.database.models.Track,
|
||||
): eu.kanade.tachiyomi.data.database.models.Track = track
|
||||
|
||||
override suspend fun login(username: String, password: String) = Unit
|
||||
|
||||
override fun logout() = Unit
|
||||
|
||||
override fun getUsername(): String = "username"
|
||||
|
||||
override fun getPassword(): String = "passw0rd"
|
||||
|
||||
override fun saveCredentials(username: String, password: String) = Unit
|
||||
|
||||
override suspend fun register(
|
||||
item: eu.kanade.tachiyomi.data.database.models.Track,
|
||||
mangaId: Long,
|
||||
) = Unit
|
||||
|
||||
override suspend fun setRemoteStatus(
|
||||
track: eu.kanade.tachiyomi.data.database.models.Track,
|
||||
status: Int,
|
||||
) = Unit
|
||||
|
||||
override suspend fun setRemoteLastChapterRead(
|
||||
track: eu.kanade.tachiyomi.data.database.models.Track,
|
||||
chapterNumber: Int,
|
||||
) = Unit
|
||||
|
||||
override suspend fun setRemoteScore(
|
||||
track: eu.kanade.tachiyomi.data.database.models.Track,
|
||||
scoreString: String,
|
||||
) = Unit
|
||||
|
||||
override suspend fun setRemoteStartDate(
|
||||
track: eu.kanade.tachiyomi.data.database.models.Track,
|
||||
epochMillis: Long,
|
||||
) = Unit
|
||||
|
||||
override suspend fun setRemoteFinishDate(
|
||||
track: eu.kanade.tachiyomi.data.database.models.Track,
|
||||
epochMillis: Long,
|
||||
) = Unit
|
||||
}
|
Reference in a new issue