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

Make settings a a dynamic feature #174

Merged
merged 1 commit into from
Aug 25, 2019
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions client/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ android {
applicationId "com.jraska.github.client"
minSdkVersion 21
targetSdkVersion 28
versionName '0.15.7'
versionCode 47
versionName '0.16.0'
versionCode 48
multiDexEnabled true

testInstrumentationRunner "com.jraska.github.client.TestRunner"
Expand Down Expand Up @@ -62,7 +62,7 @@ android {
unitTests.returnDefaultValues = true
}

dynamicFeatures = [":feature:about"]
dynamicFeatures = [":feature:about", ":feature:settings"]
}

dependencies {
Expand All @@ -74,7 +74,7 @@ dependencies {
api project(':lib-dynamic-features')
api project(':feature:push')
api project(':feature:users')
api project(':feature:settings')
api project(':feature:settings_entrance')
api project(':feature:about_entrance')
api project(':feature:shortcuts')

Expand Down
4 changes: 2 additions & 2 deletions client/src/main/java/com/jraska/github/client/AppComponent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import com.jraska.github.client.http.HttpComponent
import com.jraska.github.client.identity.IdentityModule
import com.jraska.github.client.identity.IdentityProvider
import com.jraska.github.client.push.PushModule
import com.jraska.github.client.settings.SettingsModule
import com.jraska.github.client.settings.entrance.SettingsEntranceModule
import com.jraska.github.client.shortcuts.ShortcutsModule
import com.jraska.github.client.users.UsersModule
import dagger.BindsInstance
Expand All @@ -27,7 +27,7 @@ import dagger.Subcomponent
IdentityModule::class,
UsersModule::class,
PushModule::class,
SettingsModule::class,
SettingsEntranceModule::class,
AboutFeatureEntranceModule::class,
ShortcutsModule::class],
dependencies = [
Expand Down
4 changes: 3 additions & 1 deletion feature/settings/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apply plugin: 'com.android.library'
apply plugin: 'com.android.dynamic-feature'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
Expand All @@ -18,6 +18,8 @@ android {
dependencies {
api project(':core')
api project(':core-android')
implementation project(':lib-dynamic-features')
implementation project(':client')

api 'com.airbnb.android:epoxy:3.7.0'
api 'com.jraska:console:1.0.0'
Expand Down
13 changes: 12 additions & 1 deletion feature/settings/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
package="com.jraska.github.client.settings">

<application>
<activity android:name=".SettingsActivity"/>
</application>

<dist:module
dist:instant="false"
dist:title="@string/title_dynamic_feature_about">
<dist:delivery>
<dist:on-demand />
</dist:delivery>
<dist:fusing dist:include="true" />
</dist:module>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
package com.jraska.github.client.settings

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager
import com.airbnb.epoxy.SimpleEpoxyAdapter
import com.google.android.play.core.splitcompat.SplitCompat
import com.jraska.github.client.DynamicFeaturesComponent
import com.jraska.github.client.core.android.BaseActivity
import com.jraska.github.client.core.android.viewModel
import com.jraska.github.client.core.android.ViewModelFactory
import com.jraska.github.client.dynamicFeaturesComponent
import dagger.Component
import kotlinx.android.synthetic.main.activity_settings.toolbar
import kotlinx.android.synthetic.main.content_settings.settings_recycler

internal class SettingsActivity : BaseActivity() {
private val viewModel: SettingsViewModel by lazy { viewModel(SettingsViewModel::class.java) }
private val viewModel: SettingsViewModel by lazy {
ViewModelProviders.of(this, viewModelFactory()).get(SettingsViewModel::class.java)
}

override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase)
SplitCompat.install(this)
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -29,10 +43,18 @@ internal class SettingsActivity : BaseActivity() {
viewModel.onPurchaseSubmitted(value)
}

companion object {
fun start(inActivity: Activity) {
val intent = Intent(inActivity, SettingsActivity::class.java)
inActivity.startActivity(intent)
}
private fun viewModelFactory(): ViewModelProvider.Factory {
return DaggerSettingsComponent.builder()
.dynamicFeaturesComponent(dynamicFeaturesComponent())
.build()
.viewModelFactory()
}
}

@Component(
modules = [SettingsModule::class],
dependencies = [DynamicFeaturesComponent::class]
)
internal interface SettingsComponent {
fun viewModelFactory(): ViewModelFactory
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.jraska.github.client.settings

import androidx.annotation.Keep
import com.jraska.github.client.dynamicbase.DynamicFeature
import timber.log.Timber

@Keep // used by reflection
class SettingsFeature : DynamicFeature {
override fun onFeatureCreate() {
SetupConsoleLogging().onCreate()
Timber.i("Settings feature loaded")
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
package com.jraska.github.client.settings

import android.app.Activity
import androidx.lifecycle.ViewModel
import com.jraska.github.client.core.android.LinkLauncher
import com.jraska.github.client.core.android.OnAppCreate
import dagger.Module
import dagger.Provides
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import dagger.multibindings.IntoSet
import okhttp3.HttpUrl

@Module
object SettingsModule {
Expand All @@ -20,31 +15,4 @@ object SettingsModule {
internal fun provideUserDetailModel(viewModel: SettingsViewModel): ViewModel {
return viewModel
}

@JvmStatic
@Provides
@IntoSet
internal fun consoleLoggingSetup(): OnAppCreate {
return SetupConsoleLogging()
}

@JvmStatic
@Provides
@IntoSet
internal fun provideSettingsLauncher(): LinkLauncher {
return object : LinkLauncher {
override fun launch(inActivity: Activity, deepLink: HttpUrl): LinkLauncher.Result {
return if ("/settings" == deepLink.encodedPath) {
SettingsActivity.start(inActivity)
LinkLauncher.Result.LAUNCHED
} else {
LinkLauncher.Result.NOT_LAUNCHED
}
}

override fun priority(): LinkLauncher.Priority {
return LinkLauncher.Priority.EXACT_MATCH
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import com.jraska.github.client.analytics.AnalyticsEvent
import com.jraska.github.client.analytics.EventAnalytics
import javax.inject.Inject

internal class SettingsViewModel @Inject constructor(private val eventAnalytics: EventAnalytics) : ViewModel() {
internal class SettingsViewModel @Inject
constructor(
private val eventAnalytics: EventAnalytics
) : ViewModel() {
fun onPurchaseSubmitted(value: String) {
val money = value.toDoubleOrNull() ?: return

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.jraska.github.client.settings

import android.app.Application
import android.util.Log
import com.jraska.console.timber.ConsoleTree
import com.jraska.github.client.core.android.OnAppCreate
import timber.log.Timber

internal class SetupConsoleLogging : OnAppCreate {
override fun onCreate(app: Application) {
internal class SetupConsoleLogging {
fun onCreate() {
if (BuildConfig.DEBUG) {
Timber.plant(ConsoleTree.create())
} else {
Expand Down
1 change: 1 addition & 0 deletions feature/settings_entrance/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
25 changes: 25 additions & 0 deletions feature/settings_entrance/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 21
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {
api project(':core')
api project(':core-android')
implementation project(':lib-dynamic-features')

implementation 'com.google.dagger:dagger:2.24'
kapt 'com.google.dagger:dagger-compiler:2.24'
}
1 change: 1 addition & 0 deletions feature/settings_entrance/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<manifest package="com.jraska.github.client.settings.entrance" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.jraska.github.client.settings.entrance

import android.content.Context
import com.jraska.github.client.about.entrance.internal.DynamicSettingsLinkLauncher
import com.jraska.github.client.about.entrance.internal.ReflectiveSettingsFeatureProvider
import com.jraska.github.client.core.android.LinkLauncher
import com.jraska.github.client.dynamicbase.DynamicFeatureSpec
import dagger.Module
import dagger.Provides
import dagger.multibindings.IntoSet

@Module
object SettingsEntranceModule {
@JvmStatic
@Provides
@IntoSet
internal fun provideSettingsLauncher(launcher: DynamicSettingsLinkLauncher): LinkLauncher {
return launcher
}

@JvmStatic
@Provides
@IntoSet
internal fun featureProvider(context: Context): DynamicFeatureSpec {
val settingsFeatureName = context.getString(R.string.title_dynamic_feature_settings)
return DynamicFeatureSpec(settingsFeatureName, ReflectiveSettingsFeatureProvider())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.jraska.github.client.about.entrance.internal

import android.app.Activity
import android.content.Intent
import com.jraska.github.client.core.android.LinkLauncher
import com.jraska.github.client.core.android.TopActivityProvider
import com.jraska.github.client.dynamicbase.DynamicFeatureInstaller
import com.jraska.github.client.rx.AppSchedulers
import com.jraska.github.client.settings.entrance.R
import okhttp3.HttpUrl
import timber.log.Timber
import javax.inject.Inject

internal class DynamicSettingsLinkLauncher @Inject constructor(
val installer: DynamicFeatureInstaller,
val appSchedulers: AppSchedulers,
val topActivityProvider: TopActivityProvider
) : LinkLauncher {
override fun launch(inActivity: Activity, deepLink: HttpUrl): LinkLauncher.Result {
return if ("/settings" == deepLink.encodedPath) {
installAndLaunchSettingsFeature(inActivity)
LinkLauncher.Result.LAUNCHED
} else {
LinkLauncher.Result.NOT_LAUNCHED
}
}

override fun priority(): LinkLauncher.Priority = LinkLauncher.Priority.EXACT_MATCH

private fun installAndLaunchSettingsFeature(inActivity: Activity) {
val aboutFeature = inActivity.getString(R.string.title_dynamic_feature_settings)

installer.ensureInstalled(aboutFeature)
.subscribeOn(appSchedulers.io)
.observeOn(appSchedulers.mainThread)
.subscribe({
val activity = topActivityProvider.get()
activity.startActivity(launchIntent(activity))
}, { Timber.e(it) })
}

private fun launchIntent(inActivity: Activity): Intent {
return Intent().apply {
setClassName(inActivity.packageName, "com.jraska.github.client.settings.SettingsActivity")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.jraska.github.client.about.entrance.internal

import com.jraska.github.client.dynamicbase.DynamicFeature
import javax.inject.Provider

internal class ReflectiveSettingsFeatureProvider : Provider<DynamicFeature> {
override fun get(): DynamicFeature {
return Class.forName("com.jraska.github.client.settings.SettingsFeature").newInstance() as DynamicFeature
}
}
3 changes: 3 additions & 0 deletions feature/settings_entrance/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<resources>
<string name="title_dynamic_feature_settings">settings</string>
</resources>
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ include ':client',

':feature:users',
':feature:push',
':feature:settings_entrance',
':feature:settings',
':feature:about_entrance',
':feature:about',
Expand Down