Skip to content

Commit

Permalink
Merge branch 'feature/killswitch' of github.com:mirego/kmp-boilerplat…
Browse files Browse the repository at this point in the history
…e into feature/killswitch
  • Loading branch information
ChristopheTremblay committed Nov 6, 2023
2 parents 2d9e23f + 3df7734 commit 2cefbfd
Show file tree
Hide file tree
Showing 38 changed files with 450 additions and 77 deletions.
6 changes: 5 additions & 1 deletion androidApp/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.crashlyticsPlugin)
}

kotlin {
Expand Down Expand Up @@ -77,11 +78,14 @@ dependencies {
implementation(project(":shared"))

implementation(libs.android.splash)
implementation(libs.android.firebase.analytics)
implementation(libs.android.firebase.crashlytics)
implementation(platform(libs.android.firebase.bom))
implementation(libs.androidx.appcompat)
implementation(libs.androidx.activity.compose)

implementation(platform(libs.androidx.compose.bom))
implementation(libs.accompanist.systemuicontroller)
implementation(libs.accompanist.placeholder.material)
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.ui.tooling)
implementation(libs.androidx.compose.material)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@ import com.mirego.kmp.boilerplate.app.bootstrap.AndroidBootstrap
import com.mirego.kmp.boilerplate.bootstrap.Bootstrapper

class AndroidApplication : Application() {
private lateinit var bootstrap: AndroidBootstrap
val bootstrapper = Bootstrapper()
lateinit var bootstrapper: Bootstrapper

override fun onCreate() {
super.onCreate()
bootstrap = AndroidBootstrap(this)
bootstrapper.initDependencies(bootstrap)
bootstrapper = Bootstrapper(AndroidBootstrap(this))
bootstrapper.initDependencies()
}

override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
bootstrap.appInformation.updateLocale()
(bootstrapper.bootstrap as? AndroidBootstrap)?.appInformation?.updateLocale()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,10 @@ import androidx.lifecycle.lifecycleScope
import com.mirego.killswitch.AndroidKillswitch
import com.mirego.killswitch.KillswitchException
import com.mirego.kmp.boilerplate.app.ui.application.ApplicationView
import com.mirego.kmp.boilerplate.bootstrap.AppEnvironment
import com.mirego.kmp.boilerplate.bootstrap.Bootstrapper
import com.mirego.kmp.boilerplate.trikot.viewmodels.declarative.compose.getInitialViewModel
import com.mirego.kmp.boilerplate.utils.Const
import com.mirego.kmp.boilerplate.viewmodel.application.ApplicationViewModel
import kotlinx.coroutines.launch
import org.koin.core.component.get

class MainActivity : AppCompatActivity() {
private val bootstrapper: Bootstrapper
Expand All @@ -29,10 +26,6 @@ class MainActivity : AppCompatActivity() {
}
}

private val appEnvironment: AppEnvironment by lazy {
bootstrapper.get()
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
installSplashScreen()
Expand All @@ -44,9 +37,13 @@ class MainActivity : AppCompatActivity() {
lifecycleScope.launch {
try {
AndroidKillswitch.showDialog(
AndroidKillswitch.engage(appEnvironment.androidSpecific.killSwitchAPIKey, this@MainActivity, Const.KILLSWITCH_URL), // TODO use current appEnvironment
this@MainActivity,
android.R.style.Theme_DeviceDefault_Light_Dialog_Alert
viewData = AndroidKillswitch.engage(
key = bootstrapper.bootstrap.environment.androidSpecific.killSwitchAPIKey,
context = this@MainActivity,
url = bootstrapper.bootstrap.environment.androidSpecific.killSwitchAPIKey
),
activity = this@MainActivity,
themeResId = android.R.style.Theme_DeviceDefault_Light_Dialog_Alert
)
} catch (e: KillswitchException) {
Log.e(TAG, "Killswitch exception", e)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.mirego.kmp.boilerplate.app.analytics

import android.content.Context
import android.os.Bundle
import com.google.firebase.analytics.FirebaseAnalytics
import com.mirego.kmp.boilerplate.analytics.SharedAnalyticsService
import com.mirego.trikot.analytics.AnalyticsEvent
import com.mirego.trikot.analytics.AnalyticsPropertiesType

class AndroidSharedAnalyticsService(
context: Context,
private var analyticsEnabled: Boolean = true
) : SharedAnalyticsService {
private var firebaseAnalytics = FirebaseAnalytics.getInstance(context)

override var isEnabled: Boolean
get() = analyticsEnabled
set(value) {
analyticsEnabled = value
firebaseAnalytics.setAnalyticsCollectionEnabled(value)
}

override fun trackEvent(event: AnalyticsEvent, properties: AnalyticsPropertiesType) {
val bundle = Bundle()
properties.forEach {
bundle.putString(it.key, it.value.toString())
}
firebaseAnalytics.logEvent(event.name, bundle)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.mirego.kmp.boilerplate.app.bootstrap

import android.content.Context
import com.mirego.kmp.boilerplate.BuildConfig
import com.mirego.kmp.boilerplate.analytics.SharedAnalyticsConfiguration
import com.mirego.kmp.boilerplate.app.analytics.AndroidSharedAnalyticsService
import com.mirego.kmp.boilerplate.app.resources.AndroidImageProvider
import com.mirego.kmp.boilerplate.bootstrap.AppEnvironment
import com.mirego.kmp.boilerplate.bootstrap.Bootstrap
Expand Down Expand Up @@ -31,5 +33,11 @@ class AndroidBootstrap(context: Context) : Bootstrap {
imageProvider = AndroidImageProvider(),
textStyleProvider = DefaultTextStyleProvider()
)

val analyticsEnabled = !BuildConfig.DEBUG
SharedAnalyticsConfiguration.analyticsManager = AndroidSharedAnalyticsService(
context = context,
analyticsEnabled = analyticsEnabled
)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
package com.mirego.kmp.boilerplate.app.resources

import android.content.Context
import com.mirego.kmp.boilerplate.R
import com.mirego.kmp.boilerplate.viewmodel.common.SharedImageResource
import com.mirego.trikot.viewmodels.declarative.configuration.VMDImageProvider
import com.mirego.trikot.viewmodels.declarative.properties.VMDImageResource

class AndroidImageProvider : VMDImageProvider {
override fun resourceIdForResource(resource: VMDImageResource, context: Context) = null
override fun resourceIdForResource(resource: VMDImageResource, context: Context) = when (resource) {
is SharedImageResource -> when (resource) {
SharedImageResource.emptyPageIcon -> R.drawable.baseline_question_mark_24
SharedImageResource.errorPageIcon -> R.drawable.baseline_warning_24
SharedImageResource.imagePlaceholder -> R.drawable.baseline_image_24
SharedImageResource.closeIcon -> TODO()
}

else -> null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
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.graphics.ColorFilter
Expand All @@ -25,10 +26,11 @@ import com.mirego.trikot.viewmodels.declarative.compose.viewmodel.VMDImage
import com.mirego.trikot.viewmodels.declarative.compose.viewmodel.VMDText

@Composable
fun EmptyContentView(emptyViewModel: EmptyViewModel) {
fun EmptyContentView(emptyViewModel: EmptyViewModel, modifier: Modifier = Modifier) {
val viewModel: EmptyViewModel by emptyViewModel.observeAsState()
Column(
modifier = Modifier.fillMaxSize()
modifier = modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
VMDImage(
modifier = Modifier.size(55.dp),
Expand All @@ -39,13 +41,15 @@ fun EmptyContentView(emptyViewModel: EmptyViewModel) {
VMDText(
modifier = Modifier.padding(top = padding * 2),
viewModel = viewModel.title,
color = Color.White,
style = style(TextSize.LARGE_TITLE, TextWeight.REGULAR),
maxLines = 1
)

VMDText(
modifier = Modifier.padding(top = padding),
viewModel = viewModel.title,
viewModel = viewModel.message,
color = Color.White,
style = style(TextSize.BODY, TextWeight.REGULAR),
textAlign = TextAlign.Center
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.mirego.kmp.boilerplate.app.ui.common

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
Expand Down Expand Up @@ -34,12 +36,14 @@ import com.mirego.trikot.viewmodels.declarative.compose.viewmodel.VMDText

@Composable
fun ErrorView(errorViewModel: ErrorViewModel) {
val iconPadding = 4.dp
val viewModel: ErrorViewModel by errorViewModel.observeAsState()
Column(
modifier = Modifier
.statusBarsPadding()
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
VMDImage(
modifier = Modifier.size(55.dp),
Expand All @@ -48,7 +52,7 @@ fun ErrorView(errorViewModel: ErrorViewModel) {
)

VMDText(
modifier = Modifier.padding(top = padding * 2),
modifier = Modifier.padding(top = padding * 2 - iconPadding),
viewModel = viewModel.title,
style = style(TextSize.LARGE_TITLE, TextWeight.REGULAR),
color = Color.White,
Expand All @@ -66,12 +70,12 @@ fun ErrorView(errorViewModel: ErrorViewModel) {
VMDButton(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = padding)
.widthIn(max = 320.dp)
.padding(vertical = 12.dp)
.clip(RoundedCornerShape(16.dp))
.padding(top = padding * 2)
.padding(horizontal = padding * 2)
.clip(RoundedCornerShape(percent = 50))
.background(Color.Red)
.padding(top = padding * 2),
.padding(vertical = 12.dp),
viewModel = viewModel.retryButton,
) { content ->
Text(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.mirego.kmp.boilerplate.app.ui.common

import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import com.google.accompanist.placeholder.PlaceholderHighlight
import com.google.accompanist.placeholder.placeholder
import com.google.accompanist.placeholder.shimmer
import com.mirego.kmp.boilerplate.app.ui.theme.ShimmerBackground
import com.mirego.kmp.boilerplate.app.ui.theme.ShimmerHighlight

fun Modifier.loading(isLoading: Boolean) = this.then(
placeholder(
visible = isLoading,
highlight = PlaceholderHighlight.shimmer(highlightColor = Color.ShimmerHighlight),
color = Color.ShimmerBackground
)
)
Loading

0 comments on commit 2cefbfd

Please sign in to comment.