From 7da64ff119990df23bd5a026be8c2757ebbd2a82 Mon Sep 17 00:00:00 2001 From: Manuel Vivo Date: Wed, 14 Oct 2020 21:00:36 +0200 Subject: [PATCH] Merges alpha05 branch to main (#228) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Jetcaster] Update to SNAPSHOT 6891475 (#216) * Update Jetcaster to SNAPSHOT 6891475 * Fix episode title being centered * [Crane] Update to SNAPSHOT 6891475 (#217) * [Jetchat] Update to SNAPSHOT 6891475 Change-Id: I4a9e194aabce890638da09a632de33928ad5237f * Spotless Change-Id: Ic46c8dcfd12451ff3988a1127ac97062b0b440fb * [Rally] Update to SNAPSHOT 6891475 Change-Id: I3252cfe051737927d76cc8559d24bf516a720d3c * [Jetsurvey] Bump to alpha05 * [Jetsurvey] Using onSizeChanged to set the branding height * [Jetsurvey] Bump to alpha05 * [Jetsurvey] Using onSizeChanged to set the branding height * [Rally] Removes maven central snapshot repo Change-Id: I473f1f55b40e4c81fc655568828db3ab94fea0a6 * [Jetchat] Removes maven central snapshot repo Change-Id: I5b16871c3ef1a612da8b6f1d96309f2bc40c19d3 * [Jetsnack] Update to snapshot 6901934. Change-Id: I1d6a951b9cba9994241315348daedaac1b5f278c * [Jetsnack] Remove unused import. Change-Id: Ieacdb2dc7253fe25977c123ee3d140b7bdb81f0d * [Owl] Accept modifiers in search suggestion items. Change-Id: I9a5bf25e5bfa4632738e1e03539039a9959a03f0 * [Owl] Update to snapshot 6901934. Change-Id: I15c92c5252e61b8918bbb9c80cbdc679e3809555 * Bump JetNews to alpha05 (#221) Changes: - Use new produceState API in launchUiStateProducer - Rename launchUiStateProducer to produceUiState to match naming - Change launchInComposition to new API LaunchedTask - Replace Box/Surface with new Box import - Update modifiers for Text composable to work with new layout rules - Update to use new AmbientContentColor and AmbientEmphasisLevels Bugfix: - Fix size of error case in [HomeScreenErrorAndContent], avoiding the swipe to refresh drawing in the incorrect place. * [Readme] Removes known issues (#222) * [All] Updates to alpha05 (#227) * [All] Updates to 6901934 snapshot * [All] Updates to alpha05 Co-authored-by: Chris Banes Co-authored-by: Jose Alcerreca Co-authored-by: Florina Muntenescu Co-authored-by: Florina Muntenescu <2998890+florina-muntenescu@users.noreply.github.com> Co-authored-by: Jose Alcérreca Co-authored-by: Nick Butcher Co-authored-by: Nick Butcher Co-authored-by: Sean McQuillan --- Crane/app/build.gradle | 10 ++- .../samples/crane/base/BaseUserInput.kt | 6 +- .../samples/crane/base/ExploreSection.kt | 9 +- .../samples/crane/calendar/Calendar.kt | 4 +- .../crane/calendar/CalendarActivity.kt | 4 +- .../samples/crane/details/DetailsActivity.kt | 4 +- .../compose/samples/crane/home/CraneHome.kt | 4 +- .../samples/crane/home/LandingScreen.kt | 10 +-- .../samples/crane/home/MainActivity.kt | 8 +- Crane/build.gradle | 17 +--- .../example/crane/buildsrc/Dependencies.kt | 10 +-- JetNews/app/build.gradle | 6 +- .../java/com/example/jetnews/ui/JetnewsApp.kt | 3 +- .../com/example/jetnews/ui/SwipeToRefresh.kt | 5 +- .../jetnews/ui/article/ArticleScreen.kt | 10 +-- .../example/jetnews/ui/article/PostContent.kt | 22 ++--- .../com/example/jetnews/ui/home/HomeScreen.kt | 21 +++-- .../example/jetnews/ui/home/PostCardTop.kt | 4 +- .../jetnews/ui/home/PostCardYourNetwork.kt | 4 +- .../com/example/jetnews/ui/home/PostCards.kt | 10 +-- .../jetnews/ui/interests/InterestsScreen.kt | 15 ++-- .../jetnews/ui/interests/SelectTopicButton.kt | 4 +- ...chUiStateProducer.kt => ProduceUiState.kt} | 70 ++++++++------- JetNews/build.gradle | 18 +--- .../com/example/jetcaster/ui/home/Home.kt | 12 +-- .../ui/home/category/PodcastCategory.kt | 29 +++--- .../com/example/jetcaster/util/Buttons.kt | 8 +- Jetcaster/build.gradle | 7 +- .../jetcaster/buildsrc/dependencies.kt | 12 ++- Jetchat/app/build.gradle | 7 ++ .../jetchat/conversation/Conversation.kt | 14 +-- .../jetchat/conversation/MessageFormatter.kt | 2 +- .../compose/jetchat/conversation/UserInput.kt | 19 ++-- .../compose/jetchat/profile/Profile.kt | 12 +-- Jetchat/build.gradle | 7 +- .../compose/jetchat/buildsrc/dependencies.kt | 10 ++- .../jetsnack/ui/components/Gradient.kt | 4 +- .../jetsnack/ui/components/Scaffold.kt | 7 +- .../example/jetsnack/ui/components/Snacks.kt | 5 +- .../example/jetsnack/ui/components/Surface.kt | 6 +- .../jetsnack/ui/home/search/Results.kt | 27 ++++-- .../example/jetsnack/ui/home/search/Search.kt | 6 +- .../jetsnack/ui/home/search/Suggestions.kt | 90 ++++++++++++++----- .../com/example/jetsnack/ui/theme/Theme.kt | 18 ++-- .../com/example/jetsnack/ui/utils/Insets.kt | 20 ++--- .../example/jetsnack/buildsrc/Dependencies.kt | 4 +- Jetsurvey/app/build.gradle | 7 ++ .../jetsurvey/signinsignup/SignInScreen.kt | 4 +- .../jetsurvey/signinsignup/SignInSignUp.kt | 12 +-- .../jetsurvey/signinsignup/SignUpScreen.kt | 4 +- .../jetsurvey/signinsignup/WelcomeScreen.kt | 15 ++-- Jetsurvey/build.gradle | 6 +- .../jetsurvey/buildsrc/dependencies.kt | 9 +- .../main/java/com/example/owl/ui/OwlApp.kt | 4 +- .../example/owl/ui/common/CourseListItem.kt | 2 + .../example/owl/ui/course/CourseDetails.kt | 14 +-- .../com/example/owl/ui/courses/Courses.kt | 4 +- .../com/example/owl/ui/courses/MyCourses.kt | 24 +++-- .../example/owl/ui/courses/SearchCourses.kt | 2 + .../example/owl/ui/onboarding/Onboarding.kt | 8 +- .../ui/theme/{Elevation.kt => Elevations.kt} | 4 +- .../java/com/example/owl/ui/theme/Images.kt | 2 +- .../java/com/example/owl/ui/theme/Theme.kt | 18 ++-- .../java/com/example/owl/ui/utils/Insets.kt | 20 ++--- .../com/example/owl/ui/utils/Navigation.kt | 4 +- .../com/example/owl/ui/utils/NetworkImage.kt | 6 +- .../com/example/owl/buildsrc/Dependencies.kt | 4 +- README.md | 6 -- Rally/app/build.gradle | 7 ++ .../compose/rally/ui/components/CommonUi.kt | 8 +- .../rally/ui/overview/OverviewScreen.kt | 6 +- Rally/build.gradle | 7 +- .../compose/rally/buildsrc/dependencies.kt | 9 +- 73 files changed, 446 insertions(+), 374 deletions(-) rename JetNews/app/src/main/java/com/example/jetnews/utils/{LaunchUiStateProducer.kt => ProduceUiState.kt} (68%) rename Owl/app/src/main/java/com/example/owl/ui/theme/{Elevation.kt => Elevations.kt} (88%) diff --git a/Crane/app/build.gradle b/Crane/app/build.gradle index 2838864b8c..a2d1d99f64 100644 --- a/Crane/app/build.gradle +++ b/Crane/app/build.gradle @@ -72,7 +72,14 @@ android { } buildFeatures { - compose true + compose true + + // Disable unused AGP features + buildConfig false + aidl false + renderScript false + resValues false + shaders false } composeOptions { kotlinCompilerVersion Libs.Kotlin.version @@ -92,7 +99,6 @@ dependencies { implementation Libs.AndroidX.Compose.animation implementation Libs.AndroidX.UI.tooling - implementation Libs.AndroidX.appcompat implementation Libs.Accompanist.coil androidTestImplementation Libs.AndroidX.Test.runner diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/base/BaseUserInput.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/base/BaseUserInput.kt index 9122f264ec..f6e39f8555 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/base/BaseUserInput.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/base/BaseUserInput.kt @@ -17,11 +17,11 @@ package androidx.compose.samples.crane.base import androidx.annotation.DrawableRes +import androidx.compose.foundation.AmbientContentColor import androidx.compose.foundation.BaseTextField import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Icon import androidx.compose.foundation.Text -import androidx.compose.foundation.contentColor import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding @@ -63,7 +63,7 @@ fun CraneUserInput( modifier: Modifier = Modifier, caption: String? = null, @DrawableRes vectorImageId: Int? = null, - tint: Color = contentColor() + tint: Color = AmbientContentColor.current ) { CraneBaseUserInput( modifier = modifier, @@ -111,7 +111,7 @@ private fun CraneBaseUserInput( @DrawableRes vectorImageId: Int? = null, showCaption: () -> Boolean = { true }, tintIcon: () -> Boolean, - tint: Color = contentColor(), + tint: Color = AmbientContentColor.current, children: @Composable () -> Unit ) { Surface(modifier = modifier, color = MaterialTheme.colors.primaryVariant) { diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt index 74ec38879e..ffacb17f7a 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/base/ExploreSection.kt @@ -19,10 +19,10 @@ package androidx.compose.samples.crane.base import androidx.compose.foundation.Image import androidx.compose.foundation.Text import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.Stack import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredHeight @@ -46,7 +46,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.dp -import dev.chrisbanes.accompanist.coil.CoilImageWithCrossfade +import dev.chrisbanes.accompanist.coil.CoilImage @Composable fun ExploreSection( @@ -89,11 +89,12 @@ private fun ExploreItem( .padding(top = 12.dp, bottom = 12.dp) ) { ExploreImageContainer { - CoilImageWithCrossfade( + CoilImage( data = item.imageUrl, + fadeIn = true, contentScale = ContentScale.Crop, loading = { - Stack(Modifier.fillMaxSize()) { + Box(Modifier.fillMaxSize()) { Image( modifier = Modifier.preferredSize(36.dp).align(Alignment.Center), asset = vectorResource(id = R.drawable.ic_crane_logo) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/calendar/Calendar.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/calendar/Calendar.kt index 4614da8891..b785cbe137 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/calendar/Calendar.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/calendar/Calendar.kt @@ -19,10 +19,10 @@ package androidx.compose.samples.crane.calendar import androidx.compose.foundation.ScrollableColumn import androidx.compose.foundation.Text import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.Stack import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -210,7 +210,7 @@ private fun DayStatusContainer( children: @Composable () -> Unit ) { if (status.isMarked()) { - Stack { + Box { val color = MaterialTheme.colors.secondary Circle(color = color) if (status == DaySelectedStatus.FirstDay) { diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/calendar/CalendarActivity.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/calendar/CalendarActivity.kt index 45152a8d07..bdfb166bb7 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/calendar/CalendarActivity.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/calendar/CalendarActivity.kt @@ -19,7 +19,7 @@ package androidx.compose.samples.crane.calendar import android.content.Context import android.content.Intent import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity +import androidx.activity.ComponentActivity import androidx.compose.foundation.Image import androidx.compose.foundation.Text import androidx.compose.foundation.layout.Column @@ -42,7 +42,7 @@ fun launchCalendarActivity(context: Context) { context.startActivity(intent) } -class CalendarActivity : AppCompatActivity() { +class CalendarActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/details/DetailsActivity.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/details/DetailsActivity.kt index c352a63f4e..4715a32dc5 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/details/DetailsActivity.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/details/DetailsActivity.kt @@ -19,8 +19,8 @@ package androidx.compose.samples.crane.details import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.activity.ComponentActivity import androidx.annotation.VisibleForTesting -import androidx.appcompat.app.AppCompatActivity import androidx.compose.foundation.Text import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -73,7 +73,7 @@ data class DetailsActivityArg( val longitude: String ) -class DetailsActivity : AppCompatActivity() { +class DetailsActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt index a53e914198..510c72769f 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/home/CraneHome.kt @@ -21,7 +21,7 @@ import androidx.compose.material.BackdropValue import androidx.compose.material.DrawerValue import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalDrawerLayout -import androidx.compose.material.rememberBackdropState +import androidx.compose.material.rememberBackdropScaffoldState import androidx.compose.material.rememberDrawerState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -82,7 +82,7 @@ fun CraneHomeContent( BackdropScaffold( modifier = modifier, - backdropScaffoldState = rememberBackdropState(BackdropValue.Revealed), + scaffoldState = rememberBackdropScaffoldState(BackdropValue.Revealed), frontLayerScrimColor = Color.Transparent, appBar = { HomeTabBar(openDrawer, tabSelected, onTabSelected = { tabSelected = it }) diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/home/LandingScreen.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/home/LandingScreen.kt index ee3e8dcfbb..577aab16e5 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/home/LandingScreen.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/home/LandingScreen.kt @@ -16,13 +16,13 @@ package androidx.compose.samples.crane.home -import androidx.compose.foundation.Box -import androidx.compose.foundation.ContentGravity import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable -import androidx.compose.runtime.launchInComposition +import androidx.compose.runtime.LaunchedTask import androidx.compose.samples.crane.R +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.vectorResource import kotlinx.coroutines.delay @@ -31,8 +31,8 @@ private const val SplashWaitTime: Long = 2000 @Composable fun LandingScreen(modifier: Modifier = Modifier, onTimeout: () -> Unit) { - Box(modifier = modifier.fillMaxSize(), gravity = ContentGravity.Center) { - launchInComposition { + Box(modifier = modifier.fillMaxSize(), alignment = Alignment.Center) { + LaunchedTask { delay(SplashWaitTime) onTimeout() } diff --git a/Crane/app/src/main/java/androidx/compose/samples/crane/home/MainActivity.kt b/Crane/app/src/main/java/androidx/compose/samples/crane/home/MainActivity.kt index 96d228954a..f600492b94 100644 --- a/Crane/app/src/main/java/androidx/compose/samples/crane/home/MainActivity.kt +++ b/Crane/app/src/main/java/androidx/compose/samples/crane/home/MainActivity.kt @@ -17,7 +17,7 @@ package androidx.compose.samples.crane.home import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity +import androidx.activity.ComponentActivity import androidx.compose.animation.DpPropKey import androidx.compose.animation.core.FloatPropKey import androidx.compose.animation.core.Spring.StiffnessLow @@ -25,9 +25,9 @@ import androidx.compose.animation.core.spring import androidx.compose.animation.core.transitionDefinition import androidx.compose.animation.core.tween import androidx.compose.animation.transition +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.Stack import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -43,7 +43,7 @@ import androidx.compose.ui.platform.setContent import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -class MainActivity : AppCompatActivity() { +class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -59,7 +59,7 @@ class MainActivity : AppCompatActivity() { var splashShown by remember { mutableStateOf(SplashState.Shown) } val transition = transition(splashTransitionDefinition, splashShown) - Stack { + Box { LandingScreen( modifier = Modifier.drawOpacity(transition[splashAlphaKey]), onTimeout = { splashShown = SplashState.Completed } diff --git a/Crane/build.gradle b/Crane/build.gradle index fafda987f3..1f6412ac10 100644 --- a/Crane/build.gradle +++ b/Crane/build.gradle @@ -17,7 +17,6 @@ import com.example.crane.buildsrc.Libs import com.example.crane.buildsrc.Urls import com.example.crane.buildsrc.Versions -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { repositories { @@ -57,7 +56,7 @@ subprojects { } } - tasks.withType(KotlinCompile).configureEach { + tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { kotlinOptions { // Treat all Kotlin warnings as errors allWarningsAsErrors = true @@ -69,18 +68,4 @@ subprojects { freeCompilerArgs += '-Xallow-jvm-ir-dependencies' } } - - // Crane uses Compose alpha03 and Android Gradle Plugin 4.2.0-alpha13 which are incompatible - // TODO: Remove this workaround when updating to >alpha04 - configurations.configureEach { - resolutionStrategy.eachDependency { DependencyResolveDetails details -> - def group = details.requested.group - def module = details.requested.module.name - def version = details.requested.version - - if (group == 'androidx.compose.compiler' && module == 'compiler') { - details.useTarget("androidx.compose:compose-compiler:$version") - } - } - } } \ No newline at end of file diff --git a/Crane/buildSrc/src/main/java/com/example/crane/buildsrc/Dependencies.kt b/Crane/buildSrc/src/main/java/com/example/crane/buildsrc/Dependencies.kt index 57bda87c95..b533be766f 100644 --- a/Crane/buildSrc/src/main/java/com/example/crane/buildsrc/Dependencies.kt +++ b/Crane/buildSrc/src/main/java/com/example/crane/buildsrc/Dependencies.kt @@ -17,7 +17,7 @@ package com.example.crane.buildsrc object Versions { - const val ktLint = "0.38.1" + const val ktLint = "0.39.0" } object Libs { @@ -26,23 +26,21 @@ object Libs { const val googleMaps = "com.google.android.libraries.maps:maps:3.1.0-beta" object Accompanist { - private const val version = "0.2.2" + private const val version = "0.3.1" const val coil = "dev.chrisbanes.accompanist:accompanist-coil:$version" } object Kotlin { - private const val version = "1.4.0" + private const val version = "1.4.10" const val stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version" const val gradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$version" const val extensions = "org.jetbrains.kotlin:kotlin-android-extensions:$version" } object AndroidX { - const val appcompat = "androidx.appcompat:appcompat:1.3.0-alpha02" - object Compose { const val snapshot = "" - const val version = "1.0.0-alpha03" + const val version = "1.0.0-alpha05" const val runtime = "androidx.compose.runtime:runtime:$version" const val runtimeLivedata = "androidx.compose.runtime:runtime-livedata:$version" diff --git a/JetNews/app/build.gradle b/JetNews/app/build.gradle index 6453c74331..f5cbb880de 100644 --- a/JetNews/app/build.gradle +++ b/JetNews/app/build.gradle @@ -85,10 +85,10 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.3.0-alpha02' implementation 'androidx.activity:activity-ktx:1.1.0' - implementation 'androidx.core:core-ktx:1.5.0-alpha02' + implementation 'androidx.core:core-ktx:1.5.0-alpha04' - implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.0-alpha07" - implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.0-alpha07" + implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.0-beta01" + implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.0-beta01" androidTestImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test:rules:1.3.0' diff --git a/JetNews/app/src/main/java/com/example/jetnews/ui/JetnewsApp.kt b/JetNews/app/src/main/java/com/example/jetnews/ui/JetnewsApp.kt index 3f60b368ac..c718f42b94 100644 --- a/JetNews/app/src/main/java/com/example/jetnews/ui/JetnewsApp.kt +++ b/JetNews/app/src/main/java/com/example/jetnews/ui/JetnewsApp.kt @@ -192,8 +192,7 @@ private fun DrawerButton( Text( text = label, style = MaterialTheme.typography.body2, - color = textIconColor, - modifier = Modifier.fillMaxWidth() + color = textIconColor ) } } diff --git a/JetNews/app/src/main/java/com/example/jetnews/ui/SwipeToRefresh.kt b/JetNews/app/src/main/java/com/example/jetnews/ui/SwipeToRefresh.kt index 5bdf080067..7de3615cde 100644 --- a/JetNews/app/src/main/java/com/example/jetnews/ui/SwipeToRefresh.kt +++ b/JetNews/app/src/main/java/com/example/jetnews/ui/SwipeToRefresh.kt @@ -16,8 +16,7 @@ package com.example.jetnews.ui -import androidx.compose.foundation.Box -import androidx.compose.foundation.layout.Stack +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.offsetPx import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.FractionalThreshold @@ -48,7 +47,7 @@ fun SwipeToRefreshLayout( true } - Stack( + Box( modifier = Modifier.swipeable( state = state, anchors = mapOf( diff --git a/JetNews/app/src/main/java/com/example/jetnews/ui/article/ArticleScreen.kt b/JetNews/app/src/main/java/com/example/jetnews/ui/article/ArticleScreen.kt index d3930e57a0..f04bdf49c2 100644 --- a/JetNews/app/src/main/java/com/example/jetnews/ui/article/ArticleScreen.kt +++ b/JetNews/app/src/main/java/com/example/jetnews/ui/article/ArticleScreen.kt @@ -18,9 +18,9 @@ package com.example.jetnews.ui.article import android.content.Context import android.content.Intent +import androidx.compose.foundation.AmbientContentColor import androidx.compose.foundation.Icon import androidx.compose.foundation.Text -import androidx.compose.foundation.contentColor import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth @@ -57,12 +57,12 @@ import com.example.jetnews.data.posts.impl.post3 import com.example.jetnews.model.Post import com.example.jetnews.ui.ThemedPreview import com.example.jetnews.ui.home.BookmarkButton -import com.example.jetnews.utils.launchUiStateProducer +import com.example.jetnews.utils.produceUiState import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking /** - * Stateful Article Screen that manages state using [launchUiStateProducer] + * Stateful Article Screen that manages state using [produceUiState] * * @param postId (state) the post to show * @param postsRepository data source for this screen @@ -75,7 +75,7 @@ fun ArticleScreen( postsRepository: PostsRepository, onBack: () -> Unit ) { - val (post) = launchUiStateProducer(postsRepository, postId) { + val (post) = produceUiState(postsRepository, postId) { getPost(postId) } // TODO: handle errors when the repository is capable of creating them @@ -129,7 +129,7 @@ fun ArticleScreen( Text( text = "Published in: ${post.publication?.name}", style = MaterialTheme.typography.subtitle2, - color = contentColor() + color = AmbientContentColor.current ) }, navigationIcon = { diff --git a/JetNews/app/src/main/java/com/example/jetnews/ui/article/PostContent.kt b/JetNews/app/src/main/java/com/example/jetnews/ui/article/PostContent.kt index 980b69f8ca..102839619f 100644 --- a/JetNews/app/src/main/java/com/example/jetnews/ui/article/PostContent.kt +++ b/JetNews/app/src/main/java/com/example/jetnews/ui/article/PostContent.kt @@ -16,11 +16,12 @@ package com.example.jetnews.ui.article -import androidx.compose.foundation.Box +import androidx.compose.foundation.AmbientContentColor import androidx.compose.foundation.Image import androidx.compose.foundation.ScrollableColumn import androidx.compose.foundation.Text -import androidx.compose.foundation.contentColor +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -32,8 +33,8 @@ import androidx.compose.foundation.layout.preferredSize import androidx.compose.foundation.layout.preferredWidth import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.text.FirstBaseline +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.Colors -import androidx.compose.material.EmphasisAmbient import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis import androidx.compose.material.Surface @@ -81,7 +82,7 @@ fun PostContent(post: Post, modifier: Modifier = Modifier) { Text(text = post.title, style = MaterialTheme.typography.h4) Spacer(Modifier.preferredHeight(8.dp)) post.subtitle?.let { subtitle -> - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { Text( text = subtitle, style = MaterialTheme.typography.body2, @@ -116,19 +117,19 @@ private fun PostMetadata(metadata: Metadata) { Image( asset = Icons.Filled.AccountCircle, modifier = Modifier.preferredSize(40.dp), - colorFilter = ColorFilter.tint(contentColor()), + colorFilter = ColorFilter.tint(AmbientContentColor.current), contentScale = ContentScale.Fit ) Spacer(Modifier.preferredWidth(8.dp)) Column { - ProvideEmphasis(EmphasisAmbient.current.high) { + ProvideEmphasis(AmbientEmphasisLevels.current.high) { Text( text = metadata.author.name, style = typography.caption, modifier = Modifier.padding(top = 4.dp) ) } - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { Text( text = "${metadata.date} • ${metadata.readTimeMinutes} min read", style = typography.caption @@ -216,10 +217,9 @@ private fun BulletParagraph( .alignWithSiblings { // Add an alignment "baseline" 1sp below the bottom of the circle 9.sp.toIntPx() - }, - backgroundColor = contentColor(), - shape = CircleShape - ) + } + .background(AmbientContentColor.current, CircleShape), + ) { /* no content */ } } Text( modifier = Modifier diff --git a/JetNews/app/src/main/java/com/example/jetnews/ui/home/HomeScreen.kt b/JetNews/app/src/main/java/com/example/jetnews/ui/home/HomeScreen.kt index 5fde32a35f..445a4d02a9 100644 --- a/JetNews/app/src/main/java/com/example/jetnews/ui/home/HomeScreen.kt +++ b/JetNews/app/src/main/java/com/example/jetnews/ui/home/HomeScreen.kt @@ -16,22 +16,22 @@ package com.example.jetnews.ui.home -import androidx.compose.foundation.Box import androidx.compose.foundation.Icon import androidx.compose.foundation.ScrollableColumn import androidx.compose.foundation.ScrollableRow import androidx.compose.foundation.Text import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredSize import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.Divider import androidx.compose.material.DrawerValue -import androidx.compose.material.EmphasisAmbient import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme @@ -45,9 +45,9 @@ import androidx.compose.material.TopAppBar import androidx.compose.material.rememberDrawerState import androidx.compose.material.rememberScaffoldState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedTask import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.launchInComposition import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -67,12 +67,12 @@ import com.example.jetnews.ui.Screen import com.example.jetnews.ui.SwipeToRefreshLayout import com.example.jetnews.ui.ThemedPreview import com.example.jetnews.ui.state.UiState -import com.example.jetnews.utils.launchUiStateProducer +import com.example.jetnews.utils.produceUiState import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking /** - * Stateful HomeScreen which manages state using [launchUiStateProducer] + * Stateful HomeScreen which manages state using [produceUiState] * * @param navigateTo (event) request navigation to [Screen] * @param postsRepository data source for this screen @@ -84,7 +84,7 @@ fun HomeScreen( postsRepository: PostsRepository, scaffoldState: ScaffoldState = rememberScaffoldState() ) { - val (postUiState, refreshPost, clearError) = launchUiStateProducer(postsRepository) { + val (postUiState, refreshPost, clearError) = produceUiState(postsRepository) { getPosts() } @@ -139,7 +139,7 @@ fun HomeScreen( // Show snackbar using a coroutine, when the coroutine is cancelled the snackbar will // automatically dismiss. This coroutine will cancel whenever posts.hasError changes, and // only start when posts.hasError is true (due to the above if-check). - launchInComposition(posts.hasError) { + LaunchedTask(posts.hasError) { val snackbarResult = scaffoldState.snackbarHostState.showSnackbar( message = errorMessage, actionLabel = retryMessage @@ -258,6 +258,9 @@ private fun HomeScreenErrorAndContent( TextButton(onClick = onRefresh, modifier.fillMaxSize()) { Text("Tap to load content", textAlign = TextAlign.Center) } + } else { + // there's currently an error showing, don't show any content + Box(modifier.fillMaxSize()) { /* empty screen */ } } } @@ -310,7 +313,7 @@ private fun FullScreenLoading() { */ @Composable private fun PostListTopSection(post: Post, navigateTo: (Screen) -> Unit) { - ProvideEmphasis(EmphasisAmbient.current.high) { + ProvideEmphasis(AmbientEmphasisLevels.current.high) { Text( modifier = Modifier.padding(start = 16.dp, top = 16.dp, end = 16.dp), text = "Top stories for you", @@ -362,7 +365,7 @@ private fun PostListPopularSection( navigateTo: (Screen) -> Unit ) { Column { - ProvideEmphasis(EmphasisAmbient.current.high) { + ProvideEmphasis(AmbientEmphasisLevels.current.high) { Text( modifier = Modifier.padding(16.dp), text = "Popular on Jetnews", diff --git a/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCardTop.kt b/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCardTop.kt index 18ec983327..0f44728468 100644 --- a/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCardTop.kt +++ b/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCardTop.kt @@ -24,7 +24,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredHeight -import androidx.compose.material.EmphasisAmbient +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis import androidx.compose.runtime.Composable @@ -54,7 +54,7 @@ fun PostCardTop(post: Post, modifier: Modifier = Modifier) { } Spacer(Modifier.preferredHeight(16.dp)) - val emphasisLevels = EmphasisAmbient.current + val emphasisLevels = AmbientEmphasisLevels.current ProvideEmphasis(emphasisLevels.high) { Text( text = post.title, diff --git a/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCardYourNetwork.kt b/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCardYourNetwork.kt index 520a861642..c04c08cef1 100644 --- a/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCardYourNetwork.kt +++ b/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCardYourNetwork.kt @@ -24,8 +24,8 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredHeight import androidx.compose.foundation.layout.preferredSize +import androidx.compose.material.AmbientEmphasisLevels 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 @@ -62,7 +62,7 @@ fun PostCardPopular( .fillMaxWidth() ) Column(modifier = Modifier.padding(16.dp)) { - val emphasisLevels = EmphasisAmbient.current + val emphasisLevels = AmbientEmphasisLevels.current ProvideEmphasis(emphasisLevels.high) { Text( text = post.title, diff --git a/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCards.kt b/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCards.kt index 6aa3b31b7d..c161c9fb43 100644 --- a/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCards.kt +++ b/JetNews/app/src/main/java/com/example/jetnews/ui/home/PostCards.kt @@ -25,7 +25,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredSize -import androidx.compose.material.EmphasisAmbient +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.IconToggleButton import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis @@ -52,7 +52,7 @@ fun AuthorAndReadTime( modifier: Modifier = Modifier ) { Row(modifier) { - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { val textStyle = MaterialTheme.typography.body2 Text( text = post.metadata.author.name, @@ -79,7 +79,7 @@ fun PostImage(post: Post, modifier: Modifier = Modifier) { @Composable fun PostTitle(post: Post) { - ProvideEmphasis(EmphasisAmbient.current.high) { + ProvideEmphasis(AmbientEmphasisLevels.current.high) { Text(post.title, style = MaterialTheme.typography.subtitle1) } } @@ -118,7 +118,7 @@ fun PostCardHistory(post: Post, navigateTo: (Screen) -> Unit) { modifier = Modifier.padding(end = 16.dp) ) Column(Modifier.weight(1f)) { - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { Text( text = "BASED ON YOUR HISTORY", style = MaterialTheme.typography.overline @@ -130,7 +130,7 @@ fun PostCardHistory(post: Post, navigateTo: (Screen) -> Unit) { modifier = Modifier.padding(top = 4.dp) ) } - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { Icon(asset = Icons.Filled.MoreVert) } } diff --git a/JetNews/app/src/main/java/com/example/jetnews/ui/interests/InterestsScreen.kt b/JetNews/app/src/main/java/com/example/jetnews/ui/interests/InterestsScreen.kt index 5c45bbddc1..42f321532c 100644 --- a/JetNews/app/src/main/java/com/example/jetnews/ui/interests/InterestsScreen.kt +++ b/JetNews/app/src/main/java/com/example/jetnews/ui/interests/InterestsScreen.kt @@ -16,13 +16,14 @@ package com.example.jetnews.ui.interests -import androidx.compose.foundation.Box import androidx.compose.foundation.Icon import androidx.compose.foundation.Image import androidx.compose.foundation.ScrollableColumn import androidx.compose.foundation.Text +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredSize import androidx.compose.foundation.selection.toggleable @@ -59,7 +60,7 @@ import com.example.jetnews.data.interests.impl.FakeInterestsRepository import com.example.jetnews.ui.AppDrawer import com.example.jetnews.ui.Screen import com.example.jetnews.ui.ThemedPreview -import com.example.jetnews.utils.launchUiStateProducer +import com.example.jetnews.utils.produceUiState import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -82,7 +83,7 @@ enum class Sections(val title: String) { class TabContent(val section: Sections, val content: @Composable () -> Unit) /** - * Stateful InterestsScreen manages state using [launchUiStateProducer] + * Stateful InterestsScreen manages state using [produceUiState] * * @param navigateTo (event) request navigation to [Screen] * @param scaffoldState (state) state for screen Scaffold @@ -101,7 +102,7 @@ fun InterestsScreen( // Describe the screen sections here since each section needs 2 states and 1 event. // Pass them to the stateless InterestsScreen using a tabContent. val topicsSection = TabContent(Sections.Topics) { - val (topics) = launchUiStateProducer(interestsRepository) { + val (topics) = produceUiState(interestsRepository) { getTopics() } // collectAsState will read a [Flow] in Compose @@ -114,7 +115,7 @@ fun InterestsScreen( } val peopleSection = TabContent(Sections.People) { - val (people) = launchUiStateProducer(interestsRepository) { + val (people) = produceUiState(interestsRepository) { getPeople() } val selectedPeople by interestsRepository.observePeopleSelected().collectAsState(setOf()) @@ -126,7 +127,7 @@ fun InterestsScreen( } val publicationSection = TabContent(Sections.Publications) { - val (publications) = launchUiStateProducer(interestsRepository) { + val (publications) = produceUiState(interestsRepository) { getPublications() } val selectedPublications by interestsRepository.observePublicationSelected().collectAsState(setOf()) @@ -356,11 +357,11 @@ private fun TopicItem(itemTitle: String, selected: Boolean, onToggle: () -> Unit Text( text = itemTitle, modifier = Modifier - .weight(1f) .align(Alignment.CenterVertically) .padding(16.dp), style = MaterialTheme.typography.subtitle1 ) + Spacer(Modifier.weight(1f)) SelectTopicButton( modifier = Modifier.align(Alignment.CenterVertically), selected = selected diff --git a/JetNews/app/src/main/java/com/example/jetnews/ui/interests/SelectTopicButton.kt b/JetNews/app/src/main/java/com/example/jetnews/ui/interests/SelectTopicButton.kt index 684795ac1d..fcad3396fe 100644 --- a/JetNews/app/src/main/java/com/example/jetnews/ui/interests/SelectTopicButton.kt +++ b/JetNews/app/src/main/java/com/example/jetnews/ui/interests/SelectTopicButton.kt @@ -20,7 +20,7 @@ import androidx.compose.foundation.Icon import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredSize import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.EmphasisAmbient +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis import androidx.compose.material.Surface @@ -49,7 +49,7 @@ fun SelectTopicButton( shape = CircleShape, modifier = modifier.preferredSize(36.dp, 36.dp) ) { - ProvideEmphasis(EmphasisAmbient.current.high) { + ProvideEmphasis(AmbientEmphasisLevels.current.high) { Icon(icon) } } diff --git a/JetNews/app/src/main/java/com/example/jetnews/utils/LaunchUiStateProducer.kt b/JetNews/app/src/main/java/com/example/jetnews/utils/ProduceUiState.kt similarity index 68% rename from JetNews/app/src/main/java/com/example/jetnews/utils/LaunchUiStateProducer.kt rename to JetNews/app/src/main/java/com/example/jetnews/utils/ProduceUiState.kt index f85dcd21ac..94d6ac1578 100644 --- a/JetNews/app/src/main/java/com/example/jetnews/utils/LaunchUiStateProducer.kt +++ b/JetNews/app/src/main/java/com/example/jetnews/utils/ProduceUiState.kt @@ -18,23 +18,23 @@ package com.example.jetnews.utils import androidx.compose.runtime.Composable import androidx.compose.runtime.State -import androidx.compose.runtime.launchInComposition -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import com.example.jetnews.data.Result import com.example.jetnews.ui.state.UiState import com.example.jetnews.ui.state.copyWithResult import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.launch /** - * Result object for [launchUiStateProducer]. + * Result object for [produceUiState]. * * It is intended that you destructure this class at the call site. Here is an example usage that * calls dataSource.loadData() and then displays a UI based on the result. * * ``` - * val (result, onRefresh, onClearError) = launchUiStateProducer(dataSource) { loadData() } + * val (result, onRefresh, onClearError) = produceUiState(dataSource) { loadData() } * Text(result.value) * Button(onClick = onRefresh) { Text("Refresh" } * Button(onClick = onClearError) { Text("Clear loading error") } @@ -62,7 +62,7 @@ data class ProducerResult( * calls dataSource.loadData() and then displays a UI based on the result. * * ``` - * val (result, onRefresh, onClearError) = launchUiStateProducer(dataSource) { loadData() } + * val (result, onRefresh, onClearError) = produceUiState(dataSource) { loadData() } * Text(result.value) * Button(onClick = onRefresh) { Text("Refresh" } * Button(onClick = onClearError) { Text("Clear loading error") } @@ -75,10 +75,10 @@ data class ProducerResult( * @return data state, onRefresh event, and onClearError event */ @Composable -fun launchUiStateProducer( +fun produceUiState( producer: Producer, block: suspend Producer.() -> Result -): ProducerResult> = launchUiStateProducer(producer, Unit, block) +): ProducerResult> = produceUiState(producer, Unit, block) /** * Launch a coroutine to create refreshable [UiState] from a suspending producer. @@ -91,7 +91,7 @@ fun launchUiStateProducer( * calls dataSource.loadData(resourceId) and then displays a UI based on the result. * * ``` - * val (result, onRefresh, onClearError) = launchUiStateProducer(dataSource, resourceId) { + * val (result, onRefresh, onClearError) = produceUiState(dataSource, resourceId) { * loadData(resourceId) * } * Text(result.value) @@ -108,42 +108,44 @@ fun launchUiStateProducer( */ @OptIn(ExperimentalCoroutinesApi::class) @Composable -fun launchUiStateProducer( +fun produceUiState( producer: Producer, key: Any?, block: suspend Producer.() -> Result ): ProducerResult> { - val producerState = remember { mutableStateOf(UiState(loading = true)) } - // posting to this channel will trigger a single refresh val refreshChannel = remember { Channel(Channel.CONFLATED) } + // posting to this channel will clear the current error condition (if any) + val errorClearChannel = remember { Channel(Channel.CONFLATED) } - // event for caller to trigger a refresh - val refresh: () -> Unit = { refreshChannel.offer(Unit) } - - // event for caller to clear any errors on the current result (useful for transient error - // displays) - val clearError: () -> Unit = { - producerState.value = producerState.value.copy(exception = null) - } - - // whenever Producer or v1 changes, launch a new coroutine to call block() and refresh whenever - // the onRefresh callback is called - launchInComposition(producer, key) { - // whenever the coroutine restarts, clear the previous result immediately as they are no - // longer valid - producerState.value = UiState(loading = true) - // force a refresh on coroutine restart + val result = produceState(UiState(loading = true), producer, key) { + // whenever the coroutine restarts from producer or key changes, clear the previous result + // immediately and force refresh + value = UiState(loading = true) refreshChannel.send(Unit) - // whenever a refresh is triggered, call block again. This for-loop will suspend when - // refreshChannel is empty, and resume when the next value is offered or sent to the - // channel. - // This for-loop will loop until the [launchInComposition] coroutine is cancelled. + // launch a new coroutine to handle errorClear events async + launch { + // This for-loop will loop until the [produceState] coroutine is cancelled. + for (clearEvent in errorClearChannel) { + // This for-loop will suspend when errorClearChanel is empty, and resume when the + // next value is offered or sent to the chanel. + value = value.copy(exception = null) + } + } + + // This for-loop will loop until the [produceState] coroutine is cancelled. for (refreshEvent in refreshChannel) { - producerState.value = producerState.value.copy(loading = true) - producerState.value = producerState.value.copyWithResult(producer.block()) + // whenever a refresh is triggered, call block again. This for-loop will suspend when + // refreshChannel is empty, and resume when the next value is offered or sent to the + // channel. + value = value.copy(loading = true) + value = value.copyWithResult(producer.block()) } } - return ProducerResult(producerState, refresh, clearError) + return ProducerResult( + result = result, + onRefresh = { refreshChannel.offer(Unit) }, + onClearError = { errorClearChannel.offer(Unit) } + ) } diff --git a/JetNews/build.gradle b/JetNews/build.gradle index 881a790fa5..acfb92e0ed 100644 --- a/JetNews/build.gradle +++ b/JetNews/build.gradle @@ -16,7 +16,7 @@ buildscript { ext.kotlin_version = '1.4.10' - ext.compose_version = '1.0.0-alpha03' + ext.compose_version = '1.0.0-alpha05' repositories { google() @@ -50,20 +50,4 @@ subprojects { licenseHeaderFile rootProject.file('spotless/copyright.kt') } } -} - -// JetNews uses Compose alpha03 and Android Gradle Plugin 4.2.0-alpha13 which are incompatible -// TODO: Remove this workaround when updating to >alpha04 -subprojects { - configurations.configureEach { - resolutionStrategy.eachDependency { DependencyResolveDetails details -> - def group = details.requested.group - def module = details.requested.module.name - def version = details.requested.version - - if (group == 'androidx.compose.compiler' && module == 'compiler') { - details.useTarget("androidx.compose:compose-compiler:$version") - } - } - } } \ No newline at end of file diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/Home.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/Home.kt index c89c293dd5..2d5968fa24 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/Home.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/Home.kt @@ -34,7 +34,7 @@ import androidx.compose.foundation.layout.preferredHeight import androidx.compose.foundation.layout.preferredHeightIn import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.EmphasisAmbient +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis @@ -48,9 +48,9 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.AccountCircle import androidx.compose.material.icons.filled.Search import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedTask import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.launchInComposition import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -119,7 +119,7 @@ fun HomeAppBar( }, backgroundColor = backgroundColor, actions = { - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { IconButton( onClick = { /* TODO: Open search */ }, icon = { Icon(Icons.Filled.Search) } @@ -170,7 +170,7 @@ fun HomeContent( // When the selected image url changes, call updateColorsFromImageUrl() or reset() if (selectedImageUrl != null) { - launchInComposition(selectedImageUrl) { + LaunchedTask(selectedImageUrl) { dominantColorState.updateColorsFromImageUrl(selectedImageUrl) } } else { @@ -338,7 +338,7 @@ private fun FollowedPodcastCarouselItem( ) } - ProvideEmphasis(EmphasisAmbient.current.high) { + ProvideEmphasis(AmbientEmphasisLevels.current.high) { ToggleFollowPodcastIconButton( onClick = onUnfollowedClick, isFollowed = true, /* All podcasts are followed in this feed */ @@ -348,7 +348,7 @@ private fun FollowedPodcastCarouselItem( } if (lastEpisodeDate != null) { - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { Text( text = lastUpdated(lastEpisodeDate), style = MaterialTheme.typography.caption, diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/category/PodcastCategory.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/category/PodcastCategory.kt index 8b9aac5b67..7b110f634d 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/category/PodcastCategory.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/category/PodcastCategory.kt @@ -16,11 +16,11 @@ package com.example.jetcaster.ui.home.category +import androidx.compose.foundation.AmbientContentColor import androidx.compose.foundation.Icon import androidx.compose.foundation.Image import androidx.compose.foundation.Text import androidx.compose.foundation.clickable -import androidx.compose.foundation.contentColor import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ConstraintLayout @@ -36,8 +36,8 @@ import androidx.compose.foundation.layout.preferredWidth import androidx.compose.foundation.lazy.ExperimentalLazyDsl import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyRowForIndexed +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.Divider -import androidx.compose.material.EmphasisAmbient import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis @@ -166,7 +166,7 @@ fun EpisodeListItem( ) } - ProvideEmphasis(EmphasisAmbient.current.high) { + ProvideEmphasis(AmbientEmphasisLevels.current.high) { Text( text = episode.title, maxLines = 2, @@ -188,7 +188,7 @@ fun EpisodeListItem( val titleImageBarrier = createBottomBarrier(podcastTitle, image) - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { Text( text = podcast.title, maxLines = 2, @@ -208,11 +208,11 @@ fun EpisodeListItem( ) } - ProvideEmphasis(EmphasisAmbient.current.high) { + ProvideEmphasis(AmbientEmphasisLevels.current.high) { Image( asset = Icons.Rounded.PlayCircleFilled, contentScale = ContentScale.Fit, - colorFilter = ColorFilter.tint(contentColor()), + colorFilter = ColorFilter.tint(AmbientContentColor.current), modifier = Modifier .clickable(indication = RippleIndication(bounded = false, radius = 24.dp)) { /* TODO */ @@ -226,7 +226,7 @@ fun EpisodeListItem( ) } - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { Text( text = when { episode.duration != null -> { @@ -245,11 +245,14 @@ fun EpisodeListItem( overflow = TextOverflow.Ellipsis, style = MaterialTheme.typography.caption, modifier = Modifier.constrainAs(date) { - start.linkTo(playIcon.end, margin = 12.dp) - end.linkTo(addPlaylist.start, margin = 16.dp) centerVerticallyTo(playIcon) - - width = Dimension.fillToConstraints + linkTo( + start = playIcon.end, + startMargin = 12.dp, + end = addPlaylist.start, + endMargin = 16.dp, + bias = 0f // float this towards the start + ) } ) @@ -323,7 +326,7 @@ private fun TopPodcastRowItem( ) } - ProvideEmphasis(EmphasisAmbient.current.high) { + ProvideEmphasis(AmbientEmphasisLevels.current.high) { ToggleFollowPodcastIconButton( onClick = onToggleFollowClicked, isFollowed = isFollowed, @@ -332,7 +335,7 @@ private fun TopPodcastRowItem( } } - ProvideEmphasis(EmphasisAmbient.current.high) { + ProvideEmphasis(AmbientEmphasisLevels.current.high) { Text( text = podcastTitle, style = MaterialTheme.typography.body2, diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/util/Buttons.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/util/Buttons.kt index aa4e8a56ec..103e51ca33 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/util/Buttons.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/util/Buttons.kt @@ -17,11 +17,11 @@ package com.example.jetcaster.util import androidx.compose.animation.animate +import androidx.compose.foundation.AmbientContentColor import androidx.compose.foundation.Icon import androidx.compose.foundation.background -import androidx.compose.foundation.contentColor import androidx.compose.foundation.layout.padding -import androidx.compose.material.EmphasisAmbient +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.icons.Icons @@ -51,8 +51,8 @@ fun ToggleFollowPodcastIconButton( }, tint = animate( when { - isFollowed -> contentColor() - else -> EmphasisAmbient.current.high.applyEmphasis(Color.Black) + isFollowed -> AmbientContentColor.current + else -> AmbientEmphasisLevels.current.high.applyEmphasis(Color.Black) } ), modifier = Modifier diff --git a/Jetcaster/build.gradle b/Jetcaster/build.gradle index d66ba8d8b3..f3bb7bd530 100644 --- a/Jetcaster/build.gradle +++ b/Jetcaster/build.gradle @@ -43,10 +43,9 @@ subprojects { mavenCentral() jcenter() - if (!Libs.AndroidX.Compose.snapshot.isEmpty()) { - maven { - url "https://androidx.dev/snapshots/builds/${Libs.AndroidX.Compose.snapshot}/artifacts/ui/repository/" - } + // Jetpack Compose SNAPSHOTs + if (Libs.AndroidX.Compose.version.endsWith("SNAPSHOT")) { + maven { url Libs.AndroidX.Compose.snapshotUrl } } maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } diff --git a/Jetcaster/buildSrc/src/main/java/com/example/jetcaster/buildsrc/dependencies.kt b/Jetcaster/buildSrc/src/main/java/com/example/jetcaster/buildsrc/dependencies.kt index f6e6e94901..1d7000df8c 100644 --- a/Jetcaster/buildSrc/src/main/java/com/example/jetcaster/buildsrc/dependencies.kt +++ b/Jetcaster/buildSrc/src/main/java/com/example/jetcaster/buildsrc/dependencies.kt @@ -29,12 +29,12 @@ object Libs { const val material = "com.google.android.material:material:1.1.0" object Accompanist { - private const val version = "0.3.0" + private const val version = "0.3.1" const val coil = "dev.chrisbanes.accompanist:accompanist-coil:$version" } object Kotlin { - private const val version = "1.4.0" + private const val version = "1.4.10" const val stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version" const val gradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$version" const val extensions = "org.jetbrains.kotlin:kotlin-android-extensions:$version" @@ -61,8 +61,12 @@ object Libs { const val coreKtx = "androidx.core:core-ktx:1.5.0-alpha02" object Compose { - const val snapshot = "" - const val version = "1.0.0-alpha04" + private const val snapshot = "" + const val version = "1.0.0-alpha05" + + @get:JvmStatic + val snapshotUrl: String + get() = "https://androidx.dev/snapshots/builds/$snapshot/artifacts/ui/repository/" const val runtime = "androidx.compose.runtime:runtime:$version" const val foundation = "androidx.compose.foundation:foundation:${version}" diff --git a/Jetchat/app/build.gradle b/Jetchat/app/build.gradle index ab392af6a3..94ea28d959 100644 --- a/Jetchat/app/build.gradle +++ b/Jetchat/app/build.gradle @@ -67,6 +67,13 @@ android { buildFeatures { compose true + + // Disable unused AGP features + buildConfig false + aidl false + renderScript false + resValues false + shaders false } composeOptions { diff --git a/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/Conversation.kt b/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/Conversation.kt index 8850dbc407..efbe18eab7 100644 --- a/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/Conversation.kt +++ b/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/Conversation.kt @@ -41,8 +41,8 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.LastBaseline +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.Divider -import androidx.compose.material.EmphasisAmbient import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis import androidx.compose.material.Surface @@ -138,7 +138,7 @@ fun ChannelNameBar( ) // Number of members // TODO: Multiple emphasis layers - https://issuetracker.google.com/159017896 - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text( text = stringResource(R.string.members, channelMembers), style = MaterialTheme.typography.caption, @@ -148,7 +148,7 @@ fun ChannelNameBar( } }, actions = { - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { // Search icon Icon( asset = Icons.Outlined.Search, @@ -311,7 +311,7 @@ fun AuthorAndTextMessage( private fun AuthorNameTimestamp(msg: Message) { // Combine author and timestamp for a11y. Row(modifier = Modifier.semantics(mergeAllDescendants = true) {}) { - ProvideEmphasis(emphasis = EmphasisAmbient.current.high) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.high) { Text( text = msg.author, style = MaterialTheme.typography.subtitle1, @@ -321,7 +321,7 @@ private fun AuthorNameTimestamp(msg: Message) { ) } Spacer(modifier = Modifier.preferredWidth(8.dp)) - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text( text = msg.timestamp, style = MaterialTheme.typography.caption, @@ -338,7 +338,7 @@ private val LastChatBubbleShape = RoundedCornerShape(0.dp, 8.dp, 8.dp, 8.dp) fun DayHeader(dayString: String) { Row(modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp).preferredHeight(16.dp)) { DayHeaderLine() - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text( text = dayString, modifier = Modifier.padding(horizontal = 16.dp), @@ -373,7 +373,7 @@ fun ChatItemBubble( val bubbleShape = if (lastMessageByAuthor) LastChatBubbleShape else ChatBubbleShape Column { Surface(color = backgroundBubbleColor, shape = bubbleShape) { - ProvideEmphasis(emphasis = EmphasisAmbient.current.high) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.high) { ClickableMessage( message = message ) diff --git a/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/MessageFormatter.kt b/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/MessageFormatter.kt index 01061f7231..a0772df2e3 100644 --- a/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/MessageFormatter.kt +++ b/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/MessageFormatter.kt @@ -85,7 +85,7 @@ fun messageFormatter( if (stringAnnotation != null) { val (item, start, end, tag) = stringAnnotation - addStringAnnotation(scope = tag, start = start, end = end, annotation = item) + addStringAnnotation(tag = tag, start = start, end = end, annotation = item) } cursorPosition = token.range.last + 1 diff --git a/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/UserInput.kt b/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/UserInput.kt index be9a53e93a..a0a1dbf93b 100644 --- a/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/UserInput.kt +++ b/Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/UserInput.kt @@ -19,6 +19,8 @@ package com.example.compose.jetchat.conversation import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.fadeIn +import androidx.compose.foundation.AmbientContentColor +import androidx.compose.foundation.AmbientTextStyle import androidx.compose.foundation.BaseTextField import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.ExperimentalFoundationApi @@ -28,7 +30,6 @@ import androidx.compose.foundation.ScrollableRow import androidx.compose.foundation.Text import androidx.compose.foundation.clickable import androidx.compose.foundation.contentColor -import androidx.compose.foundation.currentTextStyle import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -44,10 +45,10 @@ import androidx.compose.foundation.layout.sizeIn import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.FirstBaseline +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.Button import androidx.compose.material.ButtonConstants import androidx.compose.material.Divider -import androidx.compose.material.EmphasisAmbient import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis @@ -226,13 +227,13 @@ fun FunctionalityNotAvailablePanel() { verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { - ProvideEmphasis(emphasis = EmphasisAmbient.current.high) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.high) { Text( text = stringResource(id = R.string.not_available), style = MaterialTheme.typography.subtitle1 ) } - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text( text = stringResource(id = R.string.not_available_subtitle), modifier = Modifier.relativePaddingFrom(FirstBaseline, before = 32.dp), @@ -313,7 +314,7 @@ private fun UserInputSelector( disabledColor = MaterialTheme.colors.surface ) val disabledContentColor = - EmphasisAmbient.current.disabled.applyEmphasis(MaterialTheme.colors.onSurface) + AmbientEmphasisLevels.current.disabled.applyEmphasis(MaterialTheme.colors.onSurface) val contentColor = ButtonConstants.defaultButtonContentColor( enabled = sendMessageEnabled, defaultColor = contentColorFor(backgroundColor), @@ -352,8 +353,8 @@ private fun InputSelectorButton( onClick = onClick, modifier = Modifier.semantics { accessibilityLabel = description } ) { - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { - val tint = if (selected) MaterialTheme.colors.primary else contentColor() + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { + val tint = if (selected) MaterialTheme.colors.primary else AmbientContentColor.current Icon( icon, tint = tint, @@ -426,7 +427,7 @@ private fun UserInputText( ) val disableContentColor = - EmphasisAmbient.current.disabled.applyEmphasis(MaterialTheme.colors.onSurface) + AmbientEmphasisLevels.current.disabled.applyEmphasis(MaterialTheme.colors.onSurface) if (textFieldValue.text.isEmpty() && !focusState) { Text( modifier = Modifier @@ -533,7 +534,7 @@ fun EmojiTable( .sizeIn(minWidth = 42.dp, minHeight = 42.dp) .padding(8.dp), text = emoji, - style = currentTextStyle().copy( + style = AmbientTextStyle.current.copy( fontSize = 18.sp, textAlign = TextAlign.Center ) diff --git a/Jetchat/app/src/main/java/com/example/compose/jetchat/profile/Profile.kt b/Jetchat/app/src/main/java/com/example/compose/jetchat/profile/Profile.kt index 51ca717d8c..c1ecc968f0 100644 --- a/Jetchat/app/src/main/java/com/example/compose/jetchat/profile/Profile.kt +++ b/Jetchat/app/src/main/java/com/example/compose/jetchat/profile/Profile.kt @@ -34,8 +34,8 @@ import androidx.compose.foundation.layout.preferredHeight import androidx.compose.foundation.layout.preferredHeightIn import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.rememberScrollState +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.Divider -import androidx.compose.material.EmphasisAmbient import androidx.compose.material.FloatingActionButton import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis @@ -75,7 +75,7 @@ fun ProfileScreen(userData: ProfileScreenState, onNavIconPressed: () -> Unit = { onNavIconPressed = onNavIconPressed, title = { }, actions = { - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { // More icon Icon( asset = Icons.Outlined.MoreVert, @@ -152,7 +152,7 @@ private fun NameAndPosition( @Composable private fun Name(userData: ProfileScreenState, modifier: Modifier = Modifier) { - ProvideEmphasis(emphasis = EmphasisAmbient.current.high) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.high) { Text( text = userData.name, modifier = modifier, @@ -163,7 +163,7 @@ private fun Name(userData: ProfileScreenState, modifier: Modifier = Modifier) { @Composable private fun Position(userData: ProfileScreenState, modifier: Modifier = Modifier) { - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text( text = userData.position, modifier = modifier, @@ -207,7 +207,7 @@ private fun ProfileHeader( fun ProfileProperty(label: String, value: String, isLink: Boolean = false) { Column(modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)) { Divider() - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text( text = label, modifier = Modifier.baselineHeight(24.dp), @@ -219,7 +219,7 @@ fun ProfileProperty(label: String, value: String, isLink: Boolean = false) { } else { MaterialTheme.typography.body1 } - ProvideEmphasis(emphasis = EmphasisAmbient.current.high) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.high) { Text( text = value, modifier = Modifier.baselineHeight(24.dp), diff --git a/Jetchat/build.gradle b/Jetchat/build.gradle index 0e0a382c3a..64522a765b 100644 --- a/Jetchat/build.gradle +++ b/Jetchat/build.gradle @@ -16,6 +16,7 @@ import com.example.compose.jetchat.buildsrc.Libs +import com.example.compose.jetchat.buildsrc.Urls import com.example.compose.jetchat.buildsrc.Versions buildscript { @@ -41,12 +42,8 @@ subprojects { jcenter() if (!Libs.AndroidX.Compose.snapshot.isEmpty()) { - maven { - url "https://androidx.dev/snapshots/builds/${Libs.AndroidX.Compose.snapshot}/artifacts/ui/repository/" - } + maven { url Urls.composeSnapshotRepo } } - - maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } } apply plugin: 'com.diffplug.spotless' diff --git a/Jetchat/buildSrc/src/main/java/com/example/compose/jetchat/buildsrc/dependencies.kt b/Jetchat/buildSrc/src/main/java/com/example/compose/jetchat/buildsrc/dependencies.kt index e62b599b8c..684053d3d8 100644 --- a/Jetchat/buildSrc/src/main/java/com/example/compose/jetchat/buildsrc/dependencies.kt +++ b/Jetchat/buildSrc/src/main/java/com/example/compose/jetchat/buildsrc/dependencies.kt @@ -29,7 +29,7 @@ object Libs { const val material = "com.google.android.material:material:1.1.0" object Kotlin { - private const val version = "1.4.0" + private const val version = "1.4.10" const val stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version" const val gradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$version" const val extensions = "org.jetbrains.kotlin:kotlin-android-extensions:$version" @@ -48,9 +48,8 @@ object Libs { object Compose { const val snapshot = "" - const val version = "1.0.0-alpha04" + const val version = "1.0.0-alpha05" - const val core = "androidx.compose.ui:ui:$version" const val foundation = "androidx.compose.foundation:foundation:$version" const val layout = "androidx.compose.foundation:foundation-layout:$version" const val material = "androidx.compose.material:material:$version" @@ -89,3 +88,8 @@ object Libs { } } } + +object Urls { + const val composeSnapshotRepo = "https://androidx-dev-prod.appspot.com/snapshots/builds/" + + "${Libs.AndroidX.Compose.snapshot}/artifacts/ui/repository/" +} diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Gradient.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Gradient.kt index 262739a753..d2e022efb5 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Gradient.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Gradient.kt @@ -34,7 +34,7 @@ import androidx.compose.ui.graphics.HorizontalGradient import androidx.compose.ui.graphics.LinearGradient import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.TileMode -import androidx.compose.ui.onPositioned +import androidx.compose.ui.onSizeChanged import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp @@ -138,7 +138,7 @@ fun Modifier.gradientBorder( ) = composed { var size by remember { mutableStateOf(IntSize.Zero) } val gradient = remember(colors, size) { brushProvider(colors, size) } - val sizeProvider = onPositioned { size = it.size } + val sizeProvider = onSizeChanged { size = it } sizeProvider then border( width = borderSize, brush = gradient, diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Scaffold.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Scaffold.kt index 128fede4a0..63c514070f 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Scaffold.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Scaffold.kt @@ -28,6 +28,7 @@ import androidx.compose.material.SnackbarHost import androidx.compose.material.SnackbarHostState import androidx.compose.material.rememberScaffoldState import androidx.compose.runtime.Composable +import androidx.compose.runtime.emptyContent import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape @@ -42,10 +43,10 @@ import com.example.jetsnack.ui.theme.JetsnackTheme fun JetsnackScaffold( modifier: Modifier = Modifier, scaffoldState: ScaffoldState = rememberScaffoldState(), - topBar: @Composable (() -> Unit)? = null, - bottomBar: @Composable (() -> Unit)? = null, + topBar: @Composable (() -> Unit) = emptyContent(), + bottomBar: @Composable (() -> Unit) = emptyContent(), snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) }, - floatingActionButton: @Composable (() -> Unit)? = null, + floatingActionButton: @Composable (() -> Unit) = emptyContent(), floatingActionButtonPosition: FabPosition = FabPosition.End, isFloatingActionButtonDocked: Boolean = false, drawerContent: @Composable (ColumnScope.() -> Unit)? = null, diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt index e09f7218f9..2878f3db1e 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt @@ -32,6 +32,7 @@ import androidx.compose.foundation.layout.preferredHeight import androidx.compose.foundation.layout.preferredHeightIn import androidx.compose.foundation.layout.preferredSize import androidx.compose.foundation.layout.preferredWidth +import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.lazy.LazyRowFor import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape @@ -87,7 +88,9 @@ fun SnackCollection( color = JetsnackTheme.colors.brand, maxLines = 1, overflow = TextOverflow.Ellipsis, - modifier = Modifier.weight(1f) + modifier = Modifier + .weight(1f) + .wrapContentWidth(Alignment.Start) ) IconButton( onClick = { /* todo */ }, diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Surface.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Surface.kt index 94a3309059..bfc6172047 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Surface.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Surface.kt @@ -16,8 +16,8 @@ package com.example.jetsnack.ui.components +import androidx.compose.foundation.AmbientContentColor import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.ContentColorAmbient import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box @@ -38,7 +38,7 @@ import kotlin.math.ln /** * An alternative to [androidx.compose.material.Surface] utilizing - * [com.example.jetsnack.ui.theme.JetsnackColorPalette] + * [com.example.jetsnack.ui.theme.JetsnackColors] */ @Composable fun JetsnackSurface( @@ -60,7 +60,7 @@ fun JetsnackSurface( ) .clip(shape) ) { - Providers(ContentColorAmbient provides contentColor, children = content) + Providers(AmbientContentColor provides contentColor, children = content) } } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt index c96b7697a0..0254320b27 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Results.kt @@ -23,7 +23,6 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.ChainStyle import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ConstraintLayout -import androidx.compose.foundation.layout.Dimension import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -110,7 +109,7 @@ private fun SearchResult( bottom = parent.bottom, bottomMargin = 16.dp ) - linkTo(start = parent.start, end = name.start) + start.linkTo(parent.start) } ) Text( @@ -122,9 +121,9 @@ private fun SearchResult( start = image.end, startMargin = 16.dp, end = add.start, - endMargin = 16.dp + endMargin = 16.dp, + bias = 0f ) - width = Dimension.fillToConstraints } ) Text( @@ -132,8 +131,13 @@ private fun SearchResult( style = MaterialTheme.typography.body1, color = JetsnackTheme.colors.textHelp, modifier = Modifier.constrainAs(tag) { - linkTo(start = name.start, end = name.end) - width = Dimension.fillToConstraints + linkTo( + start = image.end, + startMargin = 16.dp, + end = add.start, + endMargin = 16.dp, + bias = 0f + ) } ) Spacer( @@ -148,8 +152,13 @@ private fun SearchResult( style = MaterialTheme.typography.subtitle1, color = JetsnackTheme.colors.textPrimary, modifier = Modifier.constrainAs(price) { - linkTo(start = name.start, end = name.end) - width = Dimension.fillToConstraints + linkTo( + start = image.end, + startMargin = 16.dp, + end = add.start, + endMargin = 16.dp, + bias = 0f + ) } ) JetsnackButton( @@ -160,7 +169,7 @@ private fun SearchResult( .preferredSize(36.dp) .constrainAs(add) { linkTo(top = parent.top, bottom = parent.bottom) - linkTo(start = name.end, end = parent.end) + end.linkTo(parent.end) } ) { Icon(Icons.Outlined.Add) diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt index 8701960fe3..970e8ef761 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt @@ -21,7 +21,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Icon import androidx.compose.foundation.Text import androidx.compose.foundation.contentColor -import androidx.compose.foundation.currentTextStyle import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -41,9 +40,9 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.ArrowBack import androidx.compose.material.icons.outlined.Search import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedTask import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue -import androidx.compose.runtime.launchInComposition import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -88,7 +87,7 @@ fun Search( ) JetsnackDivider() - launchInComposition(state.query.text) { + LaunchedTask(state.query.text) { state.searching = true state.searchResults = SearchRepo.search(state.query.text) state.searching = false @@ -204,7 +203,6 @@ private fun SearchBar( BaseTextField( value = query, onValueChange = onQueryChange, - textStyle = currentTextStyle().copy(color = contentColor()), imeAction = ImeAction.Search, onImeActionPerformed = { /* todo */ }, cursorColor = JetsnackTheme.colors.textPrimary, diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Suggestions.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Suggestions.kt index c0415ee388..1caa70fbf8 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Suggestions.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Suggestions.kt @@ -23,41 +23,87 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredHeight import androidx.compose.foundation.layout.preferredHeightIn import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.foundation.lazy.LazyColumnFor +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.lazy.ExperimentalLazyDsl +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import androidx.ui.tooling.preview.Preview +import com.example.jetsnack.model.SearchRepo import com.example.jetsnack.model.SearchSuggestionGroup +import com.example.jetsnack.ui.components.JetsnackSurface import com.example.jetsnack.ui.theme.JetsnackTheme +@OptIn(ExperimentalLazyDsl::class) @Composable fun SearchSuggestions( suggestions: List, onSuggestionSelect: (String) -> Unit ) { - LazyColumnFor(suggestions) { suggestionGroup -> - Text( - text = suggestionGroup.name, - style = MaterialTheme.typography.h6, - color = JetsnackTheme.colors.textPrimary, - modifier = Modifier - .preferredHeightIn(min = 56.dp) - .padding(horizontal = 24.dp, vertical = 4.dp) - .wrapContentHeight() - ) - suggestionGroup.suggestions.forEach { suggestion -> - Text( - text = suggestion, - style = MaterialTheme.typography.subtitle1, - modifier = Modifier - .fillParentMaxWidth() - .preferredHeightIn(min = 48.dp) - .clickable { onSuggestionSelect(suggestion) } - .padding(start = 24.dp) - .wrapContentHeight() + LazyColumn { + suggestions.forEach { suggestionGroup -> + item { + SuggestionHeader(suggestionGroup.name) + } + items(suggestionGroup.suggestions) { suggestion -> + Suggestion( + suggestion = suggestion, + onSuggestionSelect = onSuggestionSelect, + modifier = Modifier.fillParentMaxWidth() + ) + } + item { + Spacer(Modifier.preferredHeight(4.dp)) + } + } + } +} + +@Composable +private fun SuggestionHeader( + name: String, + modifier: Modifier = Modifier +) { + Text( + text = name, + style = MaterialTheme.typography.h6, + color = JetsnackTheme.colors.textPrimary, + modifier = modifier + .preferredHeightIn(min = 56.dp) + .padding(horizontal = 24.dp, vertical = 4.dp) + .wrapContentHeight() + ) +} + +@Composable +private fun Suggestion( + suggestion: String, + onSuggestionSelect: (String) -> Unit, + modifier: Modifier = Modifier +) { + Text( + text = suggestion, + style = MaterialTheme.typography.subtitle1, + modifier = modifier + .preferredHeightIn(min = 48.dp) + .clickable { onSuggestionSelect(suggestion) } + .padding(start = 24.dp) + .wrapContentSize(Alignment.CenterStart) + ) +} + +@Preview +@Composable +fun PreviewSuggestions() { + JetsnackTheme { + JetsnackSurface { + SearchSuggestions( + suggestions = SearchRepo.getSuggestions(), + onSuggestionSelect = { } ) } - Spacer(Modifier.preferredHeight(4.dp)) } } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Theme.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Theme.kt index d5f0bc7f2d..030bbc087e 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Theme.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/theme/Theme.kt @@ -31,7 +31,7 @@ import androidx.compose.runtime.staticAmbientOf import androidx.compose.ui.graphics.Color import com.example.jetsnack.ui.utils.SysUiController -private val LightColorPalette = JetsnackColorPalette( +private val LightColorPalette = JetsnackColors( brand = Shadow5, uiBackground = Neutral0, uiBorder = Neutral4, @@ -53,7 +53,7 @@ private val LightColorPalette = JetsnackColorPalette( isDark = false ) -private val DarkColorPalette = JetsnackColorPalette( +private val DarkColorPalette = JetsnackColors( brand = Shadow1, uiBackground = Neutral8, uiBorder = Neutral3, @@ -103,15 +103,15 @@ fun JetsnackTheme( object JetsnackTheme { @Composable - val colors: JetsnackColorPalette - get() = JetsnackColorAmbient.current + val colors: JetsnackColors + get() = AmbientJetsnackColors.current } /** * Jetsnack custom Color Palette */ @Stable -class JetsnackColorPalette( +class JetsnackColors( gradient6_1: List, gradient6_2: List, gradient3_1: List, @@ -189,7 +189,7 @@ class JetsnackColorPalette( var isDark by mutableStateOf(isDark) private set - fun update(other: JetsnackColorPalette) { + fun update(other: JetsnackColors) { gradient6_1 = other.gradient6_1 gradient6_2 = other.gradient6_2 gradient3_1 = other.gradient3_1 @@ -220,15 +220,15 @@ class JetsnackColorPalette( @Composable fun ProvideJetsnackColors( - colors: JetsnackColorPalette, + colors: JetsnackColors, content: @Composable () -> Unit ) { val colorPalette = remember { colors } colorPalette.update(colors) - Providers(JetsnackColorAmbient provides colorPalette, children = content) + Providers(AmbientJetsnackColors provides colorPalette, children = content) } -private val JetsnackColorAmbient = staticAmbientOf { +private val AmbientJetsnackColors = staticAmbientOf { error("No JetsnackColorPalette provided") } diff --git a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/utils/Insets.kt b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/utils/Insets.kt index 53b4eb9579..72397b34a9 100644 --- a/Jetsnack/app/src/main/java/com/example/jetsnack/ui/utils/Insets.kt +++ b/Jetsnack/app/src/main/java/com/example/jetsnack/ui/utils/Insets.kt @@ -118,10 +118,10 @@ class Insets { internal set } -val InsetsAmbient = staticAmbientOf { DisplayInsets() } +val AmbientInsets = staticAmbientOf { DisplayInsets() } /** - * Applies any [WindowInsetsCompat] values to [InsetsAmbient], which are then available + * Applies any [WindowInsetsCompat] values to [AmbientInsets], which are then available * within [content]. * * @param consumeWindowInsets Whether to consume any [WindowInsetsCompat]s which are dispatched to @@ -165,7 +165,7 @@ fun ProvideDisplayInsets( } } - Providers(InsetsAmbient provides displayInsets) { + Providers(AmbientInsets provides displayInsets) { content() } } @@ -192,7 +192,7 @@ private fun Insets.updateFrom(windowInsets: WindowInsetsCompat, type: Int) { */ fun Modifier.systemBarsPadding(enabled: Boolean = true) = composed { insetsPadding( - insets = InsetsAmbient.current.systemBars, + insets = AmbientInsets.current.systemBars, left = enabled, top = enabled, right = enabled, @@ -205,7 +205,7 @@ fun Modifier.systemBarsPadding(enabled: Boolean = true) = composed { * of the content. */ fun Modifier.statusBarsPadding() = composed { - insetsPadding(insets = InsetsAmbient.current.statusBars, top = true) + insetsPadding(insets = AmbientInsets.current.statusBars, top = true) } /** @@ -226,7 +226,7 @@ fun Modifier.navigationBarsPadding( right: Boolean = true ) = composed { insetsPadding( - insets = InsetsAmbient.current.navigationBars, + insets = AmbientInsets.current.navigationBars, left = left, right = right, bottom = bottom @@ -260,7 +260,7 @@ fun Modifier.navigationBarsPadding( */ fun Modifier.statusBarsHeight(additional: Dp = 0.dp) = composed { InsetsSizeModifier( - insets = InsetsAmbient.current.statusBars, + insets = AmbientInsets.current.statusBars, heightSide = VerticalSide.Top, additionalHeight = additional ) @@ -312,7 +312,7 @@ inline fun Modifier.statusBarsHeight() = statusBarsHeightPlus(0.dp) */ fun Modifier.statusBarsHeightPlus(additional: Dp) = composed { InsetsSizeModifier( - insets = InsetsAmbient.current.statusBars, + insets = AmbientInsets.current.statusBars, heightSide = VerticalSide.Top, additionalHeight = additional ) @@ -364,7 +364,7 @@ inline fun Modifier.navigationBarsHeight() = navigationBarsHeightPlus(0.dp) */ fun Modifier.navigationBarsHeightPlus(additional: Dp) = composed { InsetsSizeModifier( - insets = InsetsAmbient.current.navigationBars, + insets = AmbientInsets.current.navigationBars, heightSide = VerticalSide.Bottom, additionalHeight = additional ) @@ -418,7 +418,7 @@ fun Modifier.navigationBarsWidthPlus( additional: Dp ) = composed { InsetsSizeModifier( - insets = InsetsAmbient.current.navigationBars, + insets = AmbientInsets.current.navigationBars, widthSide = side, additionalWidth = additional ) diff --git a/Jetsnack/buildSrc/src/main/java/com/example/jetsnack/buildsrc/Dependencies.kt b/Jetsnack/buildSrc/src/main/java/com/example/jetsnack/buildsrc/Dependencies.kt index 0da21dad44..1c0c9884cb 100644 --- a/Jetsnack/buildSrc/src/main/java/com/example/jetsnack/buildsrc/Dependencies.kt +++ b/Jetsnack/buildSrc/src/main/java/com/example/jetsnack/buildsrc/Dependencies.kt @@ -25,7 +25,7 @@ object Libs { const val junit = "junit:junit:4.13" object Accompanist { - private const val version = "0.3.0" + private const val version = "0.3.1" const val coil = "dev.chrisbanes.accompanist:accompanist-coil:$version" } @@ -48,7 +48,7 @@ object Libs { object Compose { const val snapshot = "" - const val version = "1.0.0-alpha04" + const val version = "1.0.0-alpha05" const val runtime = "androidx.compose.runtime:runtime:$version" const val foundation = "androidx.compose.foundation:foundation:${version}" diff --git a/Jetsurvey/app/build.gradle b/Jetsurvey/app/build.gradle index 2e2cf1f5e7..fb712e6938 100644 --- a/Jetsurvey/app/build.gradle +++ b/Jetsurvey/app/build.gradle @@ -65,6 +65,13 @@ android { buildFeatures { compose true + + // Disable unused AGP features + buildConfig false + aidl false + renderScript false + resValues false + shaders false } composeOptions { diff --git a/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignInScreen.kt b/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignInScreen.kt index d339d1190c..4f3761b0d8 100644 --- a/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignInScreen.kt +++ b/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignInScreen.kt @@ -16,8 +16,8 @@ package com.example.compose.jetsurvey.signinsignup +import androidx.compose.foundation.AmbientContentColor import androidx.compose.foundation.Text -import androidx.compose.foundation.contentColor import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -167,7 +167,7 @@ fun ErrorSnackbar( data.actionLabel?.let { TextButton( onClick = onDismiss, - contentColor = contentColor() + contentColor = AmbientContentColor.current ) { Text( text = stringResource(id = R.string.dismiss), diff --git a/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignInSignUp.kt b/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignInSignUp.kt index c16530986d..1209e2a7b9 100644 --- a/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignInSignUp.kt +++ b/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignInSignUp.kt @@ -16,10 +16,10 @@ package com.example.compose.jetsurvey.signinsignup +import androidx.compose.foundation.AmbientTextStyle import androidx.compose.foundation.Icon import androidx.compose.foundation.ScrollableColumn import androidx.compose.foundation.Text -import androidx.compose.foundation.currentTextStyle import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -30,7 +30,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredHeight import androidx.compose.foundation.layout.preferredWidth import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material.EmphasisAmbient +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.OutlinedButton @@ -117,7 +117,7 @@ fun Email( emailState.text = it }, label = { - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text( text = stringResource(id = R.string.email), style = MaterialTheme.typography.body2 @@ -170,7 +170,7 @@ fun Password( }, textStyle = MaterialTheme.typography.body2, label = { - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text( text = label, style = MaterialTheme.typography.body2 @@ -216,7 +216,7 @@ fun TextFieldError(textError: String) { Text( text = textError, modifier = Modifier.fillMaxWidth(), - style = currentTextStyle().copy(color = MaterialTheme.colors.error) + style = AmbientTextStyle.current.copy(color = MaterialTheme.colors.error) ) } } @@ -231,7 +231,7 @@ fun OrSignInAsGuest( horizontalAlignment = Alignment.CenterHorizontally ) { Surface { - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text( text = stringResource(id = R.string.or), style = MaterialTheme.typography.subtitle2 diff --git a/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignUpScreen.kt b/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignUpScreen.kt index ce7e0ba762..3b043fd158 100644 --- a/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignUpScreen.kt +++ b/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/SignUpScreen.kt @@ -21,8 +21,8 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.preferredHeight +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.Button -import androidx.compose.material.EmphasisAmbient import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis import androidx.compose.material.Scaffold @@ -103,7 +103,7 @@ fun SignUpContent( ) Spacer(modifier = Modifier.preferredHeight(16.dp)) - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text( text = stringResource(id = R.string.terms_and_conditions), style = MaterialTheme.typography.caption diff --git a/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/WelcomeScreen.kt b/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/WelcomeScreen.kt index 78ff9aea6a..b1518b236a 100644 --- a/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/WelcomeScreen.kt +++ b/Jetsurvey/app/src/main/java/com/example/compose/jetsurvey/signinsignup/WelcomeScreen.kt @@ -26,8 +26,8 @@ import androidx.compose.foundation.layout.offsetPx import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredHeight import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.Button -import androidx.compose.material.EmphasisAmbient import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis import androidx.compose.material.Surface @@ -39,7 +39,8 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.boundsInParent -import androidx.compose.ui.onPositioned +import androidx.compose.ui.onGloballyPositioned +import androidx.compose.ui.onSizeChanged import androidx.compose.ui.platform.DensityAmbient import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource @@ -72,14 +73,14 @@ fun WelcomeScreen(onEvent: (WelcomeEvent) -> Unit) { modifier = Modifier.fillMaxWidth() .brandingPreferredHeight(showBranding, heightDp) .offsetPx(y = currentOffsetHolder) - .onPositioned { + .onSizeChanged { if (showBranding) { - heightWithBranding = it.size.height + heightWithBranding = it.height } } ) { Branding( - modifier = Modifier.fillMaxWidth().weight(1f).onPositioned { + modifier = Modifier.fillMaxWidth().weight(1f).onGloballyPositioned { if (brandingBottom == 0f) { brandingBottom = it.boundsInParent.bottom } @@ -112,7 +113,7 @@ private fun Branding(modifier: Modifier = Modifier) { modifier = modifier.wrapContentHeight(align = Alignment.CenterVertically) ) { Logo(modifier = Modifier.align(Alignment.CenterHorizontally).padding(horizontal = 76.dp)) - ProvideEmphasis(emphasis = EmphasisAmbient.current.high) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.high) { Text( text = stringResource(id = R.string.app_tagline), style = MaterialTheme.typography.subtitle1, @@ -147,7 +148,7 @@ private fun SignInCreateAccount( ) { val emailState = remember { EmailState() } Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) { - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text( text = stringResource(id = R.string.sign_in_create_account), style = MaterialTheme.typography.subtitle2, diff --git a/Jetsurvey/build.gradle b/Jetsurvey/build.gradle index dc1c110111..8963493a05 100644 --- a/Jetsurvey/build.gradle +++ b/Jetsurvey/build.gradle @@ -38,10 +38,8 @@ subprojects { mavenCentral() jcenter() - if (!Libs.AndroidX.Compose.snapshot.isEmpty()) { - maven { - url "https://androidx.dev/snapshots/builds/${Libs.AndroidX.Compose.snapshot}/artifacts/ui/repository/" - } + if (Libs.AndroidX.Compose.version.endsWith("SNAPSHOT")) { + maven { url Libs.AndroidX.Compose.snapshotUrl } } } diff --git a/Jetsurvey/buildSrc/src/main/java/com/example/compose/jetsurvey/buildsrc/dependencies.kt b/Jetsurvey/buildSrc/src/main/java/com/example/compose/jetsurvey/buildsrc/dependencies.kt index db8cd6a04d..9e08760240 100644 --- a/Jetsurvey/buildSrc/src/main/java/com/example/compose/jetsurvey/buildsrc/dependencies.kt +++ b/Jetsurvey/buildSrc/src/main/java/com/example/compose/jetsurvey/buildsrc/dependencies.kt @@ -29,7 +29,7 @@ object Libs { const val material = "com.google.android.material:material:1.1.0" object Kotlin { - private const val version = "1.4.0" + private const val version = "1.4.10" const val stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version" const val gradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$version" const val extensions = "org.jetbrains.kotlin:kotlin-android-extensions:$version" @@ -41,9 +41,12 @@ object Libs { object Compose { const val snapshot = "" - const val version = "1.0.0-alpha04" + const val version = "1.0.0-alpha05" + + @get:JvmStatic + val snapshotUrl: String + get() = "https://androidx.dev/snapshots/builds/$snapshot/artifacts/ui/repository/" - const val core = "androidx.compose.ui:ui:$version" const val foundation = "androidx.compose.foundation:foundation:$version" const val layout = "androidx.compose.foundation:foundation-layout:$version" const val material = "androidx.compose.material:material:$version" diff --git a/Owl/app/src/main/java/com/example/owl/ui/OwlApp.kt b/Owl/app/src/main/java/com/example/owl/ui/OwlApp.kt index ff857b1645..cc6b3e8a5f 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/OwlApp.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/OwlApp.kt @@ -25,7 +25,7 @@ import androidx.compose.runtime.savedinstancestate.rememberSavedInstanceState import com.example.owl.ui.course.CourseDetails import com.example.owl.ui.courses.Courses import com.example.owl.ui.onboarding.Onboarding -import com.example.owl.ui.utils.BackDispatcherAmbient +import com.example.owl.ui.utils.AmbientBackDispatcher import com.example.owl.ui.utils.Navigator import com.example.owl.ui.utils.ProvideDisplayInsets import com.example.owl.ui.utils.ProvideImageLoader @@ -40,7 +40,7 @@ fun OwlApp(backDispatcher: OnBackPressedDispatcher) { } val actions = remember(navigator) { Actions(navigator) } - Providers(BackDispatcherAmbient provides backDispatcher) { + Providers(AmbientBackDispatcher provides backDispatcher) { ProvideDisplayInsets { ProvideImageLoader { Crossfade(navigator.current) { destination -> diff --git a/Owl/app/src/main/java/com/example/owl/ui/common/CourseListItem.kt b/Owl/app/src/main/java/com/example/owl/ui/common/CourseListItem.kt index e6ab69fdf8..7a74b9ef2f 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/common/CourseListItem.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/common/CourseListItem.kt @@ -26,6 +26,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredHeight import androidx.compose.foundation.layout.preferredSize +import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.MaterialTheme import androidx.compose.material.Surface @@ -104,6 +105,7 @@ fun CourseListItem( modifier = Modifier .padding(start = 8.dp) .weight(1f) + .wrapContentWidth(Alignment.Start) ) NetworkImage( url = course.instructor, diff --git a/Owl/app/src/main/java/com/example/owl/ui/course/CourseDetails.kt b/Owl/app/src/main/java/com/example/owl/ui/course/CourseDetails.kt index 344a4be44c..43291465b8 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/course/CourseDetails.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/course/CourseDetails.kt @@ -37,8 +37,8 @@ import androidx.compose.foundation.layout.preferredHeight import androidx.compose.foundation.layout.preferredSize import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.Divider -import androidx.compose.material.EmphasisAmbient import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.FractionalThreshold import androidx.compose.material.IconButton @@ -81,7 +81,7 @@ import com.example.owl.ui.common.OutlinedAvatar import com.example.owl.ui.theme.BlueTheme import com.example.owl.ui.theme.PinkTheme import com.example.owl.ui.theme.pink500 -import com.example.owl.ui.utils.InsetsAmbient +import com.example.owl.ui.utils.AmbientInsets import com.example.owl.ui.utils.NetworkImage import com.example.owl.ui.utils.backHandler import com.example.owl.ui.utils.lerp @@ -227,7 +227,7 @@ private fun CourseDescriptionBody(course: Course) { .padding(horizontal = 16.dp) ) Spacer(modifier = Modifier.preferredHeight(16.dp)) - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { Text( text = stringResource(id = R.string.course_desc), style = MaterialTheme.typography.body1, @@ -246,7 +246,7 @@ private fun CourseDescriptionBody(course: Course) { .fillMaxWidth() .padding(16.dp) ) - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { Text( text = stringResource(id = R.string.needs), style = MaterialTheme.typography.body1, @@ -320,7 +320,7 @@ private fun LessonsSheet( ) { // Use the fraction that the sheet is open to drive the transformation from FAB -> Sheet val fabSize = with(DensityAmbient.current) { FabSize.toPx() } - val fabSheetHeight = fabSize + InsetsAmbient.current.systemBars.bottom + val fabSheetHeight = fabSize + AmbientInsets.current.systemBars.bottom val offsetX = lerp(width - fabSize, 0f, 0f, 0.15f, openFraction) val offsetY = lerp(height - fabSheetHeight, 0f, openFraction) val tlCorner = lerp(fabSize, 0f, 0f, 0.15f, openFraction) @@ -388,7 +388,7 @@ private fun Lessons( } ScrollableColumn( scrollState = scroll, - contentPadding = InsetsAmbient.current.systemBars.toPaddingValues( + contentPadding = AmbientInsets.current.systemBars.toPaddingValues( top = false ) ) { @@ -442,7 +442,7 @@ private fun Lesson(lesson: Lesson) { maxLines = 2, overflow = TextOverflow.Ellipsis ) - ProvideEmphasis(EmphasisAmbient.current.medium) { + ProvideEmphasis(AmbientEmphasisLevels.current.medium) { Row( modifier = Modifier.padding(top = 4.dp), verticalAlignment = Alignment.CenterVertically diff --git a/Owl/app/src/main/java/com/example/owl/ui/courses/Courses.kt b/Owl/app/src/main/java/com/example/owl/ui/courses/Courses.kt index f4dbd3ae4b..d1786663e6 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/courses/Courses.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/courses/Courses.kt @@ -18,10 +18,10 @@ package com.example.owl.ui.courses import androidx.annotation.DrawableRes import androidx.annotation.StringRes +import androidx.compose.foundation.AmbientContentColor import androidx.compose.foundation.Icon import androidx.compose.foundation.Image import androidx.compose.foundation.Text -import androidx.compose.foundation.contentColor import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredHeight import androidx.compose.material.BottomNavigation @@ -67,7 +67,7 @@ fun Courses(selectCourse: (Long) -> Unit) { onClick = { setSelectedTab(tab) }, alwaysShowLabels = false, selectedContentColor = MaterialTheme.colors.secondary, - unselectedContentColor = contentColor(), + unselectedContentColor = AmbientContentColor.current, modifier = Modifier.navigationBarsPadding() ) } diff --git a/Owl/app/src/main/java/com/example/owl/ui/courses/MyCourses.kt b/Owl/app/src/main/java/com/example/owl/ui/courses/MyCourses.kt index b1341298ca..f816e6ef47 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/courses/MyCourses.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/courses/MyCourses.kt @@ -16,13 +16,13 @@ package com.example.owl.ui.courses -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredHeight import androidx.compose.foundation.layout.preferredWidth -import androidx.compose.foundation.lazy.LazyColumnFor +import androidx.compose.foundation.lazy.ExperimentalLazyDsl +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -32,19 +32,24 @@ import com.example.owl.model.Course import com.example.owl.model.courses import com.example.owl.ui.common.CourseListItem import com.example.owl.ui.theme.BlueTheme -import com.example.owl.ui.utils.statusBarsPadding +import com.example.owl.ui.utils.statusBarsHeight +@OptIn(ExperimentalLazyDsl::class) @Composable fun MyCourses( courses: List, selectCourse: (Long) -> Unit, modifier: Modifier = Modifier ) { - Column(modifier = modifier.statusBarsPadding()) { - // TODO appbar should scroll out - CoursesAppBar() - LazyColumnFor(courses) { course -> - MyCourse(course, selectCourse) + LazyColumn(modifier) { + item { + Spacer(Modifier.statusBarsHeight()) + } + item { + CoursesAppBar() + } + itemsIndexed(courses) { index, course -> + MyCourse(course, index, selectCourse) } } } @@ -52,10 +57,11 @@ fun MyCourses( @Composable fun MyCourse( course: Course, + index: Int, selectCourse: (Long) -> Unit ) { Row(modifier = Modifier.padding(bottom = 8.dp)) { - val stagger = if (course.id % 2L == 0L) 72.dp else 16.dp + val stagger = if (index % 2 == 0) 72.dp else 16.dp Spacer(modifier = Modifier.preferredWidth(stagger)) CourseListItem( course = course, diff --git a/Owl/app/src/main/java/com/example/owl/ui/courses/SearchCourses.kt b/Owl/app/src/main/java/com/example/owl/ui/courses/SearchCourses.kt index 89723bf28c..74d2ea3b40 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/courses/SearchCourses.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/courses/SearchCourses.kt @@ -25,6 +25,7 @@ import androidx.compose.foundation.Text import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.TopAppBar @@ -67,6 +68,7 @@ fun SearchCourses( end = 16.dp, bottom = 8.dp ) + .wrapContentWidth(Alignment.Start) ) } } diff --git a/Owl/app/src/main/java/com/example/owl/ui/onboarding/Onboarding.kt b/Owl/app/src/main/java/com/example/owl/ui/onboarding/Onboarding.kt index d444c03a79..f1ecdb78a0 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/onboarding/Onboarding.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/onboarding/Onboarding.kt @@ -38,7 +38,7 @@ import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.selection.toggleable import androidx.compose.foundation.shape.CornerSize -import androidx.compose.material.EmphasisAmbient +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.FloatingActionButton import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme @@ -94,7 +94,7 @@ fun Onboarding(onboardingComplete: () -> Unit) { .navigationBarsPadding() .padding(innerPadding) ) { - ProvideEmphasis(EmphasisAmbient.current.high) { + ProvideEmphasis(AmbientEmphasisLevels.current.high) { Text( text = stringResource(R.string.choose_topics_that_interest_you), style = MaterialTheme.typography.h4, @@ -129,7 +129,7 @@ private fun AppBar() { asset = vectorResource(id = OwlTheme.images.lockupLogo), modifier = Modifier.padding(16.dp) ) - ProvideEmphasis(emphasis = EmphasisAmbient.current.high) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.high) { IconButton( modifier = Modifier.padding(16.dp), onClick = { /* todo */ } @@ -221,7 +221,7 @@ private fun TopicChip(topic: Topic) { ) ) Row(verticalAlignment = Alignment.CenterVertically) { - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Icon( asset = vectorResource(R.drawable.ic_grain), modifier = Modifier diff --git a/Owl/app/src/main/java/com/example/owl/ui/theme/Elevation.kt b/Owl/app/src/main/java/com/example/owl/ui/theme/Elevations.kt similarity index 88% rename from Owl/app/src/main/java/com/example/owl/ui/theme/Elevation.kt rename to Owl/app/src/main/java/com/example/owl/ui/theme/Elevations.kt index 4c141a1004..c82d8399b2 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/theme/Elevation.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/theme/Elevations.kt @@ -25,6 +25,6 @@ import androidx.compose.ui.unit.dp * Elevation values that can be themed. */ @Immutable -data class Elevation(val card: Dp = 0.dp) +data class Elevations(val card: Dp = 0.dp) -internal val ElevationAmbient = staticAmbientOf { Elevation() } +internal val AmbientElevations = staticAmbientOf { Elevations() } diff --git a/Owl/app/src/main/java/com/example/owl/ui/theme/Images.kt b/Owl/app/src/main/java/com/example/owl/ui/theme/Images.kt index a88afff8a2..2d7596f9a2 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/theme/Images.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/theme/Images.kt @@ -26,4 +26,4 @@ import androidx.compose.runtime.staticAmbientOf @Immutable data class Images(@DrawableRes val lockupLogo: Int) -internal val ImageAmbient = staticAmbientOf() +internal val AmbientImages = staticAmbientOf() diff --git a/Owl/app/src/main/java/com/example/owl/ui/theme/Theme.kt b/Owl/app/src/main/java/com/example/owl/ui/theme/Theme.kt index f893c1b3c4..4705cc7cbf 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/theme/Theme.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/theme/Theme.kt @@ -110,9 +110,9 @@ fun PinkTheme( OwlTheme(darkTheme, colors, content) } -private val LightElevation = Elevation() +private val LightElevation = Elevations() -private val DarkElevation = Elevation(card = 1.dp) +private val DarkElevation = Elevations(card = 1.dp) private val LightImages = Images(lockupLogo = R.drawable.ic_lockup_blue) @@ -127,8 +127,8 @@ private fun OwlTheme( val elevation = if (darkTheme) DarkElevation else LightElevation val images = if (darkTheme) DarkImages else LightImages Providers( - ElevationAmbient provides elevation, - ImageAmbient provides images + AmbientElevations provides elevation, + AmbientImages provides images ) { MaterialTheme( colors = colors, @@ -140,7 +140,7 @@ private fun OwlTheme( } /** - * Alternate to [MaterialTheme] allowing us to add our own theme systems (e.g. [Elevation]) or to + * Alternate to [MaterialTheme] allowing us to add our own theme systems (e.g. [Elevations]) or to * extend [MaterialTheme]'s types e.g. return our own [Colors] extension */ object OwlTheme { @@ -167,16 +167,16 @@ object OwlTheme { get() = MaterialTheme.shapes /** - * Retrieves the current [Elevation] at the call site's position in the hierarchy. + * Retrieves the current [Elevations] at the call site's position in the hierarchy. */ @Composable - val elevations: Elevation - get() = ElevationAmbient.current + val elevations: Elevations + get() = AmbientElevations.current /** * Retrieves the current [Images] at the call site's position in the hierarchy. */ @Composable val images: Images - get() = ImageAmbient.current + get() = AmbientImages.current } diff --git a/Owl/app/src/main/java/com/example/owl/ui/utils/Insets.kt b/Owl/app/src/main/java/com/example/owl/ui/utils/Insets.kt index b2793b4f37..81f232fd35 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/utils/Insets.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/utils/Insets.kt @@ -118,10 +118,10 @@ class Insets { internal set } -val InsetsAmbient = staticAmbientOf { DisplayInsets() } +val AmbientInsets = staticAmbientOf { DisplayInsets() } /** - * Applies any [WindowInsetsCompat] values to [InsetsAmbient], which are then available + * Applies any [WindowInsetsCompat] values to [AmbientInsets], which are then available * within [content]. * * @param consumeWindowInsets Whether to consume any [WindowInsetsCompat]s which are dispatched to @@ -165,7 +165,7 @@ fun ProvideDisplayInsets( } } - Providers(InsetsAmbient provides displayInsets) { + Providers(AmbientInsets provides displayInsets) { content() } } @@ -192,7 +192,7 @@ private fun Insets.updateFrom(windowInsets: WindowInsetsCompat, type: Int) { */ fun Modifier.systemBarsPadding(enabled: Boolean = true) = composed { insetsPadding( - insets = InsetsAmbient.current.systemBars, + insets = AmbientInsets.current.systemBars, left = enabled, top = enabled, right = enabled, @@ -205,7 +205,7 @@ fun Modifier.systemBarsPadding(enabled: Boolean = true) = composed { * of the content. */ fun Modifier.statusBarsPadding() = composed { - insetsPadding(insets = InsetsAmbient.current.statusBars, top = true) + insetsPadding(insets = AmbientInsets.current.statusBars, top = true) } /** @@ -226,7 +226,7 @@ fun Modifier.navigationBarsPadding( right: Boolean = true ) = composed { insetsPadding( - insets = InsetsAmbient.current.navigationBars, + insets = AmbientInsets.current.navigationBars, left = left, right = right, bottom = bottom @@ -260,7 +260,7 @@ fun Modifier.navigationBarsPadding( */ fun Modifier.statusBarsHeight(additional: Dp = 0.dp) = composed { InsetsSizeModifier( - insets = InsetsAmbient.current.statusBars, + insets = AmbientInsets.current.statusBars, heightSide = VerticalSide.Top, additionalHeight = additional ) @@ -312,7 +312,7 @@ inline fun Modifier.statusBarsHeight() = statusBarsHeightPlus(0.dp) */ fun Modifier.statusBarsHeightPlus(additional: Dp) = composed { InsetsSizeModifier( - insets = InsetsAmbient.current.statusBars, + insets = AmbientInsets.current.statusBars, heightSide = VerticalSide.Top, additionalHeight = additional ) @@ -364,7 +364,7 @@ inline fun Modifier.navigationBarsHeight() = navigationBarsHeightPlus(0.dp) */ fun Modifier.navigationBarsHeightPlus(additional: Dp) = composed { InsetsSizeModifier( - insets = InsetsAmbient.current.navigationBars, + insets = AmbientInsets.current.navigationBars, heightSide = VerticalSide.Bottom, additionalHeight = additional ) @@ -418,7 +418,7 @@ fun Modifier.navigationBarsWidthPlus( additional: Dp ) = composed { InsetsSizeModifier( - insets = InsetsAmbient.current.navigationBars, + insets = AmbientInsets.current.navigationBars, widthSide = side, additionalWidth = additional ) diff --git a/Owl/app/src/main/java/com/example/owl/ui/utils/Navigation.kt b/Owl/app/src/main/java/com/example/owl/ui/utils/Navigation.kt index 3fe95907f9..44234e20a9 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/utils/Navigation.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/utils/Navigation.kt @@ -91,7 +91,7 @@ fun backHandler( backCallback.isEnabled = enabled } - val dispatcher = BackDispatcherAmbient.current + val dispatcher = AmbientBackDispatcher.current onCommit(backCallback) { dispatcher.addCallback(backCallback) onDispose { @@ -104,6 +104,6 @@ fun backHandler( * An [androidx.compose.runtime.Ambient] providing the current [OnBackPressedDispatcher]. You must * [provide][androidx.compose.runtime.Providers] a value before use. */ -internal val BackDispatcherAmbient = staticAmbientOf { +internal val AmbientBackDispatcher = staticAmbientOf { error("No Back Dispatcher provided") } diff --git a/Owl/app/src/main/java/com/example/owl/ui/utils/NetworkImage.kt b/Owl/app/src/main/java/com/example/owl/ui/utils/NetworkImage.kt index 894dffbdd3..5d9ee0ef2e 100644 --- a/Owl/app/src/main/java/com/example/owl/ui/utils/NetworkImage.kt +++ b/Owl/app/src/main/java/com/example/owl/ui/utils/NetworkImage.kt @@ -51,7 +51,7 @@ fun NetworkImage( data = url, modifier = modifier, contentScale = contentScale, - imageLoader = ImageLoaderAmbient.current, + imageLoader = AmbientImageLoader.current, loading = { if (placeholderColor != null) { Spacer( @@ -64,7 +64,7 @@ fun NetworkImage( ) } -private val ImageLoaderAmbient = staticAmbientOf { +private val AmbientImageLoader = staticAmbientOf { error("No loader provided") } @@ -77,7 +77,7 @@ fun ProvideImageLoader(content: @Composable () -> Unit) { add(UnsplashSizingInterceptor) }.build() } - Providers(ImageLoaderAmbient provides loader, children = content) + Providers(AmbientImageLoader provides loader, children = content) } /** diff --git a/Owl/buildSrc/src/main/java/com/example/owl/buildsrc/Dependencies.kt b/Owl/buildSrc/src/main/java/com/example/owl/buildsrc/Dependencies.kt index 0357ef70fc..5a83c5c5fc 100644 --- a/Owl/buildSrc/src/main/java/com/example/owl/buildsrc/Dependencies.kt +++ b/Owl/buildSrc/src/main/java/com/example/owl/buildsrc/Dependencies.kt @@ -25,7 +25,7 @@ object Libs { const val junit = "junit:junit:4.13" object Accompanist { - private const val version = "0.3.0" + private const val version = "0.3.1" const val coil = "dev.chrisbanes.accompanist:accompanist-coil:$version" } @@ -48,7 +48,7 @@ object Libs { object Compose { const val snapshot = "" - const val version = "1.0.0-alpha04" + const val version = "1.0.0-alpha05" const val runtime = "androidx.compose.runtime:runtime:$version" const val foundation = "androidx.compose.foundation:foundation:$version" diff --git a/README.md b/README.md index 774e1bc501..ba8363afc5 100644 --- a/README.md +++ b/README.md @@ -41,12 +41,6 @@ To see how Compose and view-based UIs can coexist and interact together, check o * [Sunflower's `compose` branch](https://goo.gle/sunflower-compose) * [Tivi](https://tivi.app) -🚧 Known issues ------------- - -Jetnews and Crane are not updated to version `alpha04` due to this -[bug](https://issuetracker.google.com/169629547). - ## License ``` Copyright 2020 The Android Open Source Project diff --git a/Rally/app/build.gradle b/Rally/app/build.gradle index ce14fe130b..c3ccf14aea 100644 --- a/Rally/app/build.gradle +++ b/Rally/app/build.gradle @@ -67,6 +67,13 @@ android { buildFeatures { compose true + + // Disable unused AGP features + buildConfig false + aidl false + renderScript false + resValues false + shaders false } composeOptions { diff --git a/Rally/app/src/main/java/com/example/compose/rally/ui/components/CommonUi.kt b/Rally/app/src/main/java/com/example/compose/rally/ui/components/CommonUi.kt index f5862dcf34..08823687c1 100644 --- a/Rally/app/src/main/java/com/example/compose/rally/ui/components/CommonUi.kt +++ b/Rally/app/src/main/java/com/example/compose/rally/ui/components/CommonUi.kt @@ -27,8 +27,8 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredHeight import androidx.compose.foundation.layout.preferredSize import androidx.compose.foundation.layout.preferredWidth +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.Divider -import androidx.compose.material.EmphasisAmbient import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis import androidx.compose.material.icons.Icons @@ -89,10 +89,10 @@ private fun BaseRow( ) Spacer(Modifier.preferredWidth(12.dp)) Column(Modifier) { - ProvideEmphasis(emphasis = EmphasisAmbient.current.high) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.high) { Text(text = title, style = typography.body1) } - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Text(text = subtitle, style = typography.subtitle1) } } @@ -115,7 +115,7 @@ private fun BaseRow( } Spacer(Modifier.preferredWidth(16.dp)) - ProvideEmphasis(emphasis = EmphasisAmbient.current.medium) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.medium) { Icon( asset = Icons.Filled.ChevronRight, modifier = Modifier diff --git a/Rally/app/src/main/java/com/example/compose/rally/ui/overview/OverviewScreen.kt b/Rally/app/src/main/java/com/example/compose/rally/ui/overview/OverviewScreen.kt index c1857861d9..814ec10866 100644 --- a/Rally/app/src/main/java/com/example/compose/rally/ui/overview/OverviewScreen.kt +++ b/Rally/app/src/main/java/com/example/compose/rally/ui/overview/OverviewScreen.kt @@ -28,8 +28,8 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.preferredHeight +import androidx.compose.material.AmbientEmphasisLevels import androidx.compose.material.Card -import androidx.compose.material.EmphasisAmbient import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.ProvideEmphasis @@ -102,7 +102,7 @@ private fun AlertHeader(onClickSeeAll: () -> Unit) { modifier = Modifier.padding(RallyDefaultPadding).fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { - ProvideEmphasis(emphasis = EmphasisAmbient.current.high) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.high) { Text( text = "Alerts", style = MaterialTheme.typography.subtitle2, @@ -128,7 +128,7 @@ private fun AlertItem(message: String) { modifier = Modifier.padding(RallyDefaultPadding), horizontalArrangement = Arrangement.SpaceBetween ) { - ProvideEmphasis(emphasis = EmphasisAmbient.current.high) { + ProvideEmphasis(emphasis = AmbientEmphasisLevels.current.high) { Text( style = MaterialTheme.typography.body2, modifier = Modifier.weight(1f), diff --git a/Rally/build.gradle b/Rally/build.gradle index ad6a6d24d5..6ccc84cc18 100644 --- a/Rally/build.gradle +++ b/Rally/build.gradle @@ -15,6 +15,7 @@ */ import com.example.compose.rally.buildsrc.Libs +import com.example.compose.rally.buildsrc.Urls import com.example.compose.rally.buildsrc.Versions buildscript { @@ -40,12 +41,8 @@ subprojects { jcenter() if (!Libs.AndroidX.Compose.snapshot.isEmpty()) { - maven { - url "https://androidx.dev/snapshots/builds/${Libs.AndroidX.Compose.snapshot}/artifacts/ui/repository/" - } + maven { url Urls.composeSnapshotRepo } } - - maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } } apply plugin: 'com.diffplug.spotless' diff --git a/Rally/buildSrc/src/main/java/com/example/compose/rally/buildsrc/dependencies.kt b/Rally/buildSrc/src/main/java/com/example/compose/rally/buildsrc/dependencies.kt index 4f166912da..11a2c38908 100644 --- a/Rally/buildSrc/src/main/java/com/example/compose/rally/buildsrc/dependencies.kt +++ b/Rally/buildSrc/src/main/java/com/example/compose/rally/buildsrc/dependencies.kt @@ -29,7 +29,7 @@ object Libs { const val material = "com.google.android.material:material:1.1.0" object Kotlin { - private const val version = "1.4.0" + private const val version = "1.4.10" const val stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version" const val gradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$version" const val extensions = "org.jetbrains.kotlin:kotlin-android-extensions:$version" @@ -48,7 +48,7 @@ object Libs { object Compose { const val snapshot = "" - const val version = "1.0.0-alpha04" + const val version = "1.0.0-alpha05" const val core = "androidx.compose.ui:ui:$version" const val foundation = "androidx.compose.foundation:foundation:$version" @@ -89,3 +89,8 @@ object Libs { } } } + +object Urls { + const val composeSnapshotRepo = "https://androidx-dev-prod.appspot.com/snapshots/builds/" + + "${Libs.AndroidX.Compose.snapshot}/artifacts/ui/repository/" +}