Ver Fonte

[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
Caleb Morris há 1 ano atrás
pai
commit
6d1e520c6c

+ 14 - 0
app/src/main/java/eu/kanade/presentation/track/TrackInfoDialogHome.kt

@@ -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() }
+}

+ 81 - 0
app/src/main/java/eu/kanade/presentation/track/TrackInfoDialogHomePreviewProvider.kt

@@ -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,
+        )
+}

+ 24 - 0
app/src/main/java/eu/kanade/presentation/track/TrackInfoDialogSelector.kt

@@ -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 = {},
+        )
+    }
+}

+ 12 - 0
app/src/main/java/eu/kanade/presentation/track/TrackerSearch.kt

@@ -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() }
+}

+ 84 - 0
app/src/main/java/eu/kanade/presentation/track/TrackerSearchPreviewProvider.kt

@@ -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
+}

+ 17 - 0
app/src/main/java/eu/kanade/presentation/track/components/TrackLogoIcon.kt

@@ -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,
+        )
+    }
+}

+ 20 - 0
app/src/main/java/eu/kanade/presentation/track/components/TrackLogoIconPreviewProvider.kt

@@ -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,
+            ),
+        )
+}

+ 115 - 0
app/src/main/java/eu/kanade/tachiyomi/dev/preview/DummyTracker.kt

@@ -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
+}