From 1d25feadf9ac6ea0110aef7c75f9fc934b4d7858 Mon Sep 17 00:00:00 2001 From: Kevin Gorham Date: Mon, 6 Jan 2020 00:01:06 -0500 Subject: [PATCH] Fix dagger implementation by simplifying things and removing Dagger Android. Dagger Android is overly complex and confusing and Google admitted that they need to change it and simply its use. In the meantime, it is easier to just remove it and setup dagger the old way. --- app/build.gradle | 9 ++- .../java/cash/z/ecc/android/ZcashWalletApp.kt | 19 ++--- .../cash/z/ecc/android/di/AppComponent.kt | 45 ------------ .../java/cash/z/ecc/android/di/AppModule.kt | 15 ---- .../ecc/android/di/component/AppComponent.kt | 20 ++++++ .../di/component/MainActivitySubcomponent.kt | 45 ++++++++++++ .../di/{ => module}/AppBindingModule.kt | 2 +- .../cash/z/ecc/android/di/module/AppModule.kt | 22 ++++++ .../android/di/module/MainActivityModule.kt | 50 ++++++++++++++ .../ViewModelsModule.kt} | 61 ++++++++-------- .../ecc/android/di/viewmodel/ViewModelExt.kt | 36 ++++++++++ .../android/di/viewmodel/ViewModelFactory.kt | 23 +++++++ .../cash/z/ecc/android/ui/MainActivity.kt | 69 ++++--------------- .../z/ecc/android/ui/base/BaseFragment.kt | 5 +- .../android/ui/detail/WalletDetailFragment.kt | 11 --- .../z/ecc/android/ui/home/HomeFragment.kt | 28 +++----- .../ecc/android/ui/receive/ReceiveFragment.kt | 15 ---- .../android/ui/send/SendAddressFragment.kt | 18 ++--- .../android/ui/send/SendConfirmFragment.kt | 42 +++++------ .../ecc/android/ui/send/SendFinalFragment.kt | 22 ++---- .../z/ecc/android/ui/send/SendMemoFragment.kt | 22 ++---- .../z/ecc/android/ui/send/SendViewModel.kt | 6 +- .../z/ecc/android/ui/setup/BackupFragment.kt | 20 +----- .../z/ecc/android/ui/setup/LandingFragment.kt | 19 +---- .../android/ui/setup/WalletSetupViewModel.kt | 11 +-- .../java/cash/z/ecc/android/Dependencies.kt | 1 + gradle.properties | 2 + 27 files changed, 322 insertions(+), 316 deletions(-) delete mode 100644 app/src/main/java/cash/z/ecc/android/di/AppComponent.kt delete mode 100644 app/src/main/java/cash/z/ecc/android/di/AppModule.kt create mode 100644 app/src/main/java/cash/z/ecc/android/di/component/AppComponent.kt create mode 100644 app/src/main/java/cash/z/ecc/android/di/component/MainActivitySubcomponent.kt rename app/src/main/java/cash/z/ecc/android/di/{ => module}/AppBindingModule.kt (64%) create mode 100644 app/src/main/java/cash/z/ecc/android/di/module/AppModule.kt create mode 100644 app/src/main/java/cash/z/ecc/android/di/module/MainActivityModule.kt rename app/src/main/java/cash/z/ecc/android/di/{ViewModelModule.kt => module/ViewModelsModule.kt} (50%) create mode 100644 app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelExt.kt create mode 100644 app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelFactory.kt diff --git a/app/build.gradle b/app/build.gradle index 0328934..01b0f9e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,7 +72,13 @@ android { kotlinOptions { jvmTarget = "1.8" } - + kapt { + arguments { + arg 'dagger.fastInit', 'enabled' + arg 'dagger.fullBindingGraphValidation', 'ERROR' + arg 'dagger.gradle.incremental' + } + } applicationVariants.all { variant -> variant.outputs.all { outputFileName = "$archivesBaseName-v${defaultConfig.versionName}-${variant.buildType.name}.apk" @@ -96,6 +102,7 @@ dependencies { implementation Deps.AndroidX.CORE_KTX implementation Deps.AndroidX.CONSTRAINT_LAYOUT implementation Deps.AndroidX.Lifecycle.LIFECYCLE_RUNTIME_KTX + implementation Deps.AndroidX.Lifecycle.LIFECYCLE_EXTENSIONS implementation Deps.AndroidX.Navigation.FRAGMENT_KTX implementation Deps.AndroidX.Navigation.UI_KTX implementation "androidx.room:room-ktx:2.2.3" diff --git a/app/src/main/java/cash/z/ecc/android/ZcashWalletApp.kt b/app/src/main/java/cash/z/ecc/android/ZcashWalletApp.kt index 769d6be..84af5ba 100644 --- a/app/src/main/java/cash/z/ecc/android/ZcashWalletApp.kt +++ b/app/src/main/java/cash/z/ecc/android/ZcashWalletApp.kt @@ -1,18 +1,16 @@ package cash.z.ecc.android +import android.app.Application import android.content.Context import android.os.Build -import cash.z.ecc.android.di.DaggerAppComponent -import cash.z.ecc.android.feedback.FeedbackCoordinator +import cash.z.ecc.android.di.component.AppComponent +import cash.z.ecc.android.di.component.DaggerAppComponent import cash.z.wallet.sdk.ext.TroubleshootingTwig import cash.z.wallet.sdk.ext.Twig import cash.z.wallet.sdk.ext.twig -import dagger.android.AndroidInjector -import dagger.android.DaggerApplication -import javax.inject.Inject -class ZcashWalletApp : DaggerApplication() { +class ZcashWalletApp : Application() { var creationTime: Long = 0 private set @@ -25,17 +23,11 @@ class ZcashWalletApp : DaggerApplication() { // Setup handler for uncaught exceptions. super.onCreate() + component = DaggerAppComponent.factory().create(this) Thread.setDefaultUncaughtExceptionHandler(ExceptionReporter(Thread.getDefaultUncaughtExceptionHandler())) Twig.plant(TroubleshootingTwig()) } - /** - * Implement the HasActivityInjector behavior so that dagger knows which [AndroidInjector] to use. - */ - override fun applicationInjector(): AndroidInjector { - return DaggerAppComponent.factory().create(this) - } - override fun attachBaseContext(base: Context) { super.attachBaseContext(base) // MultiDex.install(this) @@ -43,6 +35,7 @@ class ZcashWalletApp : DaggerApplication() { companion object { lateinit var instance: ZcashWalletApp + lateinit var component: AppComponent } class ExceptionReporter(val ogHandler: Thread.UncaughtExceptionHandler) : Thread.UncaughtExceptionHandler { diff --git a/app/src/main/java/cash/z/ecc/android/di/AppComponent.kt b/app/src/main/java/cash/z/ecc/android/di/AppComponent.kt deleted file mode 100644 index fc2f176..0000000 --- a/app/src/main/java/cash/z/ecc/android/di/AppComponent.kt +++ /dev/null @@ -1,45 +0,0 @@ -package cash.z.ecc.android.di - -import cash.z.ecc.android.ZcashWalletApp -import cash.z.ecc.android.ui.MainActivityModule -import cash.z.ecc.android.ui.detail.WalletDetailFragmentModule -import cash.z.ecc.android.ui.home.HomeFragmentModule -import cash.z.ecc.android.ui.receive.ReceiveFragmentModule -import cash.z.ecc.android.ui.send.* -import cash.z.ecc.android.ui.setup.BackupFragmentModule -import cash.z.ecc.android.ui.setup.LandingFragmentModule -import dagger.BindsInstance -import dagger.Component -import dagger.android.AndroidInjector -import dagger.android.support.AndroidSupportInjectionModule -import javax.inject.Singleton - -@Singleton -@Component( - modules = [ - AndroidSupportInjectionModule::class, - - AppModule::class, - - // Activities - MainActivityModule::class, - - // Fragments - HomeFragmentModule::class, - ReceiveFragmentModule::class, - SendAddressFragmentModule::class, - SendMemoFragmentModule::class, - SendConfirmFragmentModule::class, - SendFinalFragmentModule::class, - WalletDetailFragmentModule::class, - LandingFragmentModule::class, - BackupFragmentModule::class - ] -) -interface AppComponent : AndroidInjector { - - @Component.Factory - interface Factory { - fun create(@BindsInstance application: ZcashWalletApp): AppComponent - } -} \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/di/AppModule.kt b/app/src/main/java/cash/z/ecc/android/di/AppModule.kt deleted file mode 100644 index d1cecfb..0000000 --- a/app/src/main/java/cash/z/ecc/android/di/AppModule.kt +++ /dev/null @@ -1,15 +0,0 @@ -package cash.z.ecc.android.di - -import android.content.Context -import cash.z.ecc.android.ZcashWalletApp -import dagger.Module -import dagger.Provides -import javax.inject.Singleton - -@Module(includes = [AppBindingModule::class, ViewModelModule::class]) -class AppModule { - - @Provides - @Singleton - fun provideAppContext(): Context = ZcashWalletApp.instance -} diff --git a/app/src/main/java/cash/z/ecc/android/di/component/AppComponent.kt b/app/src/main/java/cash/z/ecc/android/di/component/AppComponent.kt new file mode 100644 index 0000000..12e02bf --- /dev/null +++ b/app/src/main/java/cash/z/ecc/android/di/component/AppComponent.kt @@ -0,0 +1,20 @@ +package cash.z.ecc.android.di.component + +import cash.z.ecc.android.ZcashWalletApp +import cash.z.ecc.android.di.module.AppModule +import dagger.BindsInstance +import dagger.Component +import javax.inject.Singleton + +@Singleton +@Component(modules = [AppModule::class]) +interface AppComponent { + + // Subcomponents + fun mainActivityComponent(): MainActivitySubcomponent.Factory + + @Component.Factory + interface Factory { + fun create(@BindsInstance application: ZcashWalletApp): AppComponent + } +} \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/di/component/MainActivitySubcomponent.kt b/app/src/main/java/cash/z/ecc/android/di/component/MainActivitySubcomponent.kt new file mode 100644 index 0000000..e96809a --- /dev/null +++ b/app/src/main/java/cash/z/ecc/android/di/component/MainActivitySubcomponent.kt @@ -0,0 +1,45 @@ +package cash.z.ecc.android.di.component + +import androidx.fragment.app.FragmentActivity +import androidx.lifecycle.ViewModelProvider +import cash.z.ecc.android.di.annotation.ActivityScope +import cash.z.ecc.android.di.module.MainActivityModule +import cash.z.ecc.android.di.module.ViewModelsModule +import cash.z.ecc.android.ui.MainActivity +import cash.z.ecc.android.ui.detail.WalletDetailFragment +import cash.z.ecc.android.ui.home.HomeFragment +import cash.z.ecc.android.ui.receive.ReceiveFragment +import cash.z.ecc.android.ui.send.SendAddressFragment +import cash.z.ecc.android.ui.send.SendConfirmFragment +import cash.z.ecc.android.ui.send.SendFinalFragment +import cash.z.ecc.android.ui.send.SendMemoFragment +import cash.z.ecc.android.ui.setup.BackupFragment +import cash.z.ecc.android.ui.setup.LandingFragment +import dagger.BindsInstance +import dagger.Subcomponent + +@ActivityScope +@Subcomponent(modules = [MainActivityModule::class, ViewModelsModule::class]) +interface MainActivitySubcomponent { + + fun inject(activity: MainActivity) + + // Fragments + fun inject(fragment: HomeFragment) + fun inject(fragment: ReceiveFragment) + fun inject(fragment: SendAddressFragment) + fun inject(fragment: SendMemoFragment) + fun inject(fragment: SendConfirmFragment) + fun inject(fragment: SendFinalFragment) + fun inject(fragment: WalletDetailFragment) + fun inject(fragment: LandingFragment) + fun inject(fragment: BackupFragment) + + fun viewModels(): ViewModelProvider + fun viewModelFactory(): ViewModelProvider.Factory + + @Subcomponent.Factory + interface Factory { + fun create(@BindsInstance activity: FragmentActivity): MainActivitySubcomponent + } +} \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/di/AppBindingModule.kt b/app/src/main/java/cash/z/ecc/android/di/module/AppBindingModule.kt similarity index 64% rename from app/src/main/java/cash/z/ecc/android/di/AppBindingModule.kt rename to app/src/main/java/cash/z/ecc/android/di/module/AppBindingModule.kt index eb5a0ad..8ebfbf0 100644 --- a/app/src/main/java/cash/z/ecc/android/di/AppBindingModule.kt +++ b/app/src/main/java/cash/z/ecc/android/di/module/AppBindingModule.kt @@ -1,4 +1,4 @@ -package cash.z.ecc.android.di +package cash.z.ecc.android.di.module import dagger.Module diff --git a/app/src/main/java/cash/z/ecc/android/di/module/AppModule.kt b/app/src/main/java/cash/z/ecc/android/di/module/AppModule.kt new file mode 100644 index 0000000..abeaadd --- /dev/null +++ b/app/src/main/java/cash/z/ecc/android/di/module/AppModule.kt @@ -0,0 +1,22 @@ +package cash.z.ecc.android.di.module + +import android.content.ClipboardManager +import android.content.Context +import cash.z.ecc.android.ZcashWalletApp +import cash.z.ecc.android.di.component.MainActivitySubcomponent +import dagger.Module +import dagger.Provides +import javax.inject.Singleton + +@Module(subcomponents = [MainActivitySubcomponent::class]) +class AppModule { + + @Provides + @Singleton + fun provideAppContext(): Context = ZcashWalletApp.instance + + @Provides + @Singleton + fun provideClipboard(context: Context) = + context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager +} diff --git a/app/src/main/java/cash/z/ecc/android/di/module/MainActivityModule.kt b/app/src/main/java/cash/z/ecc/android/di/module/MainActivityModule.kt new file mode 100644 index 0000000..db78bd4 --- /dev/null +++ b/app/src/main/java/cash/z/ecc/android/di/module/MainActivityModule.kt @@ -0,0 +1,50 @@ +package cash.z.ecc.android.di.module + +import androidx.fragment.app.FragmentActivity +import androidx.lifecycle.ViewModelProvider +import cash.z.ecc.android.di.annotation.ActivityScope +import cash.z.ecc.android.feedback.* +import dagger.Module +import dagger.Provides +import dagger.multibindings.IntoSet + +@Module +class MainActivityModule { + + @Provides + @ActivityScope + fun provideViewModelProvider(activity: FragmentActivity, factory: ViewModelProvider.Factory): ViewModelProvider { + return ViewModelProvider(activity, factory) + } + + @Provides + @ActivityScope + fun provideFeedback(): Feedback = Feedback() + + @Provides + @ActivityScope + fun provideFeedbackCoordinator( + feedback: Feedback, + defaultObservers: Set<@JvmSuppressWildcards FeedbackCoordinator.FeedbackObserver> + ): FeedbackCoordinator = FeedbackCoordinator(feedback, defaultObservers) + + + // + // Default Feedback Observer Set + // + + @Provides + @ActivityScope + @IntoSet + fun provideFeedbackFile(): FeedbackCoordinator.FeedbackObserver = FeedbackFile() + + @Provides + @ActivityScope + @IntoSet + fun provideFeedbackConsole(): FeedbackCoordinator.FeedbackObserver = FeedbackConsole() + + @Provides + @ActivityScope + @IntoSet + fun provideFeedbackMixpanel(): FeedbackCoordinator.FeedbackObserver = FeedbackMixpanel() +} diff --git a/app/src/main/java/cash/z/ecc/android/di/ViewModelModule.kt b/app/src/main/java/cash/z/ecc/android/di/module/ViewModelsModule.kt similarity index 50% rename from app/src/main/java/cash/z/ecc/android/di/ViewModelModule.kt rename to app/src/main/java/cash/z/ecc/android/di/module/ViewModelsModule.kt index 074f4b9..3d23355 100644 --- a/app/src/main/java/cash/z/ecc/android/di/ViewModelModule.kt +++ b/app/src/main/java/cash/z/ecc/android/di/module/ViewModelsModule.kt @@ -1,52 +1,55 @@ -package cash.z.ecc.android.di +package cash.z.ecc.android.di.module + import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import cash.z.ecc.android.di.annotation.ActivityScope import cash.z.ecc.android.di.annotation.ViewModelKey +import cash.z.ecc.android.di.viewmodel.ViewModelFactory import cash.z.ecc.android.ui.home.HomeViewModel import cash.z.ecc.android.ui.send.SendViewModel import cash.z.ecc.android.ui.setup.WalletSetupViewModel import dagger.Binds import dagger.Module import dagger.multibindings.IntoMap -import javax.inject.Inject -import javax.inject.Provider -import javax.inject.Singleton @Module -abstract class ViewModelModule { +abstract class ViewModelsModule { - @Binds - abstract fun bindViewModelFactory(implementation: ViewModelFactory): ViewModelProvider.Factory + // + // Activity View Models + // + @ActivityScope @Binds @IntoMap @ViewModelKey(WalletSetupViewModel::class) - abstract fun bindWalletSetupViewModel(implementation: WalletSetupViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(HomeViewModel::class) - abstract fun bindHomeViewModel(implementation: HomeViewModel): ViewModel + abstract fun bindWalletSetupViewModel(implementation: WalletSetupViewModel): ViewModel + @ActivityScope @Binds @IntoMap @ViewModelKey(SendViewModel::class) - abstract fun bindSendViewModel(implementation: SendViewModel): ViewModel -} + abstract fun bindSendViewModel(implementation: SendViewModel): ViewModel + + + // + // Fragment View Models + // + + @ActivityScope + @Binds + @IntoMap + @ViewModelKey(HomeViewModel::class) + abstract fun bindHomeViewModel(implementation: HomeViewModel): ViewModel + + + // + // View Model Helpers + // + + @ActivityScope + @Binds + abstract fun bindViewModelFactory(implementation: ViewModelFactory): ViewModelProvider.Factory -@Singleton -class ViewModelFactory @Inject constructor( - private val creators: Map, @JvmSuppressWildcards Provider> -) : ViewModelProvider.Factory { - override fun create(modelClass: Class): T { - val creator = creators[modelClass] ?: creators.entries.firstOrNull { - modelClass.isAssignableFrom(it.key) - }?.value ?: throw IllegalArgumentException( - "No map entry found for ${modelClass.canonicalName}." + - " Verify that this ViewModel has been added to the ViewModelModule." - ) - @Suppress("UNCHECKED_CAST") - return creator.get() as T - } } \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelExt.kt b/app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelExt.kt new file mode 100644 index 0000000..827dec3 --- /dev/null +++ b/app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelExt.kt @@ -0,0 +1,36 @@ +package cash.z.ecc.android.di.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import cash.z.ecc.android.ui.MainActivity +import cash.z.ecc.android.ui.base.BaseFragment + + +inline fun MainActivity.viewModel() = object : Lazy { + val cached: VM? = null + override fun isInitialized(): Boolean = cached != null + override val value: VM get() { + return cached ?: component.viewModels()[VM::class.java] + } +} + +inline fun BaseFragment<*>.viewModel() = object : Lazy { + val cached: VM? = null + override fun isInitialized(): Boolean = cached != null + override val value: VM get() { + return if (cached != null) cached else { + val factory = mainActivity?.component?.viewModelFactory() + ?: throw IllegalStateException("Error: mainActivity should not be null by the time the ${VM::class.java.simpleName} viewmodel is lazily accessed!") + ViewModelProvider(this@viewModel, factory)[VM::class.java] + } + } +} + +inline fun BaseFragment<*>.activityViewModel() = object : Lazy { + val cached: VM? = null + override fun isInitialized(): Boolean = cached != null + override val value: VM get() { + return cached ?: mainActivity?.component?.viewModels()?.get(VM::class.java) + ?: throw IllegalStateException("Error: mainActivity should not be null by the time the ${VM::class.java.simpleName} activityViewModel is lazily accessed!") + } +} \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelFactory.kt b/app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelFactory.kt new file mode 100644 index 0000000..2f0a0b4 --- /dev/null +++ b/app/src/main/java/cash/z/ecc/android/di/viewmodel/ViewModelFactory.kt @@ -0,0 +1,23 @@ +package cash.z.ecc.android.di.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import cash.z.ecc.android.di.annotation.ActivityScope +import javax.inject.Inject +import javax.inject.Provider + +@ActivityScope +class ViewModelFactory @Inject constructor( + private val creators: Map, @JvmSuppressWildcards Provider> +) : ViewModelProvider.Factory { + override fun create(modelClass: Class): T { + val creator = creators[modelClass] ?: creators.entries.firstOrNull { + modelClass.isAssignableFrom(it.key) + }?.value ?: throw IllegalArgumentException( + "No map entry found for ${modelClass.canonicalName}." + + " Verify that this ViewModel has been added to the ViewModelModule." + ) + @Suppress("UNCHECKED_CAST") + return creator.get() as T + } +} \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/ui/MainActivity.kt b/app/src/main/java/cash/z/ecc/android/ui/MainActivity.kt index ce92237..459b9ae 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/MainActivity.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/MainActivity.kt @@ -13,15 +13,15 @@ import android.view.ViewGroup import android.view.WindowManager import android.view.inputmethod.InputMethodManager import android.widget.Toast -import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity import androidx.core.content.getSystemService -import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController import androidx.navigation.findNavController import cash.z.ecc.android.R import cash.z.ecc.android.ZcashWalletApp -import cash.z.ecc.android.di.annotation.ActivityScope +import cash.z.ecc.android.di.component.MainActivitySubcomponent +import cash.z.ecc.android.di.viewmodel.viewModel import cash.z.ecc.android.feedback.* import cash.z.ecc.android.feedback.Report.NonUserAction.FEEDBACK_STOPPED import cash.z.ecc.android.feedback.Report.NonUserAction.SYNC_START @@ -30,16 +30,11 @@ import cash.z.wallet.sdk.Initializer import cash.z.wallet.sdk.Synchronizer import cash.z.wallet.sdk.ext.twig import com.google.android.material.snackbar.Snackbar -import dagger.Module -import dagger.Provides -import dagger.android.ContributesAndroidInjector -import dagger.android.support.DaggerAppCompatActivity -import dagger.multibindings.IntoSet import kotlinx.coroutines.launch import javax.inject.Inject -class MainActivity : DaggerAppCompatActivity() { +class MainActivity : AppCompatActivity() { private var syncInit: (() -> Unit)? = null @@ -50,21 +45,26 @@ class MainActivity : DaggerAppCompatActivity() { lateinit var feedbackCoordinator: FeedbackCoordinator @Inject - lateinit var viewModelFactory: ViewModelProvider.Factory + lateinit var clipboard: ClipboardManager - val sendViewModel: SendViewModel by viewModels { viewModelFactory } + val sendViewModel: SendViewModel by viewModel() - lateinit var navController: NavController private val mediaPlayer: MediaPlayer = MediaPlayer() private var snackbar: Snackbar? = null + lateinit var navController: NavController + lateinit var synchronizer: Synchronizer - val clipboard get() = (getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager) + lateinit var component: MainActivitySubcomponent + override fun onCreate(savedInstanceState: Bundle?) { + component = ZcashWalletApp.component.mainActivityComponent().create(this).also { + it.inject(this) + } super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) initNavigation() @@ -223,46 +223,3 @@ class MainActivity : DaggerAppCompatActivity() { } } } - -@Module -abstract class MainActivityModule { - @ActivityScope - @ContributesAndroidInjector(modules = [MainActivityProviderModule::class]) - abstract fun contributeActivity(): MainActivity - -} - -@Module -class MainActivityProviderModule { - - @Provides - @ActivityScope - fun provideFeedback(): Feedback = Feedback() - - @Provides - @ActivityScope - fun provideFeedbackCoordinator( - feedback: Feedback, - defaultObservers: Set<@JvmSuppressWildcards FeedbackCoordinator.FeedbackObserver> - ): FeedbackCoordinator = FeedbackCoordinator(feedback, defaultObservers) - - - // - // Default Feedback Observer Set - // - - @Provides - @ActivityScope - @IntoSet - fun provideFeedbackFile(): FeedbackCoordinator.FeedbackObserver = FeedbackFile() - - @Provides - @ActivityScope - @IntoSet - fun provideFeedbackConsole(): FeedbackCoordinator.FeedbackObserver = FeedbackConsole() - - @Provides - @ActivityScope - @IntoSet - fun provideFeedbackMixpanel(): FeedbackCoordinator.FeedbackObserver = FeedbackMixpanel() -} \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/ui/base/BaseFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/base/BaseFragment.kt index 12e7598..4e45d90 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/base/BaseFragment.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/base/BaseFragment.kt @@ -5,17 +5,16 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.annotation.NonNull +import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.viewbinding.ViewBinding import cash.z.ecc.android.ui.MainActivity -import dagger.android.support.DaggerFragment import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel -import kotlin.coroutines.coroutineContext -abstract class BaseFragment : DaggerFragment() { +abstract class BaseFragment : Fragment() { val mainActivity: MainActivity? get() = activity as MainActivity? lateinit var binding: T diff --git a/app/src/main/java/cash/z/ecc/android/ui/detail/WalletDetailFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/detail/WalletDetailFragment.kt index c1bd601..83f25ae 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/detail/WalletDetailFragment.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/detail/WalletDetailFragment.kt @@ -8,15 +8,12 @@ import androidx.paging.PagedList import androidx.recyclerview.widget.LinearLayoutManager import cash.z.ecc.android.R import cash.z.ecc.android.databinding.FragmentDetailBinding -import cash.z.ecc.android.di.annotation.FragmentScope import cash.z.ecc.android.ext.onClick import cash.z.ecc.android.ext.onClickNavUp import cash.z.ecc.android.feedback.FeedbackFile import cash.z.ecc.android.ui.base.BaseFragment import cash.z.wallet.sdk.entity.ConfirmedTransaction import cash.z.wallet.sdk.ext.twig -import dagger.Module -import dagger.android.ContributesAndroidInjector import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import okio.Okio @@ -96,12 +93,4 @@ class WalletDetailFragment : BaseFragment() { return it.readUtf8() } } -} - - -@Module -abstract class WalletDetailFragmentModule { - @FragmentScope - @ContributesAndroidInjector - abstract fun contributeFragment(): WalletDetailFragment } \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/ui/home/HomeFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/home/HomeFragment.kt index 4409734..3b2b4af 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/home/HomeFragment.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/home/HomeFragment.kt @@ -6,17 +6,17 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.widget.TextView -import androidx.fragment.app.activityViewModels -import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import cash.z.ecc.android.R import cash.z.ecc.android.databinding.FragmentHomeBinding -import cash.z.ecc.android.di.annotation.FragmentScope +import cash.z.ecc.android.di.viewmodel.activityViewModel +import cash.z.ecc.android.di.viewmodel.viewModel import cash.z.ecc.android.ext.disabledIf import cash.z.ecc.android.ext.goneIf import cash.z.ecc.android.ext.onClickNavTo import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.home.HomeFragment.BannerAction.* +import cash.z.ecc.android.ui.send.SendViewModel import cash.z.ecc.android.ui.setup.WalletSetupViewModel import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.NO_SEED import cash.z.wallet.sdk.SdkSynchronizer @@ -26,24 +26,19 @@ import cash.z.wallet.sdk.ext.convertZecToZatoshi import cash.z.wallet.sdk.ext.safelyConvertToBigDecimal import cash.z.wallet.sdk.ext.twig import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.Module -import dagger.android.ContributesAndroidInjector import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.flow.* import kotlinx.coroutines.isActive import kotlinx.coroutines.launch -import javax.inject.Inject class HomeFragment : BaseFragment() { private lateinit var numberPad: List private lateinit var uiModel: HomeViewModel.UiModel - @Inject - lateinit var viewModelFactory: ViewModelProvider.Factory - - private val walletSetup: WalletSetupViewModel by activityViewModels { viewModelFactory } - private val viewModel: HomeViewModel by activityViewModels { viewModelFactory } + private val walletSetup: WalletSetupViewModel by activityViewModel() + private val sendViewModel: SendViewModel by activityViewModel() + private val viewModel: HomeViewModel by viewModel() private val _typedChars = ConflatedBroadcastChannel() private val typedChars = _typedChars.asFlow() @@ -58,6 +53,7 @@ class HomeFragment : BaseFragment() { override fun onAttach(context: Context) { twig("HomeFragment.onAttach") + mainActivity?.component?.inject(this) super.onAttach(context) // call initSync either now or later (after initializing DBs with newly created seed) @@ -178,7 +174,7 @@ class HomeFragment : BaseFragment() { fun setSendAmount(amount: String) { binding.textSendAmount.text = "\$$amount" - mainActivity?.sendViewModel?.zatoshiAmount = amount.safelyConvertToBigDecimal().convertZecToZatoshi() + sendViewModel.zatoshiAmount = amount.safelyConvertToBigDecimal().convertZecToZatoshi() binding.buttonSend.disabledIf(amount == "0") } @@ -343,12 +339,4 @@ class HomeFragment : BaseFragment() { super.onDetach() twig("HomeFragment.onDetach") } -} - - -@Module -abstract class HomeFragmentModule { - @FragmentScope - @ContributesAndroidInjector - abstract fun contributeFragment(): HomeFragment } \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/ui/receive/ReceiveFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/receive/ReceiveFragment.kt index 5711695..53d1fac 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/receive/ReceiveFragment.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/receive/ReceiveFragment.kt @@ -8,21 +8,14 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.widget.TextView -import androidx.lifecycle.lifecycleScope import cash.z.android.qrecycler.QRecycler import cash.z.ecc.android.databinding.FragmentReceiveBinding -import cash.z.ecc.android.di.annotation.FragmentScope -import cash.z.ecc.android.ext.onClickNavTo import cash.z.ecc.android.ext.onClickNavUp import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.util.AddressPartNumberSpan import cash.z.wallet.sdk.ext.twig -import dagger.Module -import dagger.android.ContributesAndroidInjector import kotlinx.android.synthetic.main.fragment_receive.* import kotlinx.coroutines.launch -import kotlin.math.floor -import kotlin.math.round import kotlin.math.roundToInt class ReceiveFragment : BaseFragment() { @@ -97,12 +90,4 @@ class ReceiveFragment : BaseFragment() { addressParts[index].text = textSpan } -} - - -@Module -abstract class ReceiveFragmentModule { - @FragmentScope - @ContributesAndroidInjector - abstract fun contributeFragment(): ReceiveFragment } \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/ui/send/SendAddressFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/send/SendAddressFragment.kt index 69abc5a..a7ff187 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/send/SendAddressFragment.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/send/SendAddressFragment.kt @@ -9,6 +9,7 @@ import android.view.inputmethod.EditorInfo import cash.z.ecc.android.R import cash.z.ecc.android.databinding.FragmentSendAddressBinding import cash.z.ecc.android.di.annotation.FragmentScope +import cash.z.ecc.android.di.viewmodel.viewModel import cash.z.ecc.android.ext.goneIf import cash.z.ecc.android.ext.onClickNavBack import cash.z.ecc.android.ui.base.BaseFragment @@ -16,10 +17,13 @@ import cash.z.wallet.sdk.ext.convertZatoshiToZecString import cash.z.wallet.sdk.ext.twig import dagger.Module import dagger.android.ContributesAndroidInjector +import javax.inject.Inject class SendAddressFragment : BaseFragment(), ClipboardManager.OnPrimaryClipChangedListener { + val sendViewModel: SendViewModel by viewModel() + override fun inflate(inflater: LayoutInflater): FragmentSendAddressBinding = FragmentSendAddressBinding.inflate(inflater) @@ -35,7 +39,7 @@ class SendAddressFragment : BaseFragment(), binding.textBannerMessage.setOnClickListener { onPaste() } - binding.textAmount.text = "Sending ${mainActivity?.sendViewModel?.zatoshiAmount.convertZatoshiToZecString(8)} ZEC" + binding.textAmount.text = "Sending ${sendViewModel.zatoshiAmount.convertZatoshiToZecString(8)} ZEC" binding.inputZcashAddress.setOnEditorActionListener { v, actionId, event -> if (actionId == EditorInfo.IME_ACTION_DONE) { onAddAddress() @@ -47,7 +51,7 @@ class SendAddressFragment : BaseFragment(), } private fun onAddAddress() { - mainActivity?.sendViewModel?.toAddress = binding.inputZcashAddress.text.toString() + sendViewModel.toAddress = binding.inputZcashAddress.text.toString() mainActivity?.navController?.navigate(R.id.action_nav_send_address_to_send_memo) } @@ -102,12 +106,4 @@ class SendAddressFragment : BaseFragment(), private fun ClipboardManager.text(): CharSequence = primaryClip!!.getItemAt(0).coerceToText(mainActivity) -} - - -@Module -abstract class SendAddressFragmentModule { - @FragmentScope - @ContributesAndroidInjector - abstract fun contributeFragment(): SendAddressFragment -} +} \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/ui/send/SendConfirmFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/send/SendConfirmFragment.kt index de0b212..aa88936 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/send/SendConfirmFragment.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/send/SendConfirmFragment.kt @@ -6,48 +6,38 @@ import android.view.View import androidx.lifecycle.lifecycleScope import cash.z.ecc.android.R import cash.z.ecc.android.databinding.FragmentSendConfirmBinding -import cash.z.ecc.android.di.annotation.FragmentScope +import cash.z.ecc.android.di.viewmodel.viewModel import cash.z.ecc.android.ext.goneIf import cash.z.ecc.android.ext.onClickNavBack -import cash.z.ecc.android.ui.MainActivity import cash.z.ecc.android.ui.base.BaseFragment import cash.z.wallet.sdk.ext.abbreviatedAddress import cash.z.wallet.sdk.ext.convertZatoshiToZecString -import dagger.Module -import dagger.android.ContributesAndroidInjector import kotlinx.coroutines.launch class SendConfirmFragment : BaseFragment() { + + val sendViewModel: SendViewModel by viewModel() + override fun inflate(inflater: LayoutInflater): FragmentSendConfirmBinding = FragmentSendConfirmBinding.inflate(inflater) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - mainActivity?.apply { - binding.buttonNext.setOnClickListener { - onSend() - } - binding.backButtonHitArea.onClickNavBack() - mainActivity?.lifecycleScope?.launch { - binding.textConfirmation.text = - "Send ${sendViewModel?.zatoshiAmount.convertZatoshiToZecString(8)} ZEC to ${sendViewModel?.toAddress.abbreviatedAddress()}?" - } - sendViewModel.memo.trim().isNotEmpty().let { hasMemo -> - binding.radioIncludeAddress.isChecked = hasMemo - binding.radioIncludeAddress.goneIf(!hasMemo) - } + binding.buttonNext.setOnClickListener { + onSend() + } + binding.backButtonHitArea.onClickNavBack() + mainActivity?.lifecycleScope?.launch { + binding.textConfirmation.text = + "Send ${sendViewModel.zatoshiAmount.convertZatoshiToZecString(8)} ZEC to ${sendViewModel?.toAddress.abbreviatedAddress()}?" + } + sendViewModel.memo.trim().isNotEmpty().let { hasMemo -> + binding.radioIncludeAddress.isChecked = hasMemo + binding.radioIncludeAddress.goneIf(!hasMemo) } } private fun onSend() { mainActivity?.navController?.navigate(R.id.action_nav_send_confirm_to_send_final) } -} - - -@Module -abstract class SendConfirmFragmentModule { - @FragmentScope - @ContributesAndroidInjector - abstract fun contributeFragment(): SendConfirmFragment -} +} \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/ui/send/SendFinalFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/send/SendFinalFragment.kt index ff8ea1e..a064a0b 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/send/SendFinalFragment.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/send/SendFinalFragment.kt @@ -7,23 +7,23 @@ import android.view.View import androidx.lifecycle.lifecycleScope import cash.z.ecc.android.R import cash.z.ecc.android.databinding.FragmentSendFinalBinding -import cash.z.ecc.android.di.annotation.FragmentScope +import cash.z.ecc.android.di.viewmodel.viewModel import cash.z.ecc.android.ext.goneIf import cash.z.ecc.android.ui.base.BaseFragment import cash.z.wallet.sdk.entity.* import cash.z.wallet.sdk.ext.abbreviatedAddress import cash.z.wallet.sdk.ext.convertZatoshiToZecString import cash.z.wallet.sdk.ext.twig -import dagger.Module -import dagger.android.ContributesAndroidInjector import kotlinx.coroutines.delay import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import kotlin.math.min import kotlin.random.Random class SendFinalFragment : BaseFragment() { + + val sendViewModel: SendViewModel by viewModel() + override fun inflate(inflater: LayoutInflater): FragmentSendFinalBinding = FragmentSendFinalBinding.inflate(inflater) @@ -36,8 +36,8 @@ class SendFinalFragment : BaseFragment() { onExit() } binding.textConfirmation.text = - "Sending ${mainActivity?.sendViewModel?.zatoshiAmount.convertZatoshiToZecString(8)} ZEC to ${mainActivity?.sendViewModel?.toAddress?.abbreviatedAddress()}" - mainActivity?.sendViewModel?.memo?.trim()?.isNotEmpty()?.let { hasMemo -> + "Sending ${sendViewModel.zatoshiAmount.convertZatoshiToZecString(8)} ZEC to ${sendViewModel.toAddress.abbreviatedAddress()}" + sendViewModel.memo?.trim()?.isNotEmpty()?.let { hasMemo -> binding.radioIncludeAddress.isChecked = hasMemo binding.radioIncludeAddress.goneIf(!hasMemo) } @@ -92,12 +92,4 @@ class SendFinalFragment : BaseFragment() { private fun onExit() { mainActivity?.navController?.popBackStack(R.id.send_navigation, true) } -} - - -@Module -abstract class SendFinalFragmentModule { - @FragmentScope - @ContributesAndroidInjector - abstract fun contributeFragment(): SendFinalFragment -} +} \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/ui/send/SendMemoFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/send/SendMemoFragment.kt index 39a8a26..7abe80d 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/send/SendMemoFragment.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/send/SendMemoFragment.kt @@ -6,14 +6,14 @@ import android.view.View import android.view.inputmethod.EditorInfo import cash.z.ecc.android.R import cash.z.ecc.android.databinding.FragmentSendMemoBinding -import cash.z.ecc.android.di.annotation.FragmentScope +import cash.z.ecc.android.di.viewmodel.viewModel import cash.z.ecc.android.ext.onClickNavBack -import cash.z.ecc.android.ext.onClickNavUp import cash.z.ecc.android.ui.base.BaseFragment -import dagger.Module -import dagger.android.ContributesAndroidInjector class SendMemoFragment : BaseFragment() { + + val sendViewModel: SendViewModel by viewModel() + override fun inflate(inflater: LayoutInflater): FragmentSendMemoBinding = FragmentSendMemoBinding.inflate(inflater) @@ -24,7 +24,7 @@ class SendMemoFragment : BaseFragment() { } binding.buttonSkip.setOnClickListener { binding.inputMemo.setText("") - mainActivity?.sendViewModel?.memo = "" + sendViewModel.memo = "" mainActivity?.navController?.navigate(R.id.action_nav_send_memo_to_send_confirm) } binding.backButtonHitArea.onClickNavBack() @@ -47,15 +47,7 @@ class SendMemoFragment : BaseFragment() { } private fun onAddMemo() { - mainActivity?.sendViewModel?.memo = binding.inputMemo.text.toString() + sendViewModel.memo = binding.inputMemo.text.toString() mainActivity?.navController?.navigate(R.id.action_nav_send_memo_to_send_confirm) } -} - - -@Module -abstract class SendMemoFragmentModule { - @FragmentScope - @ContributesAndroidInjector - abstract fun contributeFragment(): SendMemoFragment -} +} \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/ui/send/SendViewModel.kt b/app/src/main/java/cash/z/ecc/android/ui/send/SendViewModel.kt index 5040c5d..cd6bd22 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/send/SendViewModel.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/send/SendViewModel.kt @@ -11,7 +11,11 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.onEach import javax.inject.Inject -class SendViewModel @Inject constructor(var lockBox: LockBox) : ViewModel() { +class SendViewModel @Inject constructor() : ViewModel() { + + @Inject + lateinit var lockBox: LockBox + fun send(synchronizer: Synchronizer): Flow { val keys = (synchronizer as SdkSynchronizer).rustBackend!!.deriveSpendingKeys( lockBox.getBytes(WalletSetupViewModel.LockBoxKey.SEED)!! diff --git a/app/src/main/java/cash/z/ecc/android/ui/setup/BackupFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/setup/BackupFragment.kt index 9dc5cb6..36a9541 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/setup/BackupFragment.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/setup/BackupFragment.kt @@ -8,13 +8,11 @@ import android.view.LayoutInflater import android.view.View import android.widget.TextView import android.widget.Toast -import androidx.fragment.app.activityViewModels -import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import cash.z.ecc.android.R import cash.z.ecc.android.ZcashWalletApp import cash.z.ecc.android.databinding.FragmentBackupBinding -import cash.z.ecc.android.di.annotation.FragmentScope +import cash.z.ecc.android.di.viewmodel.viewModel import cash.z.ecc.android.feedback.Report.MetricType.SEED_PHRASE_LOADED import cash.z.ecc.android.feedback.measure import cash.z.ecc.android.lockbox.LockBox @@ -23,20 +21,14 @@ import cash.z.ecc.android.ui.setup.WalletSetupViewModel.LockBoxKey import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.SEED_WITH_BACKUP import cash.z.ecc.android.ui.util.AddressPartNumberSpan import cash.z.ecc.kotlin.mnemonic.Mnemonics -import dagger.Module -import dagger.android.ContributesAndroidInjector import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import javax.inject.Inject class BackupFragment : BaseFragment() { - @Inject - lateinit var viewModelFactory: ViewModelProvider.Factory - - private val walletSetup: WalletSetupViewModel by activityViewModels { viewModelFactory } + val walletSetup: WalletSetupViewModel by viewModel() private var hasBackUp: Boolean? = null @@ -104,12 +96,4 @@ class BackupFragment : BaseFragment() { result } } -} - - -@Module -abstract class BackupFragmentModule { - @FragmentScope - @ContributesAndroidInjector - abstract fun contributeFragment(): BackupFragment } \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/ui/setup/LandingFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/setup/LandingFragment.kt index de010d2..683dbd6 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/setup/LandingFragment.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/setup/LandingFragment.kt @@ -5,32 +5,24 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.widget.Toast -import androidx.fragment.app.activityViewModels -import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import cash.z.ecc.android.R import cash.z.ecc.android.ZcashWalletApp import cash.z.ecc.android.databinding.FragmentLandingBinding -import cash.z.ecc.android.di.annotation.FragmentScope -import cash.z.ecc.android.isEmulator +import cash.z.ecc.android.di.viewmodel.viewModel import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.SEED_WITHOUT_BACKUP import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.SEED_WITH_BACKUP import cash.z.wallet.sdk.Initializer import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.Module -import dagger.android.ContributesAndroidInjector import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import javax.inject.Inject class LandingFragment : BaseFragment() { - @Inject - lateinit var viewModelFactory: ViewModelProvider.Factory + val walletSetup: WalletSetupViewModel by viewModel() - private val walletSetup: WalletSetupViewModel by activityViewModels { viewModelFactory } private var skipCount: Int = 0 override fun inflate(inflater: LayoutInflater): FragmentLandingBinding = @@ -155,11 +147,4 @@ class LandingFragment : BaseFragment() { skipCount = 0 mainActivity?.navController?.popBackStack() } -} - -@Module -abstract class LandingFragmentModule { - @FragmentScope - @ContributesAndroidInjector - abstract fun contributeFragment(): LandingFragment } \ No newline at end of file diff --git a/app/src/main/java/cash/z/ecc/android/ui/setup/WalletSetupViewModel.kt b/app/src/main/java/cash/z/ecc/android/ui/setup/WalletSetupViewModel.kt index 4dfe047..466a0a4 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/setup/WalletSetupViewModel.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/setup/WalletSetupViewModel.kt @@ -13,8 +13,13 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.withContext import javax.inject.Inject -class WalletSetupViewModel @Inject constructor(val mnemonics: Mnemonics, val lockBox: LockBox) : - ViewModel() { +class WalletSetupViewModel @Inject constructor() : ViewModel() { + + @Inject + lateinit var mnemonics: Mnemonics + + @Inject + lateinit var lockBox: LockBox enum class WalletSetupState { UNKNOWN, SEED_WITH_BACKUP, SEED_WITHOUT_BACKUP, NO_SEED @@ -89,8 +94,6 @@ class WalletSetupViewModel @Inject constructor(val mnemonics: Mnemonics, val loc } } - - object LockBoxKey { const val SEED = "cash.z.ecc.android.SEED" const val SEED_PHRASE = "cash.z.ecc.android.SEED_PHRASE" diff --git a/buildSrc/src/main/java/cash/z/ecc/android/Dependencies.kt b/buildSrc/src/main/java/cash/z/ecc/android/Dependencies.kt index 1fd4529..7c59aa8 100644 --- a/buildSrc/src/main/java/cash/z/ecc/android/Dependencies.kt +++ b/buildSrc/src/main/java/cash/z/ecc/android/Dependencies.kt @@ -22,6 +22,7 @@ object Deps { } object Lifecycle: Version("2.2.0-rc02") { val LIFECYCLE_RUNTIME_KTX = "androidx.lifecycle:lifecycle-runtime-ktx:$version" + val LIFECYCLE_EXTENSIONS = "androidx.lifecycle:lifecycle-extensions:$version" } } object Dagger : Version("2.25.2") { diff --git a/gradle.properties b/gradle.properties index 23339e0..dab4578 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,3 +19,5 @@ android.useAndroidX=true android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official + +dagger.fastInit=enabled \ No newline at end of file