Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

📊 Re-enable and adapt Tracker to by dynamic on Android and static on iOS #608

Merged
merged 2 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions features/preference/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import extension.androidDependencies
import extension.commonDependencies
import extension.iosDependencies
import extension.setFrameworkBaseName

plugins {
Expand Down Expand Up @@ -30,6 +31,11 @@ kotlin {

androidDependencies {
implementation(libs.androidx.corektx)
implementation(projects.libraries.splitInstall)
}

iosDependencies {
implementation(projects.features.tracker)
}
}
android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ package com.escodro.preference.di

import com.escodro.preference.provider.AndroidAppInfoProvider
import com.escodro.preference.provider.AndroidBrowserProvider
import com.escodro.preference.provider.AndroidTrackerProvider
import com.escodro.preference.provider.AppInfoProvider
import com.escodro.preference.provider.BrowserProvider
import com.escodro.preference.provider.TrackerProvider
import org.koin.core.module.dsl.factoryOf
import org.koin.dsl.bind
import org.koin.dsl.module

actual val platformPreferenceModule = module {
factoryOf(::AndroidBrowserProvider) bind BrowserProvider::class
factoryOf(::AndroidAppInfoProvider) bind AppInfoProvider::class
factoryOf(::AndroidTrackerProvider) bind TrackerProvider::class
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.escodro.preference.provider

import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.compose.runtime.Composable
import com.escodro.splitinstall.LoadFeature

internal class AndroidTrackerProvider(private val context: Context) : TrackerProvider {

@Composable
override fun Content(onUpPress: () -> Unit) {
LoadFeature(
context = context,
featureName = FeatureTracker,
onDismiss = onUpPress,
) {
// Workaround to be able to use Dynamic Feature with Compose
// https://issuetracker.google.com/issues/183677219
val intent = Intent(Intent.ACTION_VIEW).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
data = Uri.parse(TrackerDeepLink)
`package` = context.packageName
}
context.startActivity(intent)
}
}

private companion object {
private const val FeatureTracker = "tracker"
private const val TrackerDeepLink = "app://com.escodro.tracker"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ val preferenceScreenModule = screenModule {
register<AlkaaDestinations.Preferences.OpenSource> {
OpenSourceScreen()
}
register<AlkaaDestinations.Preferences.Tracker> {
TrackerScreen()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.escodro.preference.navigation

import androidx.compose.runtime.Composable
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import com.escodro.preference.provider.TrackerProvider
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject

/**
* Tracker screen.
*/
internal class TrackerScreen : Screen, KoinComponent {

private val trackerProvider: TrackerProvider by inject()

@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
trackerProvider.Content(onUpPress = { navigator.pop() })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ fun PreferenceSection(
val screen = ScreenRegistry.get(AlkaaDestinations.Preferences.About)
navigator.push(screen)
},
onTrackerClick = { }, // TODO decide what to do with tracker,
onTrackerClick = {
val screen = ScreenRegistry.get(AlkaaDestinations.Preferences.Tracker)
navigator.push(screen)
},
onOpenSourceClick = {
val screen = ScreenRegistry.get(AlkaaDestinations.Preferences.OpenSource)
navigator.push(screen)
Expand All @@ -60,12 +63,12 @@ private fun PreferenceLoader(
}.collectAsState(initial = AppThemeOptions.SYSTEM)

PreferenceContent(
modifier = modifier,
onAboutClick = onAboutClick,
onTrackerClick = onTrackerClick,
onOpenSourceClick = onOpenSourceClick,
theme = theme,
onThemeUpdate = viewModel::updateTheme,
modifier = modifier,
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.escodro.preference.provider

import androidx.compose.runtime.Composable

/**
* Provides the Tracker feature information on each platform. Since this is an Android dynamic
* feature, it be always available for iOS.
*/
internal interface TrackerProvider {

/**
* Returns the Tracker feature content.
*/
@Composable
fun Content(onUpPress: () -> Unit)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import com.escodro.preference.provider.AppInfoProvider
import com.escodro.preference.provider.BrowserProvider
import com.escodro.preference.provider.IosAppInfoProvider
import com.escodro.preference.provider.IosBrowserProvider
import com.escodro.preference.provider.IosTrackerProvider
import com.escodro.preference.provider.TrackerProvider
import org.koin.core.module.dsl.factoryOf
import org.koin.dsl.bind
import org.koin.dsl.module

actual val platformPreferenceModule = module {
factoryOf(::IosBrowserProvider) bind BrowserProvider::class
factoryOf(::IosAppInfoProvider) bind AppInfoProvider::class
factoryOf(::IosTrackerProvider) bind TrackerProvider::class
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.escodro.preference.provider

import androidx.compose.runtime.Composable
import com.escodro.tracker.presentation.TrackerScreen

internal class IosTrackerProvider : TrackerProvider {

@Composable
override fun Content(onUpPress: () -> Unit) {
TrackerScreen(onUpPress = onUpPress)
}
}
66 changes: 32 additions & 34 deletions features/tracker/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,46 +1,44 @@
import extension.androidDependencies
import extension.commonDependencies
import extension.commonTestDependencies
import extension.setFrameworkBaseName

plugins {
id("com.escodro.android-dynamic")
alias(libs.plugins.compose)
}

android {
buildFeatures {
compose = true
}
kotlin {
setFrameworkBaseName("tracker")

composeOptions {
kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
}
commonDependencies {
implementation(projects.domain)
implementation(projects.libraries.designsystem)
implementation(projects.resources)
implementation(projects.libraries.di)

packaging {
resources.excludes.apply {
add("META-INF/AL2.0")
add("META-INF/LGPL2.1")
}
}
namespace = "com.escodro.tracker"
}
implementation(compose.runtime)
implementation(compose.material3)
implementation(compose.materialIconsExtended)

dependencies {
implementation(projects.domain)
implementation(projects.libraries.designsystem)

implementation(libs.koin.android)
implementation(libs.koin.compose)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.compose.activity)
implementation(libs.kotlinx.collections.immutable)
implementation(libs.koin.compose.jb)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.moko.resources.compose)
implementation(libs.moko.mvvm.compose)
}

implementation(libs.bundles.compose)
implementation(libs.kotlinx.collections.immutable)
commonTestDependencies {
implementation(kotlin("test"))
implementation(projects.libraries.test)
implementation(libs.kotlinx.datetime)
}

androidTestImplementation(libs.bundles.composetest) {
exclude(group = "androidx.core", module = "core-ktx")
exclude(group = "androidx.fragment", module = "fragment")
exclude(group = "androidx.customview", module = "customview")
exclude(group = "androidx.activity", module = "activity")
exclude(group = "androidx.lifecycle", module = "lifecycle-runtime")
androidDependencies {
implementation(libs.compose.activity)
}
}

testImplementation(projects.libraries.test)
testImplementation(libs.test.junit)
testImplementation(libs.kotlinx.datetime)
android {
namespace = "com.escodro.tracker"
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<application>
<activity
android:name=".presentation.TrackerActivity"
android:name=".TrackerActivity"
android:exported="true"
android:theme="@style/Theme.Alkaa">

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
package com.escodro.tracker.presentation
package com.escodro.tracker

import android.content.Context
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import com.escodro.designsystem.AlkaaTheme
import com.escodro.tracker.di.injectDynamicFeature
import com.escodro.tracker.presentation.TrackerScreen
import com.google.android.play.core.splitcompat.SplitCompat

internal class TrackerActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

injectDynamicFeature()

setContent {
AlkaaTheme {
TrackerSection(onUpPress = { finish() })
TrackerScreen(onUpPress = { finish() })
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.escodro.tracker.di

import com.escodro.di.viewModelDefinition
import com.escodro.tracker.mapper.TrackerMapper
import com.escodro.tracker.presentation.TrackerViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.context.loadKoinModules
import org.koin.core.module.dsl.factoryOf
import org.koin.dsl.module

/**
Expand All @@ -20,6 +21,6 @@ private val loadFeatureModules by lazy {
* Tracker dependency injection module.
*/
val trackerModule = module {
viewModel { TrackerViewModel(get(), get()) }
factory { TrackerMapper() }
viewModelDefinition { TrackerViewModel(get(), get()) }
factoryOf(::TrackerMapper)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.escodro.tracker.mapper

import android.graphics.Color
import com.escodro.designsystem.extensions.toArgbColor
import com.escodro.domain.model.TaskWithCategory
import com.escodro.tracker.model.Tracker
import kotlinx.collections.immutable.toImmutableList
Expand Down Expand Up @@ -31,7 +31,7 @@ internal class TrackerMapper {
val taskCount = map.value.size
return Tracker.CategoryInfo(
name = first.category?.name,
color = first.category?.color?.let { color -> Color.parseColor(color) },
color = first.category?.color?.toArgbColor(),
taskCount = taskCount,
percentage = taskCount.toFloat() / totalCount,
)
Expand Down