Skip to content

Commit

Permalink
Compose code for App Distribution (#1630)
Browse files Browse the repository at this point in the history
  • Loading branch information
b1no0019 committed May 31, 2024
1 parent 8c3e5e5 commit 8f57919
Show file tree
Hide file tree
Showing 11 changed files with 271 additions and 12 deletions.
7 changes: 4 additions & 3 deletions appdistribution/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ plugins {

android {
namespace 'com.google.firebase.appdistributionquickstart'
compileSdk 33
compileSdk 34
defaultConfig {
applicationId "com.google.firebase.appdistributionquickstart"
minSdk 21 // minSdk would be 19 without compose
targetSdk 33
targetSdk 34
versionCode 1
versionName "1.0"

Expand Down Expand Up @@ -66,7 +66,7 @@ dependencies {
implementation platform('com.google.firebase:firebase-bom:31.0.2')

// ADD the SDK to the "prerelease" variant only (example)
implementation 'com.google.firebase:firebase-appdistribution-ktx:16.0.0-beta01'
implementation 'com.google.firebase:firebase-appdistribution:16.0.0-beta12'

// For an optimal experience using App Distribution, add the Firebase SDK
// for Google Analytics. This is recommended, but not required.
Expand All @@ -77,6 +77,7 @@ dependencies {
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.activity:activity-compose:1.5.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.4.1'

androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Expand Down
6 changes: 6 additions & 0 deletions appdistribution/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
android:theme="@style/AppTheme">
</activity>

<activity
android:name=".kotlin.ComposeMainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme">
</activity>

<activity android:name=".EntryChoiceActivity"
android:exported="true">
<intent-filter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,29 @@ import android.content.Intent
import com.firebase.example.internal.BaseEntryChoiceActivity
import com.firebase.example.internal.Choice
import com.google.firebase.appdistributionquickstart.java.MainActivity
import com.google.firebase.appdistributionquickstart.kotlin.ComposeMainActivity
import com.google.firebase.appdistributionquickstart.kotlin.KotlinMainActivity

class EntryChoiceActivity : BaseEntryChoiceActivity() {

override fun getChoices(): List<Choice> {
return listOf(
Choice(
"Java",
"Run the Firebase App Distribution quickstart written in Java.",
Intent(this, MainActivity::class.java)),
Choice(
"Kotlin",
"Run the Firebase App Distribution quickstart written in Kotlin.",
Intent(this, KotlinMainActivity::class.java))
)
Choice(
"Java",
"Run the Firebase App Distribution quickstart written in Java.",
Intent(this, MainActivity::class.java)
),
Choice(
"Kotlin",
"Run the Firebase App Distribution quickstart written in Kotlin.",
Intent(this, KotlinMainActivity::class.java)
),
Choice(
"Compose",
"Run the Firebase App Distribution quickstart written in Compose.",
Intent(this, ComposeMainActivity::class.java),
),

)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.google.firebase.appdistributionquickstart.kotlin

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.CreationExtras
import com.google.firebase.Firebase
import com.google.firebase.appdistribution.FirebaseAppDistribution
import com.google.firebase.appdistribution.FirebaseAppDistributionException
import com.google.firebase.appdistribution.appDistribution

class AppDistributionViewModel(
val appDistribution: FirebaseAppDistribution
) : ViewModel() {

companion object {
const val TAG = "AppDistribution-Quickstart"

// Used to inject this ViewModel's dependencies
// See also: https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-factories
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
// Get instance.
val appDistribution = Firebase.appDistribution
return AppDistributionViewModel(appDistribution) as T
}
}
}

fun updateIfNewRelease() {
appDistribution.updateIfNewReleaseAvailable()
.addOnProgressListener { updateProgress ->
// (Optional) Implement custom progress updates in addition to
// automatic NotificationManager updates.
}
.addOnFailureListener { e ->
if (e is FirebaseAppDistributionException) {
// Handle exception.
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package com.google.firebase.appdistributionquickstart.kotlin

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.viewmodel.compose.viewModel
import com.google.firebase.appdistributionquickstart.R
import com.google.firebase.appdistributionquickstart.ui.theme.AppDistributionTheme


class ComposeMainActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
AppDistributionTheme {
Surface(
modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background
) {
MainAppView()
}
}
}
}
}

@Composable
fun MainAppView(
appDistributionViewModel: AppDistributionViewModel = viewModel(factory = AppDistributionViewModel.Factory)
) {

ComposableLifecycle { source, event ->
if (event == Lifecycle.Event.ON_RESUME) {
appDistributionViewModel.updateIfNewRelease()
}
}


Scaffold(topBar = {
TopAppBar(
backgroundColor = colorResource(R.color.colorPrimary)
) {
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.h6,
textAlign = TextAlign.Center,
modifier = Modifier.padding(8.dp),
color = Color.White
)
}
}, content = { it ->
Column(
horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier
.fillMaxSize()
.padding(it)
) {
Spacer(modifier = Modifier.height(30.dp))
Image(
painterResource(R.drawable.firebase_lockup_400),
contentDescription = "Firebase logo",
contentScale = ContentScale.Crop,
)
Text(
text = stringResource(R.string.textview_text), modifier = Modifier.padding(8.dp)
)
}
})
}

@Composable
fun ComposableLifecycle(
lifeCycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
onEvent: (LifecycleOwner, Lifecycle.Event) -> Unit
) {
DisposableEffect(lifeCycleOwner) {
val observer = LifecycleEventObserver { source, event ->
onEvent(source, event)
}
lifeCycleOwner.lifecycle.addObserver(observer)
onDispose {
lifeCycleOwner.lifecycle.removeObserver(observer)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.google.firebase.appdistributionquickstart.ui.theme

import androidx.compose.ui.graphics.Color

val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)

val FirebaseBlue = Color(0xFF0288D1) // copied from colors.xml
val FirebaseBannerBlue = Color(0xFF039BE5) // copied from colors.xml
val FirebaseOrange = Color(0xFFFFA000) // copied from colors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.google.firebase.appdistributionquickstart.ui.theme

import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Shapes
import androidx.compose.ui.unit.dp

val Shapes = Shapes(
small = RoundedCornerShape(16.dp),
medium = RoundedCornerShape(2.dp),
large = RoundedCornerShape(0.dp)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.google.firebase.appdistributionquickstart.ui.theme

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material.MaterialTheme
import androidx.compose.material.darkColors
import androidx.compose.material.lightColors

import androidx.compose.runtime.Composable

private val DarkColorPalette = darkColors(
primary = Purple80,
primaryVariant = PurpleGrey80,
secondary = Pink80
)

private val LightColorPalette = lightColors(
primary = FirebaseBlue,
primaryVariant = FirebaseBannerBlue,
secondary = FirebaseOrange
)

@Composable
fun AppDistributionTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colors = if (darkTheme) {
DarkColorPalette
} else {
LightColorPalette
}

MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.google.firebase.appdistributionquickstart.ui.theme

import androidx.compose.material.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp

// Set of Material typography styles to start with
val Typography = Typography(
body1 = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
)
)
4 changes: 4 additions & 0 deletions appdistribution/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

buildscript {

ext {
compose_version = '1.2.1'
}

repositories {
mavenLocal()
google()
Expand Down
1 change: 1 addition & 0 deletions appdistribution/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ org.gradle.jvmargs=-Xmx1536m
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.useAndroidX=true

0 comments on commit 8f57919

Please sign in to comment.