Skip to content
This repository has been archived by the owner on Nov 12, 2024. It is now read-only.

Commit

Permalink
Converting 'Discover' to Jetpack Compose (#692)
Browse files Browse the repository at this point in the history
* Add initial skeleton Compose setup to Discover
* Hook up Compose discover to fragment
* Show trending, popular and recommended shows
* Re-use Carousel and PosterCard in ShowDetails.kt
* Show next episode to watch
* Fix app bar behavior
* Add overflow actions to open grids
* Change overflow buttons to secondary
* Limit discover carousels to 10 items
* Refactor Carousel and header logic
* Add refresh app bar action
* Stop passing actioner around
* Move to using ComposeView
* Add todo to investigate removing text from poster card
* Address review comments
  • Loading branch information
chrisbanes authored Sep 15, 2020
1 parent 80b8da5 commit 4330a30
Show file tree
Hide file tree
Showing 22 changed files with 669 additions and 633 deletions.
3 changes: 3 additions & 0 deletions common-ui-compose/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ android {

dependencies {
implementation project(':base-android')
implementation project(':data')
api project(':common-imageloading')

implementation Libs.AndroidX.coreKtx
Expand All @@ -62,4 +63,6 @@ dependencies {
implementation Libs.Mdc.material

implementation Libs.Kotlin.stdlib

implementation Libs.Accompanist.coil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package app.tivi.common.compose

import androidx.compose.foundation.layout.InnerPadding
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.lazy.LazyRowFor
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp

@Composable
fun <T> Carousel(
items: List<T>,
modifier: Modifier = Modifier,
contentPadding: InnerPadding = InnerPadding(0.dp),
itemSpacing: Dp = 0.dp,
verticalGravity: Alignment.Vertical = Alignment.Top,
itemContent: @Composable LazyItemScope.(T, InnerPadding) -> Unit
) {
val halfSpacing = itemSpacing / 2
val spacingContent = InnerPadding(halfSpacing, 0.dp, halfSpacing, 0.dp)

LazyRowFor(
items = items,
modifier = modifier,
contentPadding = contentPadding.copy(
start = (contentPadding.start - halfSpacing).coerceAtLeast(0.dp),
end = (contentPadding.end - halfSpacing).coerceAtLeast(0.dp)
),
verticalGravity = verticalGravity,
itemContent = { item -> itemContent(item, spacingContent) }
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package app.tivi.common.compose

import androidx.compose.foundation.Text
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Stack
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Card
import androidx.compose.material.EmphasisAmbient
import androidx.compose.material.MaterialTheme
import androidx.compose.material.ProvideEmphasis
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import app.tivi.data.entities.TiviShow
import app.tivi.data.entities.TmdbImageEntity
import dev.chrisbanes.accompanist.coil.CoilImageWithCrossfade

@Composable
fun PosterCard(
show: TiviShow,
poster: TmdbImageEntity? = null,
onClick: (() -> Unit)? = null,
modifier: Modifier = Modifier
) {
Card(modifier = modifier) {
Stack(
modifier = if (onClick != null) Modifier.clickable(onClick = onClick) else Modifier
) {
// TODO: remove text if the image has loaded (and animated in).
// https://github.com/chrisbanes/accompanist/issues/76
ProvideEmphasis(EmphasisAmbient.current.medium) {
Text(
text = show.title ?: "No title",
style = MaterialTheme.typography.caption,
modifier = Modifier.padding(4.dp).gravity(Alignment.CenterStart)
)
}
if (poster != null) {
CoilImageWithCrossfade(
data = poster,
modifier = Modifier.matchParentSize()
)
}
}
}
}
4 changes: 2 additions & 2 deletions data/src/main/java/app/tivi/data/daos/PopularDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ abstract class PopularDao : PaginatedEntryDao<PopularShowEntry, PopularEntryWith
abstract fun entriesObservable(page: Int): Flow<List<PopularShowEntry>>

@Transaction
@Query("SELECT * FROM popular_shows ORDER BY page, page_order")
abstract fun entriesObservable(): Flow<List<PopularEntryWithShow>>
@Query("SELECT * FROM popular_shows ORDER BY page, page_order LIMIT :count OFFSET :offset")
abstract fun entriesObservable(count: Int, offset: Int): Flow<List<PopularEntryWithShow>>

@Transaction
@Query("SELECT * FROM popular_shows ORDER BY page, page_order")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ import javax.inject.Inject

class ObservePopularShows @Inject constructor(
private val popularShowsRepository: PopularDao
) : SubjectInteractor<Unit, List<PopularEntryWithShow>>() {
) : SubjectInteractor<ObservePopularShows.Params, List<PopularEntryWithShow>>() {

override fun createObservable(params: Unit): Flow<List<PopularEntryWithShow>> {
return popularShowsRepository.entriesObservable()
override fun createObservable(
params: ObservePopularShows.Params
): Flow<List<PopularEntryWithShow>> {
return popularShowsRepository.entriesObservable(params.count, 0)
}

data class Params(val count: Int = 20)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ import javax.inject.Inject

class ObserveRecommendedShows @Inject constructor(
private val recommendedDao: RecommendedDao
) : SubjectInteractor<Unit, List<RecommendedEntryWithShow>>() {
) : SubjectInteractor<ObserveRecommendedShows.Params, List<RecommendedEntryWithShow>>() {

override fun createObservable(params: Unit): Flow<List<RecommendedEntryWithShow>> {
return recommendedDao.entriesObservable(20, 0)
override fun createObservable(
params: ObserveRecommendedShows.Params
): Flow<List<RecommendedEntryWithShow>> {
return recommendedDao.entriesObservable(params.count, 0)
}

data class Params(val count: Int = 20)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@

package app.tivi.account

import androidx.compose.runtime.Immutable
import app.tivi.data.entities.TraktUser
import app.tivi.trakt.TraktAuthState

@Immutable
data class AccountUiViewState(
val user: TraktUser? = null,
val authState: TraktAuthState = TraktAuthState.LOGGED_OUT
Expand Down
27 changes: 19 additions & 8 deletions ui-discover/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ android {
}

buildFeatures {
dataBinding true
compose true
}

composeOptions {
kotlinCompilerVersion Libs.Kotlin.version
kotlinCompilerExtensionVersion Libs.AndroidX.Compose.version
}
}

Expand All @@ -51,24 +56,30 @@ dependencies {
implementation project(':base-android')
implementation project(':domain')
implementation project(':common-ui-view')
implementation project(':common-epoxy')
implementation project(':common-layouts')
implementation project(':common-imageloading')
implementation project(':common-databinding')
implementation project(':common-ui-compose')

implementation Libs.AndroidX.Lifecycle.livedata
implementation Libs.AndroidX.Lifecycle.viewmodel

implementation Libs.AndroidX.appcompat
implementation Libs.AndroidX.recyclerview
implementation Libs.AndroidX.swiperefresh
implementation Libs.AndroidX.constraintlayout
implementation Libs.AndroidX.coreKtx
implementation Libs.AndroidX.Fragment.fragment
implementation Libs.AndroidX.Fragment.fragmentKtx
implementation Libs.AndroidX.Navigation.fragment

implementation Libs.AndroidX.Compose.runtime
implementation Libs.AndroidX.Compose.foundation
implementation Libs.AndroidX.Compose.ui
implementation Libs.AndroidX.Compose.layout
implementation Libs.AndroidX.Compose.material
implementation Libs.AndroidX.Compose.animation
implementation Libs.AndroidX.Compose.tooling
implementation Libs.AndroidX.Compose.livedata

implementation Libs.Mdc.material
implementation Libs.Mdc.composeThemeAdapter

implementation Libs.Accompanist.coil

implementation Libs.Hilt.library
kapt Libs.Hilt.compiler
Expand Down
Loading

0 comments on commit 4330a30

Please sign in to comment.