From dc4ca065517b5253bccd45c60fb6bcb7eb56c947 Mon Sep 17 00:00:00 2001 From: Christophe Beyls Date: Fri, 10 May 2024 15:55:07 +0200 Subject: [PATCH] Replace Dagger-Android with Hilt and remove Kapt (#4423) Hilt is an annotation processor built on top of Dagger which allows to remove all the Android dependency injection boilerplate code (currently around 900 lines) by writing it for us. Hilt can use KSP instead of Kapt so Kapt can be completely removed from the project. Kapt is slow, deprecated and has a few compatibility issues. Removing Kapt will improve build times since no Java stubs have to be generated for Kotlin classes anymore (Note that KSP also processes annotations in Java classes so it can completely replace Kapt). - Remove all modules related to manual dependency injection configuration. - Rename `AppModule` to `StorageModule` since it now only contains configuration to retrieve the DataBase and SharedPreferences. - Annotate all entry points (Activities, Fragments, BroadcastReceivers and Services) with `@AndroidEntryPoint`. - Annotate all injected ViewModels with `@HiltViewModel` and replace the custom ViewModel Factory with the default one (which integrates with the one generated by Hilt). - Add a public field to allow overriding the default ViewModelProvider.Factory in `BaseActivity` in tests. - Annotate tested Activities with `@OptionalInject` since Activity tests currently rely on the Activities not being injected automatically. - Annotate injected `Context` arguments with `@ApplicationContext`. Hilt provides the `Context` binding automatically but requires to specify if the Application or Activity Context is wanted. - Add WorkManager Hilt integration so all Workers are injected by Hilt automatically using `HiltWorkerFactory`. - Lazily initialize WorkManager in `TuskyApplication`. - Remove Kapt and Kapt workarounds. - ~~Remove toolchain configuration for Java 21. Toolchains force the Java bytecode to match the JDK version used to build the project, and apparently Hilt doesn't run inside the toolchain so cannot process the source code if the JDK version of the toolchain is higher than the JDK used to run Gradle. [And configuring a toolchain for an older Java version causes other issues](https://jakewharton.com/gradle-toolchains-are-rarely-a-good-idea/). **Removing toolchains configuration doesn't prevent the project from being built using JDK 21** or more recent versions but allows to build the project using older JDKs as well.~~ Added a fix to allow Hilt to properly use the JDK toolchain. - ~~Set the Java and Kotlin bytecode target to Java 17. The standard bytecode target for Android projects is usually Java 8 or 11 (any higher version doesn't provide any benefit but may cause compatibility issues). However, since the app currently uses a library built against Java 17 bytecode (`networkresult-calladapter`), it needs to target at least Java 17 bytecode as well.~~ - Update the Dagger 2 URL in the licenses screen. Hilt is part of Dagger 2 so the label wasn't changed. --- app/build.gradle | 26 +-- .../com/keylesspalace/tusky/AboutActivity.kt | 5 +- .../tusky/AccountsInListFragment.kt | 12 +- .../com/keylesspalace/tusky/BaseActivity.java | 20 +- .../tusky/EditProfileActivity.kt | 12 +- .../keylesspalace/tusky/LicenseActivity.kt | 2 + .../com/keylesspalace/tusky/ListsActivity.kt | 19 +- .../com/keylesspalace/tusky/MainActivity.kt | 12 +- .../com/keylesspalace/tusky/SplashActivity.kt | 5 +- .../keylesspalace/tusky/StatusListActivity.kt | 11 +- .../tusky/TabPreferenceActivity.kt | 12 +- .../keylesspalace/tusky/TuskyApplication.kt | 28 +-- .../keylesspalace/tusky/ViewMediaActivity.kt | 11 +- .../components/account/AccountActivity.kt | 17 +- .../components/account/AccountViewModel.kt | 2 + .../account/list/ListSelectionFragment.kt | 12 +- .../account/list/ListsForAccountViewModel.kt | 2 + .../account/media/AccountMediaFragment.kt | 12 +- .../account/media/AccountMediaViewModel.kt | 2 + .../accountlist/AccountListActivity.kt | 12 +- .../accountlist/AccountListFragment.kt | 6 +- .../announcements/AnnouncementsActivity.kt | 13 +- .../announcements/AnnouncementsViewModel.kt | 2 + .../components/compose/ComposeActivity.kt | 13 +- .../compose/ComposeAutoCompleteAdapter.kt | 1 + .../components/compose/ComposeViewModel.kt | 2 + .../tusky/components/compose/MediaUploader.kt | 3 +- .../conversation/ConversationsFragment.kt | 10 +- .../conversation/ConversationsViewModel.kt | 2 + .../domainblocks/DomainBlocksActivity.kt | 12 +- .../domainblocks/DomainBlocksFragment.kt | 12 +- .../domainblocks/DomainBlocksViewModel.kt | 2 + .../tusky/components/drafts/DraftHelper.kt | 3 +- .../tusky/components/drafts/DraftsActivity.kt | 8 +- .../components/drafts/DraftsViewModel.kt | 2 + .../components/filters/EditFilterActivity.kt | 8 +- .../components/filters/EditFilterViewModel.kt | 2 + .../components/filters/FiltersActivity.kt | 8 +- .../components/filters/FiltersViewModel.kt | 2 + .../followedtags/FollowedTagsActivity.kt | 8 +- .../followedtags/FollowedTagsViewModel.kt | 5 +- .../tusky/components/login/LoginActivity.kt | 5 +- .../components/login/LoginWebViewActivity.kt | 12 +- .../components/login/LoginWebViewViewModel.kt | 2 + .../notifications/NotificationsFragment.kt | 12 +- .../notifications/NotificationsViewModel.kt | 2 + .../preference/AccountPreferencesFragment.kt | 5 +- .../NotificationPreferencesFragment.kt | 5 +- .../preference/PreferencesActivity.kt | 12 +- .../preference/PreferencesFragment.kt | 5 +- .../TabFilterPreferencesFragment.kt | 5 +- .../tusky/components/report/ReportActivity.kt | 18 +- .../components/report/ReportViewModel.kt | 4 + .../report/fragments/ReportDoneFragment.kt | 12 +- .../report/fragments/ReportNoteFragment.kt | 12 +- .../fragments/ReportStatusesFragment.kt | 10 +- .../scheduled/ScheduledStatusActivity.kt | 12 +- .../scheduled/ScheduledStatusViewModel.kt | 2 + .../tusky/components/search/SearchActivity.kt | 17 +- .../components/search/SearchViewModel.kt | 2 + .../fragments/SearchAccountsFragment.kt | 2 + .../search/fragments/SearchFragment.kt | 8 +- .../fragments/SearchHashtagsFragment.kt | 2 + .../fragments/SearchStatusesFragment.kt | 2 + .../NotificationFetcher.kt | 3 +- .../components/timeline/TimelineFragment.kt | 13 +- .../viewmodel/CachedTimelineViewModel.kt | 2 + .../viewmodel/NetworkTimelineViewModel.kt | 2 + .../components/trending/TrendingActivity.kt | 12 +- .../trending/TrendingTagsFragment.kt | 11 +- .../viewmodel/TrendingTagsViewModel.kt | 2 + .../viewthread/ViewThreadActivity.kt | 12 +- .../viewthread/ViewThreadFragment.kt | 13 +- .../viewthread/ViewThreadViewModel.kt | 2 + .../viewthread/edits/ViewEditsFragment.kt | 13 +- .../viewthread/edits/ViewEditsViewModel.kt | 6 +- .../tusky/di/ActivitiesModule.kt | 135 ------------ .../keylesspalace/tusky/di/AppComponent.kt | 53 ----- .../com/keylesspalace/tusky/di/AppInjector.kt | 85 -------- .../tusky/di/BroadcastReceiverModule.kt | 35 --- .../tusky/di/CoroutineScopeModule.kt | 5 +- .../tusky/di/FragmentBuildersModule.kt | 110 ---------- .../com/keylesspalace/tusky/di/Injectable.kt | 22 -- .../keylesspalace/tusky/di/NetworkModule.kt | 6 +- .../keylesspalace/tusky/di/PlayerModule.kt | 18 +- .../keylesspalace/tusky/di/ServicesModule.kt | 26 --- .../di/{AppModule.kt => StorageModule.kt} | 20 +- .../tusky/di/ViewModelFactory.kt | 202 ------------------ .../keylesspalace/tusky/di/WorkerModule.kt | 49 ----- .../keylesspalace/tusky/fragment/SFragment.kt | 3 +- .../tusky/fragment/ViewVideoFragment.kt | 5 +- ...NotificationBlockStateBroadcastReceiver.kt | 6 +- .../receiver/SendStatusBroadcastReceiver.kt | 5 +- .../receiver/UnifiedPushBroadcastReceiver.kt | 14 +- .../tusky/service/SendStatusService.kt | 11 +- .../tusky/service/ServiceClient.kt | 3 +- .../tusky/usecase/LogoutUsecase.kt | 3 +- .../keylesspalace/tusky/util/LocaleManager.kt | 3 +- .../tusky/util/ShareShortcutHelper.kt | 3 +- .../viewmodel/AccountsInListViewModel.kt | 2 + .../tusky/viewmodel/EditProfileViewModel.kt | 2 + .../tusky/viewmodel/ListsViewModel.kt | 2 + .../tusky/worker/NotificationWorker.kt | 19 +- .../tusky/worker/PruneCacheWorker.kt | 21 +- .../tusky/worker/WorkerFactory.kt | 71 ------ app/src/main/res/layout/activity_license.xml | 2 +- .../keylesspalace/tusky/MainActivityTest.kt | 3 +- .../com/keylesspalace/tusky/SpanUtilsTest.kt | 1 + .../components/compose/ComposeActivityTest.kt | 10 +- build.gradle | 9 +- gradle/libs.versions.toml | 16 +- 111 files changed, 344 insertions(+), 1253 deletions(-) delete mode 100644 app/src/main/java/com/keylesspalace/tusky/di/ActivitiesModule.kt delete mode 100644 app/src/main/java/com/keylesspalace/tusky/di/AppComponent.kt delete mode 100644 app/src/main/java/com/keylesspalace/tusky/di/AppInjector.kt delete mode 100644 app/src/main/java/com/keylesspalace/tusky/di/BroadcastReceiverModule.kt delete mode 100644 app/src/main/java/com/keylesspalace/tusky/di/FragmentBuildersModule.kt delete mode 100644 app/src/main/java/com/keylesspalace/tusky/di/Injectable.kt delete mode 100644 app/src/main/java/com/keylesspalace/tusky/di/ServicesModule.kt rename app/src/main/java/com/keylesspalace/tusky/di/{AppModule.kt => StorageModule.kt} (88%) delete mode 100644 app/src/main/java/com/keylesspalace/tusky/di/ViewModelFactory.kt delete mode 100644 app/src/main/java/com/keylesspalace/tusky/di/WorkerModule.kt delete mode 100644 app/src/main/java/com/keylesspalace/tusky/worker/WorkerFactory.kt diff --git a/app/build.gradle b/app/build.gradle index fbe7b8233c..d53675dc4b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,8 +1,8 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.google.ksp) + alias(libs.plugins.hilt.android) alias(libs.plugins.kotlin.android) - alias(libs.plugins.kotlin.kapt) alias(libs.plugins.kotlin.parcelize) } @@ -81,6 +81,7 @@ android { resValues true viewBinding true } + testOptions { unitTests { returnDefaultValues = true @@ -156,8 +157,10 @@ dependencies { implementation libs.bundles.glide ksp libs.glide.compiler - implementation libs.bundles.dagger - kapt libs.bundles.dagger.processors + implementation libs.hilt.android + ksp libs.hilt.compiler + implementation libs.androidx.hilt.work + ksp libs.androidx.hilt.compiler implementation libs.sparkbutton @@ -189,20 +192,3 @@ dependencies { androidTestImplementation libs.androidx.room.testing androidTestImplementation libs.androidx.test.junit } - -// Work around warnings of: -// WARNING: Illegal reflective access by org.jetbrains.kotlin.kapt3.util.ModuleManipulationUtilsKt (file:/C:/Users/Andi/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-annotation-processing-gradle/1.8.22/28dab7e0ee9ce62c03bf97de3543c911dc653700/kotlin-annotation-processing-gradle-1.8.22.jar) to constructor com.sun.tools.javac.util.Context() -// See https://youtrack.jetbrains.com/issue/KT-30589/Kapt-An-illegal-reflective-access-operation-has-occurred -tasks.withType(org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask).configureEach { - kaptProcessJvmArgs.addAll([ - "--add-opens", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", - "--add-opens", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", - "--add-opens", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", - "--add-opens", "jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED", - "--add-opens", "jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED", - "--add-opens", "jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED", - "--add-opens", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", - "--add-opens", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", - "--add-opens", "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", - "--add-opens", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED"]) -} diff --git a/app/src/main/java/com/keylesspalace/tusky/AboutActivity.kt b/app/src/main/java/com/keylesspalace/tusky/AboutActivity.kt index d0a7fcc006..af012d3016 100644 --- a/app/src/main/java/com/keylesspalace/tusky/AboutActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/AboutActivity.kt @@ -17,15 +17,16 @@ import androidx.annotation.StringRes import androidx.lifecycle.lifecycleScope import com.keylesspalace.tusky.components.instanceinfo.InstanceInfoRepository import com.keylesspalace.tusky.databinding.ActivityAboutBinding -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.util.NoUnderlineURLSpan import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.startActivityWithSlideInAnimation +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.launch -class AboutActivity : BottomSheetActivity(), Injectable { +@AndroidEntryPoint +class AboutActivity : BottomSheetActivity() { @Inject lateinit var instanceInfoRepository: InstanceInfoRepository diff --git a/app/src/main/java/com/keylesspalace/tusky/AccountsInListFragment.kt b/app/src/main/java/com/keylesspalace/tusky/AccountsInListFragment.kt index 0e88e0c7e9..952addaab8 100644 --- a/app/src/main/java/com/keylesspalace/tusky/AccountsInListFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/AccountsInListFragment.kt @@ -31,8 +31,6 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.ListAdapter import com.keylesspalace.tusky.databinding.FragmentAccountsInListBinding import com.keylesspalace.tusky.databinding.ItemFollowRequestBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.TimelineAccount import com.keylesspalace.tusky.settings.PrefKeys import com.keylesspalace.tusky.util.BindingHolder @@ -45,17 +43,15 @@ import com.keylesspalace.tusky.util.unsafeLazy import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.viewmodel.AccountsInListViewModel import com.keylesspalace.tusky.viewmodel.State -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch private typealias AccountInfo = Pair -class AccountsInListFragment : DialogFragment(), Injectable { +@AndroidEntryPoint +class AccountsInListFragment : DialogFragment() { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: AccountsInListViewModel by viewModels { viewModelFactory } + private val viewModel: AccountsInListViewModel by viewModels() private val binding by viewBinding(FragmentAccountsInListBinding::bind) private lateinit var listId: String diff --git a/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java b/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java index c7f78d6ab1..52f1dc7a40 100644 --- a/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java +++ b/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java @@ -33,6 +33,7 @@ import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.lifecycle.ViewModelProvider; import androidx.preference.PreferenceManager; import com.google.android.material.color.MaterialColors; @@ -41,7 +42,6 @@ import com.keylesspalace.tusky.components.login.LoginActivity; import com.keylesspalace.tusky.db.entity.AccountEntity; import com.keylesspalace.tusky.db.AccountManager; -import com.keylesspalace.tusky.di.Injectable; import com.keylesspalace.tusky.interfaces.AccountSelectionListener; import com.keylesspalace.tusky.settings.AppTheme; import com.keylesspalace.tusky.settings.PrefKeys; @@ -55,7 +55,10 @@ import static com.keylesspalace.tusky.settings.PrefKeys.APP_THEME; -public abstract class BaseActivity extends AppCompatActivity implements Injectable { +/** + * All activities inheriting from BaseActivity must be annotated with @AndroidEntryPoint + */ +public abstract class BaseActivity extends AppCompatActivity { public static final String OPEN_WITH_SLIDE_IN = "OPEN_WITH_SLIDE_IN"; @@ -65,6 +68,12 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab @NonNull public AccountManager accountManager; + /** + * Allows overriding the default ViewModelProvider.Factory for testing purposes. + */ + @Nullable + public ViewModelProvider.Factory viewModelProviderFactory = null; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -152,6 +161,13 @@ protected void attachBaseContext(Context newBase) { super.attachBaseContext(fontScaleContext); } + @NonNull + @Override + public ViewModelProvider.Factory getDefaultViewModelProviderFactory() { + final ViewModelProvider.Factory factory = viewModelProviderFactory; + return (factory != null) ? factory : super.getDefaultViewModelProviderFactory(); + } + protected boolean requiresLogin() { return true; } diff --git a/app/src/main/java/com/keylesspalace/tusky/EditProfileActivity.kt b/app/src/main/java/com/keylesspalace/tusky/EditProfileActivity.kt index e0f6a3bc80..ab459ae098 100644 --- a/app/src/main/java/com/keylesspalace/tusky/EditProfileActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/EditProfileActivity.kt @@ -43,8 +43,6 @@ import com.google.android.material.snackbar.Snackbar import com.keylesspalace.tusky.adapter.AccountFieldEditAdapter import com.keylesspalace.tusky.components.instanceinfo.InstanceInfoRepository import com.keylesspalace.tusky.databinding.ActivityEditProfileBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.util.Error import com.keylesspalace.tusky.util.Loading import com.keylesspalace.tusky.util.Success @@ -57,11 +55,12 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch -class EditProfileActivity : BaseActivity(), Injectable { +@AndroidEntryPoint +class EditProfileActivity : BaseActivity() { companion object { const val AVATAR_SIZE = 400 @@ -69,10 +68,7 @@ class EditProfileActivity : BaseActivity(), Injectable { const val HEADER_HEIGHT = 500 } - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: EditProfileViewModel by viewModels { viewModelFactory } + private val viewModel: EditProfileViewModel by viewModels() private val binding by viewBinding(ActivityEditProfileBinding::inflate) diff --git a/app/src/main/java/com/keylesspalace/tusky/LicenseActivity.kt b/app/src/main/java/com/keylesspalace/tusky/LicenseActivity.kt index 02e9b1a514..426fa1c889 100644 --- a/app/src/main/java/com/keylesspalace/tusky/LicenseActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/LicenseActivity.kt @@ -21,6 +21,7 @@ import android.widget.TextView import androidx.annotation.RawRes import androidx.lifecycle.lifecycleScope import com.keylesspalace.tusky.databinding.ActivityLicenseBinding +import dagger.hilt.android.AndroidEntryPoint import java.io.IOException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -28,6 +29,7 @@ import kotlinx.coroutines.withContext import okio.buffer import okio.source +@AndroidEntryPoint class LicenseActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { diff --git a/app/src/main/java/com/keylesspalace/tusky/ListsActivity.kt b/app/src/main/java/com/keylesspalace/tusky/ListsActivity.kt index f8a2e94659..54d76ca6ac 100644 --- a/app/src/main/java/com/keylesspalace/tusky/ListsActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/ListsActivity.kt @@ -37,8 +37,6 @@ import com.google.android.material.snackbar.Snackbar import com.keylesspalace.tusky.databinding.ActivityListsBinding import com.keylesspalace.tusky.databinding.DialogListBinding import com.keylesspalace.tusky.databinding.ItemListBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.MastoList import com.keylesspalace.tusky.util.BindingHolder import com.keylesspalace.tusky.util.hide @@ -53,22 +51,15 @@ import com.keylesspalace.tusky.viewmodel.ListsViewModel.LoadingState.ERROR_OTHER import com.keylesspalace.tusky.viewmodel.ListsViewModel.LoadingState.INITIAL import com.keylesspalace.tusky.viewmodel.ListsViewModel.LoadingState.LOADED import com.keylesspalace.tusky.viewmodel.ListsViewModel.LoadingState.LOADING -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch // TODO use the ListSelectionFragment (and/or its adapter or binding) here; but keep the LoadingState from here (?) -class ListsActivity : BaseActivity(), Injectable, HasAndroidInjector { +@AndroidEntryPoint +class ListsActivity : BaseActivity() { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - @Inject - lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector - - private val viewModel: ListsViewModel by viewModels { viewModelFactory } + private val viewModel: ListsViewModel by viewModels() private val binding by viewBinding(ActivityListsBinding::inflate) @@ -287,8 +278,6 @@ class ListsActivity : BaseActivity(), Injectable, HasAndroidInjector { } } - override fun androidInjector() = dispatchingAndroidInjector - companion object { fun newIntent(context: Context) = Intent(context, ListsActivity::class.java) } diff --git a/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt b/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt index b7848b9743..cde6a5deb9 100644 --- a/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt @@ -142,17 +142,17 @@ import com.mikepenz.materialdrawer.util.addItems import com.mikepenz.materialdrawer.util.addItemsAtPosition import com.mikepenz.materialdrawer.util.updateBadge import com.mikepenz.materialdrawer.widget.AccountHeaderView -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector +import dagger.hilt.android.AndroidEntryPoint +import dagger.hilt.android.migration.OptionalInject import de.c1710.filemojicompat_ui.helpers.EMOJI_PREFERENCE import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInjector, MenuProvider { - @Inject - lateinit var androidInjector: DispatchingAndroidInjector +@OptionalInject +@AndroidEntryPoint +class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider { @Inject lateinit var eventHub: EventHub @@ -1215,8 +1215,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje override fun getActionButton() = binding.composeButton - override fun androidInjector() = androidInjector - companion object { const val OPEN_WITH_EXPLODE_ANIMATION = "explode" diff --git a/app/src/main/java/com/keylesspalace/tusky/SplashActivity.kt b/app/src/main/java/com/keylesspalace/tusky/SplashActivity.kt index 638f0e5be9..6acabf03f4 100644 --- a/app/src/main/java/com/keylesspalace/tusky/SplashActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/SplashActivity.kt @@ -21,11 +21,12 @@ import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.keylesspalace.tusky.components.login.LoginActivity import com.keylesspalace.tusky.db.AccountManager -import com.keylesspalace.tusky.di.Injectable +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @SuppressLint("CustomSplashScreen") -class SplashActivity : AppCompatActivity(), Injectable { +@AndroidEntryPoint +class SplashActivity : AppCompatActivity() { @Inject lateinit var accountManager: AccountManager diff --git a/app/src/main/java/com/keylesspalace/tusky/StatusListActivity.kt b/app/src/main/java/com/keylesspalace/tusky/StatusListActivity.kt index a06c47d95f..2e41ddd6b0 100644 --- a/app/src/main/java/com/keylesspalace/tusky/StatusListActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/StatusListActivity.kt @@ -37,15 +37,12 @@ import com.keylesspalace.tusky.entity.FilterV1 import com.keylesspalace.tusky.util.isHttpNotFound import com.keylesspalace.tusky.util.startActivityWithSlideInAnimation import com.keylesspalace.tusky.util.viewBinding -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.launch -class StatusListActivity : BottomSheetActivity(), HasAndroidInjector { - - @Inject - lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector +@AndroidEntryPoint +class StatusListActivity : BottomSheetActivity() { @Inject lateinit var eventHub: EventHub @@ -399,8 +396,6 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector { return true } - override fun androidInjector() = dispatchingAndroidInjector - companion object { private const val EXTRA_KIND = "kind" diff --git a/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt b/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt index 23d8450cbc..2fddb882f2 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt @@ -39,20 +39,19 @@ import com.keylesspalace.tusky.appstore.EventHub import com.keylesspalace.tusky.appstore.MainTabsChangedEvent import com.keylesspalace.tusky.components.account.list.ListSelectionFragment import com.keylesspalace.tusky.databinding.ActivityTabPreferenceBinding -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.entity.MastoList import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.unsafeLazy import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.util.visible -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector +import dagger.hilt.android.AndroidEntryPoint import java.util.regex.Pattern import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -class TabPreferenceActivity : BaseActivity(), Injectable, HasAndroidInjector, ItemInteractionListener, ListSelectionFragment.ListSelectionListener { +@AndroidEntryPoint +class TabPreferenceActivity : BaseActivity(), ItemInteractionListener, ListSelectionFragment.ListSelectionListener { @Inject lateinit var mastodonApi: MastodonApi @@ -60,9 +59,6 @@ class TabPreferenceActivity : BaseActivity(), Injectable, HasAndroidInjector, It @Inject lateinit var eventHub: EventHub - @Inject - lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector - private val binding by viewBinding(ActivityTabPreferenceBinding::inflate) private lateinit var currentTabs: MutableList @@ -368,8 +364,6 @@ class TabPreferenceActivity : BaseActivity(), Injectable, HasAndroidInjector, It } } - override fun androidInjector() = dispatchingAndroidInjector - companion object { private const val MIN_TAB_COUNT = 2 } diff --git a/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.kt b/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.kt index bc1dacfce8..cb0cc615ee 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.kt +++ b/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.kt @@ -18,12 +18,13 @@ package com.keylesspalace.tusky import android.app.Application import android.content.SharedPreferences import android.util.Log +import androidx.hilt.work.HiltWorkerFactory +import androidx.work.Configuration import androidx.work.Constraints import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkManager import com.keylesspalace.tusky.components.systemnotifications.NotificationHelper -import com.keylesspalace.tusky.di.AppInjector import com.keylesspalace.tusky.settings.AppTheme import com.keylesspalace.tusky.settings.NEW_INSTALL_SCHEMA_VERSION import com.keylesspalace.tusky.settings.PrefKeys @@ -32,9 +33,7 @@ import com.keylesspalace.tusky.settings.SCHEMA_VERSION import com.keylesspalace.tusky.util.LocaleManager import com.keylesspalace.tusky.util.setAppNightMode import com.keylesspalace.tusky.worker.PruneCacheWorker -import com.keylesspalace.tusky.worker.WorkerFactory -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector +import dagger.hilt.android.HiltAndroidApp import de.c1710.filemojicompat_defaults.DefaultEmojiPackList import de.c1710.filemojicompat_ui.helpers.EmojiPackHelper import de.c1710.filemojicompat_ui.helpers.EmojiPreference @@ -43,12 +42,11 @@ import java.util.concurrent.TimeUnit import javax.inject.Inject import org.conscrypt.Conscrypt -class TuskyApplication : Application(), HasAndroidInjector { - @Inject - lateinit var androidInjector: DispatchingAndroidInjector +@HiltAndroidApp +class TuskyApplication : Application(), Configuration.Provider { @Inject - lateinit var workerFactory: WorkerFactory + lateinit var workerFactory: HiltWorkerFactory @Inject lateinit var localeManager: LocaleManager @@ -71,8 +69,6 @@ class TuskyApplication : Application(), HasAndroidInjector { Security.insertProviderAt(Conscrypt.newProvider(), 1) - AppInjector.init(this) - // Migrate shared preference keys and defaults from version to version. val oldVersion = sharedPreferences.getInt( PrefKeys.SCHEMA_VERSION, @@ -95,13 +91,6 @@ class TuskyApplication : Application(), HasAndroidInjector { NotificationHelper.createWorkerNotificationChannel(this) - WorkManager.initialize( - this, - androidx.work.Configuration.Builder() - .setWorkerFactory(workerFactory) - .build() - ) - // Prune the database every ~ 12 hours when the device is idle. val pruneCacheWorker = PeriodicWorkRequestBuilder(12, TimeUnit.HOURS) .setConstraints(Constraints.Builder().setRequiresDeviceIdle(true).build()) @@ -113,7 +102,10 @@ class TuskyApplication : Application(), HasAndroidInjector { ) } - override fun androidInjector() = androidInjector + override val workManagerConfiguration: Configuration + get() = Configuration.Builder() + .setWorkerFactory(workerFactory) + .build() private fun upgradeSharedPreferences(oldVersion: Int, newVersion: Int) { Log.d(TAG, "Upgrading shared preferences: $oldVersion -> $newVersion") diff --git a/app/src/main/java/com/keylesspalace/tusky/ViewMediaActivity.kt b/app/src/main/java/com/keylesspalace/tusky/ViewMediaActivity.kt index a8d4e60610..10bfffb5fb 100644 --- a/app/src/main/java/com/keylesspalace/tusky/ViewMediaActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/ViewMediaActivity.kt @@ -59,27 +59,22 @@ import com.keylesspalace.tusky.util.startActivityWithSlideInAnimation import com.keylesspalace.tusky.util.submitAsync import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.viewdata.AttachmentViewData -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector +import dagger.hilt.android.AndroidEntryPoint import java.io.File import java.io.FileOutputStream import java.io.IOException import java.util.Locale -import javax.inject.Inject import kotlinx.coroutines.CancellationException import kotlinx.coroutines.launch typealias ToolbarVisibilityListener = (isVisible: Boolean) -> Unit +@AndroidEntryPoint class ViewMediaActivity : BaseActivity(), - HasAndroidInjector, ViewImageFragment.PhotoActionsListener, ViewVideoFragment.VideoActionsListener { - @Inject - lateinit var androidInjector: DispatchingAndroidInjector - private val binding by viewBinding(ActivityViewMediaBinding::inflate) val toolbar: View @@ -361,8 +356,6 @@ class ViewMediaActivity : } } - override fun androidInjector() = androidInjector - companion object { private const val EXTRA_ATTACHMENTS = "attachments" private const val EXTRA_ATTACHMENT_INDEX = "index" diff --git a/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt index a13f3882f7..53eb3cc918 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt @@ -73,7 +73,6 @@ import com.keylesspalace.tusky.components.report.ReportActivity import com.keylesspalace.tusky.databinding.ActivityAccountBinding import com.keylesspalace.tusky.db.DraftsAlert import com.keylesspalace.tusky.db.entity.AccountEntity -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.Account import com.keylesspalace.tusky.entity.Relationship import com.keylesspalace.tusky.interfaces.AccountSelectionListener @@ -101,8 +100,7 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector +import dagger.hilt.android.AndroidEntryPoint import java.text.NumberFormat import java.text.ParseException import java.text.SimpleDateFormat @@ -111,18 +109,13 @@ import javax.inject.Inject import kotlin.math.abs import kotlinx.coroutines.launch -class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider, HasAndroidInjector, LinkListener { - - @Inject - lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector - - @Inject - lateinit var viewModelFactory: ViewModelFactory +@AndroidEntryPoint +class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider, LinkListener { @Inject lateinit var draftsAlert: DraftsAlert - private val viewModel: AccountViewModel by viewModels { viewModelFactory } + private val viewModel: AccountViewModel by viewModels() private val binding: ActivityAccountBinding by viewBinding(ActivityAccountBinding::inflate) @@ -1143,8 +1136,6 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide return badge } - override fun androidInjector() = dispatchingAndroidInjector - companion object { private const val KEY_ACCOUNT_ID = "id" diff --git a/app/src/main/java/com/keylesspalace/tusky/components/account/AccountViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/account/AccountViewModel.kt index 91d6dd0ea9..8716ee8266 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/account/AccountViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/account/AccountViewModel.kt @@ -19,6 +19,7 @@ import com.keylesspalace.tusky.util.Loading import com.keylesspalace.tusky.util.Resource import com.keylesspalace.tusky.util.Success import com.keylesspalace.tusky.util.getDomain +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.Job import kotlinx.coroutines.channels.BufferOverflow @@ -31,6 +32,7 @@ import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +@HiltViewModel class AccountViewModel @Inject constructor( private val mastodonApi: MastodonApi, private val eventHub: EventHub, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListSelectionFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListSelectionFragment.kt index 585c7e3111..7a1cb6c875 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListSelectionFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListSelectionFragment.kt @@ -35,30 +35,26 @@ import com.keylesspalace.tusky.ListsActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.FragmentListsListBinding import com.keylesspalace.tusky.databinding.ItemListBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.MastoList import com.keylesspalace.tusky.util.BindingHolder import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.visible -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch -class ListSelectionFragment : DialogFragment(), Injectable { +@AndroidEntryPoint +class ListSelectionFragment : DialogFragment() { interface ListSelectionListener { fun onListSelected(list: MastoList) } - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: ListsForAccountViewModel by viewModels { viewModelFactory } + private val viewModel: ListsForAccountViewModel by viewModels() private var _binding: FragmentListsListBinding? = null diff --git a/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListsForAccountViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListsForAccountViewModel.kt index b0546eceb0..692aa2d381 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListsForAccountViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListsForAccountViewModel.kt @@ -24,6 +24,7 @@ import at.connyduck.calladapter.networkresult.onSuccess import at.connyduck.calladapter.networkresult.runCatching import com.keylesspalace.tusky.entity.MastoList import com.keylesspalace.tusky.network.MastodonApi +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableSharedFlow @@ -48,6 +49,7 @@ data class ActionError( } } +@HiltViewModel @OptIn(ExperimentalCoroutinesApi::class) class ListsForAccountViewModel @Inject constructor( private val mastodonApi: MastodonApi diff --git a/app/src/main/java/com/keylesspalace/tusky/components/account/media/AccountMediaFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/account/media/AccountMediaFragment.kt index 49f19390ad..73065b39dc 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/account/media/AccountMediaFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/account/media/AccountMediaFragment.kt @@ -35,8 +35,6 @@ import com.keylesspalace.tusky.R import com.keylesspalace.tusky.ViewMediaActivity import com.keylesspalace.tusky.databinding.FragmentTimelineBinding import com.keylesspalace.tusky.db.AccountManager -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.Attachment import com.keylesspalace.tusky.interfaces.RefreshableFragment import com.keylesspalace.tusky.settings.PrefKeys @@ -49,6 +47,7 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch @@ -56,21 +55,18 @@ import kotlinx.coroutines.launch /** * Fragment with multiple columns of media previews for the specified account. */ +@AndroidEntryPoint class AccountMediaFragment : Fragment(R.layout.fragment_timeline), RefreshableFragment, - MenuProvider, - Injectable { - - @Inject - lateinit var viewModelFactory: ViewModelFactory + MenuProvider { @Inject lateinit var accountManager: AccountManager private val binding by viewBinding(FragmentTimelineBinding::bind) - private val viewModel: AccountMediaViewModel by viewModels { viewModelFactory } + private val viewModel: AccountMediaViewModel by viewModels() private lateinit var adapter: AccountMediaGridAdapter diff --git a/app/src/main/java/com/keylesspalace/tusky/components/account/media/AccountMediaViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/account/media/AccountMediaViewModel.kt index b42a7282d1..0f90772869 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/account/media/AccountMediaViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/account/media/AccountMediaViewModel.kt @@ -24,8 +24,10 @@ import androidx.paging.cachedIn import com.keylesspalace.tusky.db.AccountManager import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.viewdata.AttachmentViewData +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject +@HiltViewModel class AccountMediaViewModel @Inject constructor( accountManager: AccountManager, api: MastodonApi diff --git a/app/src/main/java/com/keylesspalace/tusky/components/accountlist/AccountListActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/accountlist/AccountListActivity.kt index 70888bbf3c..b8d972c439 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/accountlist/AccountListActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/accountlist/AccountListActivity.kt @@ -23,14 +23,10 @@ import com.keylesspalace.tusky.BottomSheetActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.ActivityAccountListBinding import com.keylesspalace.tusky.util.getSerializableExtraCompat -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint -class AccountListActivity : BottomSheetActivity(), HasAndroidInjector { - - @Inject - lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector +@AndroidEntryPoint +class AccountListActivity : BottomSheetActivity() { enum class Type { FOLLOWS, @@ -70,8 +66,6 @@ class AccountListActivity : BottomSheetActivity(), HasAndroidInjector { } } - override fun androidInjector() = dispatchingAndroidInjector - companion object { private const val EXTRA_TYPE = "type" private const val EXTRA_ID = "id" diff --git a/app/src/main/java/com/keylesspalace/tusky/components/accountlist/AccountListFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/accountlist/AccountListFragment.kt index b77e056991..b0390efef6 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/accountlist/AccountListFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/accountlist/AccountListFragment.kt @@ -42,7 +42,6 @@ import com.keylesspalace.tusky.components.accountlist.adapter.FollowRequestsHead import com.keylesspalace.tusky.components.accountlist.adapter.MutesAdapter import com.keylesspalace.tusky.databinding.FragmentAccountListBinding import com.keylesspalace.tusky.db.AccountManager -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.entity.Relationship import com.keylesspalace.tusky.entity.TimelineAccount import com.keylesspalace.tusky.interfaces.AccountActionListener @@ -56,16 +55,17 @@ import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.startActivityWithSlideInAnimation import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.view.EndlessOnScrollListener +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.CancellationException import kotlinx.coroutines.launch import retrofit2.Response +@AndroidEntryPoint class AccountListFragment : Fragment(R.layout.fragment_account_list), AccountActionListener, - LinkListener, - Injectable { + LinkListener { @Inject lateinit var api: MastodonApi diff --git a/app/src/main/java/com/keylesspalace/tusky/components/announcements/AnnouncementsActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/announcements/AnnouncementsActivity.kt index 1ed3b37793..a12460b9c2 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/announcements/AnnouncementsActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/announcements/AnnouncementsActivity.kt @@ -37,8 +37,6 @@ import com.keylesspalace.tusky.StatusListActivity import com.keylesspalace.tusky.adapter.EmojiAdapter import com.keylesspalace.tusky.adapter.OnEmojiSelectedListener import com.keylesspalace.tusky.databinding.ActivityAnnouncementsBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.settings.PrefKeys import com.keylesspalace.tusky.util.Error import com.keylesspalace.tusky.util.Loading @@ -53,20 +51,17 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch +@AndroidEntryPoint class AnnouncementsActivity : BottomSheetActivity(), AnnouncementActionListener, OnEmojiSelectedListener, - MenuProvider, - Injectable { + MenuProvider { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: AnnouncementsViewModel by viewModels { viewModelFactory } + private val viewModel: AnnouncementsViewModel by viewModels() private val binding by viewBinding(ActivityAnnouncementsBinding::inflate) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/announcements/AnnouncementsViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/announcements/AnnouncementsViewModel.kt index 1e1503c6e4..3834c5d97b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/announcements/AnnouncementsViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/announcements/AnnouncementsViewModel.kt @@ -29,12 +29,14 @@ import com.keylesspalace.tusky.util.Error import com.keylesspalace.tusky.util.Loading import com.keylesspalace.tusky.util.Resource import com.keylesspalace.tusky.util.Success +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +@HiltViewModel class AnnouncementsViewModel @Inject constructor( private val instanceInfoRepo: InstanceInfoRepository, private val mastodonApi: MastodonApi, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt index d589d85bb1..59a3263e43 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt @@ -82,8 +82,6 @@ import com.keylesspalace.tusky.components.instanceinfo.InstanceInfoRepository import com.keylesspalace.tusky.databinding.ActivityComposeBinding import com.keylesspalace.tusky.db.entity.AccountEntity import com.keylesspalace.tusky.db.entity.DraftAttachment -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.Attachment import com.keylesspalace.tusky.entity.Emoji import com.keylesspalace.tusky.entity.NewPoll @@ -113,11 +111,12 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp +import dagger.hilt.android.AndroidEntryPoint +import dagger.hilt.android.migration.OptionalInject import java.io.File import java.io.IOException import java.text.DecimalFormat import java.util.Locale -import javax.inject.Inject import kotlin.math.max import kotlin.math.min import kotlinx.coroutines.flow.collect @@ -126,19 +125,17 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize +@OptionalInject +@AndroidEntryPoint class ComposeActivity : BaseActivity(), ComposeOptionsListener, ComposeAutoCompleteAdapter.AutocompletionProvider, OnEmojiSelectedListener, - Injectable, OnReceiveContentListener, ComposeScheduleView.OnTimeSetListener, CaptionDialog.Listener { - @Inject - lateinit var viewModelFactory: ViewModelFactory - private lateinit var composeOptionsBehavior: BottomSheetBehavior<*> private lateinit var addMediaBehavior: BottomSheetBehavior<*> private lateinit var emojiBehavior: BottomSheetBehavior<*> @@ -155,7 +152,7 @@ class ComposeActivity : var maximumTootCharacters = InstanceInfoRepository.DEFAULT_CHARACTER_LIMIT var charactersReservedPerUrl = InstanceInfoRepository.DEFAULT_CHARACTERS_RESERVED_PER_URL - private val viewModel: ComposeViewModel by viewModels { viewModelFactory } + private val viewModel: ComposeViewModel by viewModels() private val binding by viewBinding(ActivityComposeBinding::inflate) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeAutoCompleteAdapter.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeAutoCompleteAdapter.kt index c37644cee2..25d78d3af3 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeAutoCompleteAdapter.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeAutoCompleteAdapter.kt @@ -75,6 +75,7 @@ class ComposeAutoCompleteAdapter( return filterResults } + @Suppress("UNCHECKED_CAST") override fun publishResults(constraint: CharSequence?, results: FilterResults) { if (results.count > 0) { resultList = results.values as List diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt index 5ba8f9a061..652ba1cda0 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt @@ -38,6 +38,7 @@ import com.keylesspalace.tusky.service.MediaToSend import com.keylesspalace.tusky.service.ServiceClient import com.keylesspalace.tusky.service.StatusToSend import com.keylesspalace.tusky.util.randomAlphanumericString +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.BufferOverflow @@ -56,6 +57,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext +@HiltViewModel class ComposeViewModel @Inject constructor( private val api: MastodonApi, private val accountManager: AccountManager, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/MediaUploader.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/MediaUploader.kt index 4f32d8dc04..9c5520c3ce 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/MediaUploader.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/MediaUploader.kt @@ -36,6 +36,7 @@ import com.keylesspalace.tusky.util.getImageSquarePixels import com.keylesspalace.tusky.util.getMediaSize import com.keylesspalace.tusky.util.getServerErrorMessage import com.keylesspalace.tusky.util.randomAlphanumericString +import dagger.hilt.android.qualifiers.ApplicationContext import java.io.File import java.io.IOException import javax.inject.Inject @@ -94,7 +95,7 @@ class UploadServerError(val errorMessage: String) : Exception() @Singleton class MediaUploader @Inject constructor( - private val context: Context, + @ApplicationContext private val context: Context, private val mediaUploadApi: MediaUploadApi ) { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsFragment.kt index 14d6ba7f87..828c8957af 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsFragment.kt @@ -45,8 +45,6 @@ import com.keylesspalace.tusky.appstore.EventHub import com.keylesspalace.tusky.appstore.PreferenceChangedEvent import com.keylesspalace.tusky.components.account.AccountActivity import com.keylesspalace.tusky.databinding.FragmentTimelineBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.fragment.SFragment import com.keylesspalace.tusky.interfaces.ActionButtonActivity import com.keylesspalace.tusky.interfaces.ReselectableFragment @@ -63,6 +61,7 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlin.time.DurationUnit import kotlin.time.toDuration @@ -70,20 +69,17 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch +@AndroidEntryPoint class ConversationsFragment : SFragment(), StatusActionListener, - Injectable, ReselectableFragment, MenuProvider { - @Inject - lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var eventHub: EventHub - private val viewModel: ConversationsViewModel by viewModels { viewModelFactory } + private val viewModel: ConversationsViewModel by viewModels() private val binding by viewBinding(FragmentTimelineBinding::bind) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsViewModel.kt index 2972293ae1..f269364513 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsViewModel.kt @@ -29,10 +29,12 @@ import com.keylesspalace.tusky.db.AppDatabase import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.usecase.TimelineCases import com.keylesspalace.tusky.util.EmptyPagingSource +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch +@HiltViewModel class ConversationsViewModel @Inject constructor( private val timelineCases: TimelineCases, private val database: AppDatabase, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksActivity.kt index 6181749076..3a1ae69a0f 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksActivity.kt @@ -4,14 +4,10 @@ import android.os.Bundle import com.keylesspalace.tusky.BaseActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.ActivityAccountListBinding -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint -class DomainBlocksActivity : BaseActivity(), HasAndroidInjector { - - @Inject - lateinit var androidInjector: DispatchingAndroidInjector +@AndroidEntryPoint +class DomainBlocksActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -30,6 +26,4 @@ class DomainBlocksActivity : BaseActivity(), HasAndroidInjector { .replace(R.id.fragment_container, DomainBlocksFragment()) .commit() } - - override fun androidInjector() = androidInjector } diff --git a/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksFragment.kt index 1adfb911ca..5cadce707a 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksFragment.kt @@ -12,24 +12,20 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.snackbar.Snackbar import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.FragmentDomainBlocksBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.util.visible -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch -class DomainBlocksFragment : Fragment(R.layout.fragment_domain_blocks), Injectable { - - @Inject - lateinit var viewModelFactory: ViewModelFactory +@AndroidEntryPoint +class DomainBlocksFragment : Fragment(R.layout.fragment_domain_blocks) { private val binding by viewBinding(FragmentDomainBlocksBinding::bind) - private val viewModel: DomainBlocksViewModel by viewModels { viewModelFactory } + private val viewModel: DomainBlocksViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val adapter = DomainBlocksAdapter(viewModel::unblock) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksViewModel.kt index aa316c6516..a07cd84bc5 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/domainblocks/DomainBlocksViewModel.kt @@ -8,12 +8,14 @@ import androidx.paging.cachedIn import at.connyduck.calladapter.networkresult.fold import at.connyduck.calladapter.networkresult.onFailure import com.keylesspalace.tusky.R +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.launch +@HiltViewModel class DomainBlocksViewModel @Inject constructor( private val repo: DomainBlocksRepository ) : ViewModel() { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftHelper.kt b/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftHelper.kt index 0cd3780247..e688960290 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftHelper.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftHelper.kt @@ -29,6 +29,7 @@ import com.keylesspalace.tusky.entity.Attachment import com.keylesspalace.tusky.entity.NewPoll import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.util.copyToFile +import dagger.hilt.android.qualifiers.ApplicationContext import java.io.File import java.io.IOException import java.text.SimpleDateFormat @@ -43,7 +44,7 @@ import okio.buffer import okio.sink class DraftHelper @Inject constructor( - val context: Context, + @ApplicationContext val context: Context, private val okHttpClient: OkHttpClient, db: AppDatabase ) { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftsActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftsActivity.kt index 5f83a3a32e..d6668c189d 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftsActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftsActivity.kt @@ -34,23 +34,21 @@ import com.keylesspalace.tusky.components.compose.ComposeActivity import com.keylesspalace.tusky.databinding.ActivityDraftsBinding import com.keylesspalace.tusky.db.DraftsAlert import com.keylesspalace.tusky.db.entity.DraftEntity -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.util.isHttpNotFound import com.keylesspalace.tusky.util.parseAsMastodonHtml import com.keylesspalace.tusky.util.visible +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch +@AndroidEntryPoint class DraftsActivity : BaseActivity(), DraftActionListener { - @Inject - lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var draftsAlert: DraftsAlert - private val viewModel: DraftsViewModel by viewModels { viewModelFactory } + private val viewModel: DraftsViewModel by viewModels() private lateinit var binding: ActivityDraftsBinding private lateinit var bottomSheet: BottomSheetBehavior diff --git a/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftsViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftsViewModel.kt index db46ba1ffe..32b36bbed0 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftsViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftsViewModel.kt @@ -26,9 +26,11 @@ import com.keylesspalace.tusky.db.AppDatabase import com.keylesspalace.tusky.db.entity.DraftEntity import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.network.MastodonApi +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.launch +@HiltViewModel class DraftsViewModel @Inject constructor( val database: AppDatabase, val accountManager: AccountManager, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/filters/EditFilterActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/filters/EditFilterActivity.kt index a10b709f60..d2d49b0912 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/filters/EditFilterActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/filters/EditFilterActivity.kt @@ -21,7 +21,6 @@ import com.keylesspalace.tusky.appstore.EventHub import com.keylesspalace.tusky.appstore.FilterUpdatedEvent import com.keylesspalace.tusky.databinding.ActivityEditFilterBinding import com.keylesspalace.tusky.databinding.DialogFilterBinding -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.Filter import com.keylesspalace.tusky.entity.FilterKeyword import com.keylesspalace.tusky.network.MastodonApi @@ -29,10 +28,12 @@ import com.keylesspalace.tusky.util.getParcelableExtraCompat import com.keylesspalace.tusky.util.isHttpNotFound import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.util.visible +import dagger.hilt.android.AndroidEntryPoint import java.util.Date import javax.inject.Inject import kotlinx.coroutines.launch +@AndroidEntryPoint class EditFilterActivity : BaseActivity() { @Inject lateinit var api: MastodonApi @@ -40,11 +41,8 @@ class EditFilterActivity : BaseActivity() { @Inject lateinit var eventHub: EventHub - @Inject - lateinit var viewModelFactory: ViewModelFactory - private val binding by viewBinding(ActivityEditFilterBinding::inflate) - private val viewModel: EditFilterViewModel by viewModels { viewModelFactory } + private val viewModel: EditFilterViewModel by viewModels() private lateinit var filter: Filter private var originalFilter: Filter? = null diff --git a/app/src/main/java/com/keylesspalace/tusky/components/filters/EditFilterViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/filters/EditFilterViewModel.kt index 83c8dacf18..ad213e271e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/filters/EditFilterViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/filters/EditFilterViewModel.kt @@ -9,12 +9,14 @@ import com.keylesspalace.tusky.entity.Filter import com.keylesspalace.tusky.entity.FilterKeyword import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.isHttpNotFound +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.withContext +@HiltViewModel class EditFilterViewModel @Inject constructor(val api: MastodonApi, val eventHub: EventHub) : ViewModel() { private var originalFilter: Filter? = null diff --git a/app/src/main/java/com/keylesspalace/tusky/components/filters/FiltersActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/filters/FiltersActivity.kt index 0acc043aed..31dedc59c9 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/filters/FiltersActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/filters/FiltersActivity.kt @@ -8,22 +8,20 @@ import androidx.lifecycle.lifecycleScope import com.keylesspalace.tusky.BaseActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.ActivityFiltersBinding -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.Filter import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.startActivityWithSlideInAnimation import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.util.visible -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch +@AndroidEntryPoint class FiltersActivity : BaseActivity(), FiltersListener { - @Inject - lateinit var viewModelFactory: ViewModelFactory private val binding by viewBinding(ActivityFiltersBinding::inflate) - private val viewModel: FiltersViewModel by viewModels { viewModelFactory } + private val viewModel: FiltersViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/filters/FiltersViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/filters/FiltersViewModel.kt index 0f1a5a2ac6..39c8020396 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/filters/FiltersViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/filters/FiltersViewModel.kt @@ -10,12 +10,14 @@ import com.keylesspalace.tusky.appstore.PreferenceChangedEvent import com.keylesspalace.tusky.entity.Filter import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.isHttpNotFound +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +@HiltViewModel class FiltersViewModel @Inject constructor( private val api: MastodonApi, private val eventHub: EventHub diff --git a/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt index e250dc9892..bd235c25b0 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt @@ -21,7 +21,6 @@ import com.keylesspalace.tusky.BaseActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.components.compose.ComposeAutoCompleteAdapter import com.keylesspalace.tusky.databinding.ActivityFollowedTagsBinding -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.interfaces.HashtagActionListener import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.settings.PrefKeys @@ -29,10 +28,12 @@ import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.util.visible +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch +@AndroidEntryPoint class FollowedTagsActivity : BaseActivity(), HashtagActionListener, @@ -40,14 +41,11 @@ class FollowedTagsActivity : @Inject lateinit var api: MastodonApi - @Inject - lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var sharedPreferences: SharedPreferences private val binding by viewBinding(ActivityFollowedTagsBinding::inflate) - private val viewModel: FollowedTagsViewModel by viewModels { viewModelFactory } + private val viewModel: FollowedTagsViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsViewModel.kt index f3376c13b7..7429672433 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsViewModel.kt @@ -10,15 +10,16 @@ import androidx.paging.cachedIn import at.connyduck.calladapter.networkresult.fold import com.keylesspalace.tusky.components.compose.ComposeAutoCompleteAdapter import com.keylesspalace.tusky.components.search.SearchType -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.entity.HashTag import com.keylesspalace.tusky.network.MastodonApi +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.runBlocking +@HiltViewModel class FollowedTagsViewModel @Inject constructor( private val api: MastodonApi -) : ViewModel(), Injectable { +) : ViewModel() { val tags: MutableList = mutableListOf() var nextKey: String? = null var currentSource: FollowedTagsPagingSource? = null diff --git a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt index 05d6e90359..bd4c6965a1 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt @@ -34,7 +34,6 @@ import com.keylesspalace.tusky.BuildConfig import com.keylesspalace.tusky.MainActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.ActivityLoginBinding -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.entity.AccessToken import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.getNonNullString @@ -42,12 +41,14 @@ import com.keylesspalace.tusky.util.openLinkInCustomTab import com.keylesspalace.tusky.util.rickRoll import com.keylesspalace.tusky.util.shouldRickRoll import com.keylesspalace.tusky.util.viewBinding +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.launch import okhttp3.HttpUrl /** Main login page, the first thing that users see. Has prompt for instance and login button. */ -class LoginActivity : BaseActivity(), Injectable { +@AndroidEntryPoint +class LoginActivity : BaseActivity() { @Inject lateinit var mastodonApi: MastodonApi diff --git a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt index a3e65d577e..c2ea86b3b1 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt @@ -39,13 +39,11 @@ import com.keylesspalace.tusky.BaseActivity import com.keylesspalace.tusky.BuildConfig import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.ActivityLoginWebviewBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.util.getParcelableExtraCompat import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.util.visible -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize @@ -102,13 +100,11 @@ sealed interface LoginResult : Parcelable { } /** Activity to do Oauth process using WebView. */ -class LoginWebViewActivity : BaseActivity(), Injectable { +@AndroidEntryPoint +class LoginWebViewActivity : BaseActivity() { private val binding by viewBinding(ActivityLoginWebviewBinding::inflate) - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: LoginWebViewViewModel by viewModels { viewModelFactory } + private val viewModel: LoginWebViewViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewViewModel.kt index 6c4caf8aa0..7ce8cfdbb9 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewViewModel.kt @@ -21,11 +21,13 @@ import androidx.lifecycle.viewModelScope import at.connyduck.calladapter.networkresult.fold import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.isHttpNotFound +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +@HiltViewModel class LoginWebViewViewModel @Inject constructor( private val api: MastodonApi ) : ViewModel() { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsFragment.kt index 5474957798..ed8eb30e54 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsFragment.kt @@ -52,8 +52,6 @@ import com.keylesspalace.tusky.components.preference.PreferencesFragment.Reading import com.keylesspalace.tusky.components.systemnotifications.NotificationHelper import com.keylesspalace.tusky.databinding.FragmentTimelineNotificationsBinding import com.keylesspalace.tusky.databinding.NotificationsFilterBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.Notification import com.keylesspalace.tusky.fragment.SFragment import com.keylesspalace.tusky.interfaces.AccountActionListener @@ -72,6 +70,7 @@ import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.viewdata.AttachmentViewData import com.keylesspalace.tusky.viewdata.NotificationViewData import com.keylesspalace.tusky.viewdata.TranslationViewData +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlin.time.DurationUnit import kotlin.time.toDuration @@ -79,6 +78,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch +@AndroidEntryPoint class NotificationsFragment : SFragment(), SwipeRefreshLayout.OnRefreshListener, @@ -86,11 +86,7 @@ class NotificationsFragment : NotificationActionListener, AccountActionListener, MenuProvider, - ReselectableFragment, - Injectable { - - @Inject - lateinit var viewModelFactory: ViewModelFactory + ReselectableFragment { @Inject lateinit var preferences: SharedPreferences @@ -100,7 +96,7 @@ class NotificationsFragment : private val binding by viewBinding(FragmentTimelineNotificationsBinding::bind) - private val viewModel: NotificationsViewModel by viewModels { viewModelFactory } + private val viewModel: NotificationsViewModel by viewModels() private lateinit var adapter: NotificationsPagingAdapter diff --git a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsViewModel.kt index 78362b897e..361b102d51 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsViewModel.kt @@ -51,6 +51,7 @@ import com.keylesspalace.tusky.util.serialize import com.keylesspalace.tusky.viewdata.NotificationViewData import com.keylesspalace.tusky.viewdata.StatusViewData import com.keylesspalace.tusky.viewdata.TranslationViewData +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -64,6 +65,7 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.launch import retrofit2.HttpException +@HiltViewModel class NotificationsViewModel @Inject constructor( private val timelineCases: TimelineCases, private val api: MastodonApi, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/AccountPreferencesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/AccountPreferencesFragment.kt index fcd5a3ba4f..708e44a1ae 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/preference/AccountPreferencesFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/AccountPreferencesFragment.kt @@ -38,7 +38,6 @@ import com.keylesspalace.tusky.components.followedtags.FollowedTagsActivity import com.keylesspalace.tusky.components.login.LoginActivity import com.keylesspalace.tusky.components.systemnotifications.currentAccountNeedsMigration import com.keylesspalace.tusky.db.AccountManager -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.entity.Account import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.network.MastodonApi @@ -59,10 +58,12 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeRes +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.launch -class AccountPreferencesFragment : PreferenceFragmentCompat(), Injectable { +@AndroidEntryPoint +class AccountPreferencesFragment : PreferenceFragmentCompat() { @Inject lateinit var accountManager: AccountManager diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/NotificationPreferencesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/NotificationPreferencesFragment.kt index 922d081fba..4b8eb03f6a 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/preference/NotificationPreferencesFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/NotificationPreferencesFragment.kt @@ -21,14 +21,15 @@ import com.keylesspalace.tusky.R import com.keylesspalace.tusky.components.systemnotifications.NotificationHelper import com.keylesspalace.tusky.db.AccountManager import com.keylesspalace.tusky.db.entity.AccountEntity -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.settings.PrefKeys import com.keylesspalace.tusky.settings.makePreferenceScreen import com.keylesspalace.tusky.settings.preferenceCategory import com.keylesspalace.tusky.settings.switchPreference +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject -class NotificationPreferencesFragment : PreferenceFragmentCompat(), Injectable { +@AndroidEntryPoint +class NotificationPreferencesFragment : PreferenceFragmentCompat() { @Inject lateinit var accountManager: AccountManager diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesActivity.kt index c2972fa180..d1acec2b15 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesActivity.kt @@ -39,23 +39,19 @@ import com.keylesspalace.tusky.settings.PrefKeys.APP_THEME import com.keylesspalace.tusky.util.getNonNullString import com.keylesspalace.tusky.util.setAppNightMode import com.keylesspalace.tusky.util.startActivityWithSlideInAnimation -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.launch +@AndroidEntryPoint class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreferenceChangeListener, - PreferenceFragmentCompat.OnPreferenceStartFragmentCallback, - HasAndroidInjector { + PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { @Inject lateinit var eventHub: EventHub - @Inject - lateinit var androidInjector: DispatchingAndroidInjector - private val restartActivitiesOnBackPressedCallback = object : OnBackPressedCallback(false) { override fun handleOnBackPressed() { /* Switching themes won't actually change the theme of activities on the back stack. @@ -171,8 +167,6 @@ class PreferencesActivity : } } - override fun androidInjector() = androidInjector - companion object { @Suppress("unused") private const val TAG = "PreferencesActivity" diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt index 3385d079e0..a0d4f31120 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt @@ -20,7 +20,6 @@ import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import com.keylesspalace.tusky.R import com.keylesspalace.tusky.db.AccountManager -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.entity.Notification import com.keylesspalace.tusky.settings.AppTheme import com.keylesspalace.tusky.settings.PrefKeys @@ -38,10 +37,12 @@ import com.keylesspalace.tusky.util.serialize import com.keylesspalace.tusky.util.unsafeLazy import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial +import dagger.hilt.android.AndroidEntryPoint import de.c1710.filemojicompat_ui.views.picker.preference.EmojiPickerPreference import javax.inject.Inject -class PreferencesFragment : PreferenceFragmentCompat(), Injectable { +@AndroidEntryPoint +class PreferencesFragment : PreferenceFragmentCompat() { @Inject lateinit var accountManager: AccountManager diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/TabFilterPreferencesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/TabFilterPreferencesFragment.kt index 93fe05cd0f..032b80ced1 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/preference/TabFilterPreferencesFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/TabFilterPreferencesFragment.kt @@ -22,15 +22,16 @@ import android.view.ViewGroup import androidx.preference.PreferenceFragmentCompat import com.google.android.material.color.MaterialColors import com.keylesspalace.tusky.R -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.settings.AccountPreferenceDataStore import com.keylesspalace.tusky.settings.PrefKeys import com.keylesspalace.tusky.settings.makePreferenceScreen import com.keylesspalace.tusky.settings.preferenceCategory import com.keylesspalace.tusky.settings.switchPreference +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject -class TabFilterPreferencesFragment : PreferenceFragmentCompat(), Injectable { +@AndroidEntryPoint +class TabFilterPreferencesFragment : PreferenceFragmentCompat() { @Inject lateinit var accountPreferenceDataStore: AccountPreferenceDataStore diff --git a/app/src/main/java/com/keylesspalace/tusky/components/report/ReportActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/report/ReportActivity.kt index 72ebbd2030..7cbb977824 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/report/ReportActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/report/ReportActivity.kt @@ -24,22 +24,14 @@ import com.keylesspalace.tusky.BottomSheetActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.components.report.adapter.ReportPagerAdapter import com.keylesspalace.tusky.databinding.ActivityReportBinding -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.util.viewBinding -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch -class ReportActivity : BottomSheetActivity(), HasAndroidInjector { +@AndroidEntryPoint +class ReportActivity : BottomSheetActivity() { - @Inject - lateinit var androidInjector: DispatchingAndroidInjector - - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: ReportViewModel by viewModels { viewModelFactory } + private val viewModel: ReportViewModel by viewModels() private val binding by viewBinding(ActivityReportBinding::inflate) @@ -149,6 +141,4 @@ class ReportActivity : BottomSheetActivity(), HasAndroidInjector { putExtra(STATUS_ID, statusId) } } - - override fun androidInjector() = androidInjector } diff --git a/app/src/main/java/com/keylesspalace/tusky/components/report/ReportViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/report/ReportViewModel.kt index b2b84d5ae1..a8960756cb 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/report/ReportViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/report/ReportViewModel.kt @@ -35,7 +35,9 @@ import com.keylesspalace.tusky.util.Loading import com.keylesspalace.tusky.util.Resource import com.keylesspalace.tusky.util.Success import com.keylesspalace.tusky.util.toViewData +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -45,6 +47,8 @@ import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch +@HiltViewModel +@OptIn(ExperimentalCoroutinesApi::class) class ReportViewModel @Inject constructor( private val mastodonApi: MastodonApi, private val eventHub: EventHub diff --git a/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportDoneFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportDoneFragment.kt index 2b5ed2628f..6961caea42 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportDoneFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportDoneFragment.kt @@ -24,21 +24,17 @@ import com.keylesspalace.tusky.R import com.keylesspalace.tusky.components.report.ReportViewModel import com.keylesspalace.tusky.components.report.Screen import com.keylesspalace.tusky.databinding.FragmentReportDoneBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.util.Loading import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.viewBinding -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch -class ReportDoneFragment : Fragment(R.layout.fragment_report_done), Injectable { +@AndroidEntryPoint +class ReportDoneFragment : Fragment(R.layout.fragment_report_done) { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: ReportViewModel by activityViewModels { viewModelFactory } + private val viewModel: ReportViewModel by activityViewModels() private val binding by viewBinding(FragmentReportDoneBinding::bind) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportNoteFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportNoteFragment.kt index 215414ff9f..87f5c17087 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportNoteFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportNoteFragment.kt @@ -26,24 +26,20 @@ import com.keylesspalace.tusky.R import com.keylesspalace.tusky.components.report.ReportViewModel import com.keylesspalace.tusky.components.report.Screen import com.keylesspalace.tusky.databinding.FragmentReportNoteBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.util.Error import com.keylesspalace.tusky.util.Loading import com.keylesspalace.tusky.util.Success import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.viewBinding +import dagger.hilt.android.AndroidEntryPoint import java.io.IOException -import javax.inject.Inject import kotlinx.coroutines.launch -class ReportNoteFragment : Fragment(R.layout.fragment_report_note), Injectable { +@AndroidEntryPoint +class ReportNoteFragment : Fragment(R.layout.fragment_report_note) { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: ReportViewModel by activityViewModels { viewModelFactory } + private val viewModel: ReportViewModel by activityViewModels() private val binding by viewBinding(FragmentReportNoteBinding::bind) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportStatusesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportStatusesFragment.kt index 9f20265f14..416bedb871 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportStatusesFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/report/fragments/ReportStatusesFragment.kt @@ -45,8 +45,6 @@ import com.keylesspalace.tusky.components.report.adapter.AdapterHandler import com.keylesspalace.tusky.components.report.adapter.StatusesAdapter import com.keylesspalace.tusky.databinding.FragmentReportStatusesBinding import com.keylesspalace.tusky.db.AccountManager -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.Attachment import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.settings.PrefKeys @@ -59,24 +57,22 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch +@AndroidEntryPoint class ReportStatusesFragment : Fragment(R.layout.fragment_report_statuses), - Injectable, OnRefreshListener, MenuProvider, AdapterHandler { - @Inject - lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var accountManager: AccountManager - private val viewModel: ReportViewModel by activityViewModels { viewModelFactory } + private val viewModel: ReportViewModel by activityViewModels() private val binding by viewBinding(FragmentReportStatusesBinding::bind) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledStatusActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledStatusActivity.kt index 89da2e12d0..e8d9955189 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledStatusActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledStatusActivity.kt @@ -35,8 +35,6 @@ import com.keylesspalace.tusky.appstore.EventHub import com.keylesspalace.tusky.appstore.StatusScheduledEvent import com.keylesspalace.tusky.components.compose.ComposeActivity import com.keylesspalace.tusky.databinding.ActivityScheduledStatusBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.ScheduledStatus import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.show @@ -45,23 +43,21 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch +@AndroidEntryPoint class ScheduledStatusActivity : BaseActivity(), ScheduledStatusActionListener, - MenuProvider, - Injectable { - - @Inject - lateinit var viewModelFactory: ViewModelFactory + MenuProvider { @Inject lateinit var eventHub: EventHub - private val viewModel: ScheduledStatusViewModel by viewModels { viewModelFactory } + private val viewModel: ScheduledStatusViewModel by viewModels() private val binding by viewBinding(ActivityScheduledStatusBinding::inflate) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledStatusViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledStatusViewModel.kt index 821364b9e9..6b5b84f150 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledStatusViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledStatusViewModel.kt @@ -25,9 +25,11 @@ import at.connyduck.calladapter.networkresult.fold import com.keylesspalace.tusky.appstore.EventHub import com.keylesspalace.tusky.entity.ScheduledStatus import com.keylesspalace.tusky.network.MastodonApi +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.launch +@HiltViewModel class ScheduledStatusViewModel @Inject constructor( val mastodonApi: MastodonApi, val eventHub: EventHub diff --git a/app/src/main/java/com/keylesspalace/tusky/components/search/SearchActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/search/SearchActivity.kt index 7cdff23fa3..a36cfdd84b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/search/SearchActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/search/SearchActivity.kt @@ -31,23 +31,16 @@ import com.keylesspalace.tusky.BottomSheetActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.components.search.adapter.SearchPagerAdapter import com.keylesspalace.tusky.databinding.ActivitySearchBinding -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.settings.PrefKeys import com.keylesspalace.tusky.util.reduceSwipeSensitivity import com.keylesspalace.tusky.util.unsafeLazy import com.keylesspalace.tusky.util.viewBinding -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint -class SearchActivity : BottomSheetActivity(), HasAndroidInjector, MenuProvider, SearchView.OnQueryTextListener { - @Inject - lateinit var androidInjector: DispatchingAndroidInjector +@AndroidEntryPoint +class SearchActivity : BottomSheetActivity(), MenuProvider, SearchView.OnQueryTextListener { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: SearchViewModel by viewModels { viewModelFactory } + private val viewModel: SearchViewModel by viewModels() private val binding by viewBinding(ActivitySearchBinding::inflate) @@ -167,8 +160,6 @@ class SearchActivity : BottomSheetActivity(), HasAndroidInjector, MenuProvider, return false } - override fun androidInjector() = androidInjector - companion object { const val TAG = "SearchActivity" fun getIntent(context: Context) = Intent(context, SearchActivity::class.java) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/search/SearchViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/search/SearchViewModel.kt index 6040bac3cd..5e9b57a82f 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/search/SearchViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/search/SearchViewModel.kt @@ -36,11 +36,13 @@ import com.keylesspalace.tusky.usecase.TimelineCases import com.keylesspalace.tusky.util.toViewData import com.keylesspalace.tusky.viewdata.StatusViewData import com.keylesspalace.tusky.viewdata.TranslationViewData +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.Deferred import kotlinx.coroutines.async import kotlinx.coroutines.launch +@HiltViewModel class SearchViewModel @Inject constructor( mastodonApi: MastodonApi, private val timelineCases: TimelineCases, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchAccountsFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchAccountsFragment.kt index 8e1c8100fd..dff440b07e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchAccountsFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchAccountsFragment.kt @@ -24,8 +24,10 @@ import androidx.recyclerview.widget.DividerItemDecoration import com.keylesspalace.tusky.components.search.adapter.SearchAccountsAdapter import com.keylesspalace.tusky.entity.TimelineAccount import com.keylesspalace.tusky.settings.PrefKeys +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.Flow +@AndroidEntryPoint class SearchAccountsFragment : SearchFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchFragment.kt index 1b0a92466e..526e47cc8b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchFragment.kt @@ -24,8 +24,6 @@ import com.keylesspalace.tusky.StatusListActivity import com.keylesspalace.tusky.components.account.AccountActivity import com.keylesspalace.tusky.components.search.SearchViewModel import com.keylesspalace.tusky.databinding.FragmentSearchBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.interfaces.LinkListener import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.startActivityWithSlideInAnimation @@ -43,17 +41,13 @@ import kotlinx.coroutines.launch abstract class SearchFragment : Fragment(R.layout.fragment_search), LinkListener, - Injectable, SwipeRefreshLayout.OnRefreshListener, MenuProvider { - @Inject - lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var mastodonApi: MastodonApi - protected val viewModel: SearchViewModel by activityViewModels { viewModelFactory } + protected val viewModel: SearchViewModel by activityViewModels() protected val binding by viewBinding(FragmentSearchBinding::bind) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchHashtagsFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchHashtagsFragment.kt index 8c4f41fb0c..7bd3c9d352 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchHashtagsFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchHashtagsFragment.kt @@ -22,8 +22,10 @@ import androidx.paging.PagingDataAdapter import androidx.recyclerview.widget.DividerItemDecoration import com.keylesspalace.tusky.components.search.adapter.SearchHashtagsAdapter import com.keylesspalace.tusky.entity.HashTag +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.Flow +@AndroidEntryPoint class SearchHashtagsFragment : SearchFragment() { override val data: Flow> diff --git a/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchStatusesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchStatusesFragment.kt index e9d4215694..9a4be2ed6e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchStatusesFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchStatusesFragment.kt @@ -65,11 +65,13 @@ import com.keylesspalace.tusky.util.startActivityWithSlideInAnimation import com.keylesspalace.tusky.view.showMuteAccountDialog import com.keylesspalace.tusky.viewdata.AttachmentViewData import com.keylesspalace.tusky.viewdata.StatusViewData +import dagger.hilt.android.AndroidEntryPoint import java.util.Locale import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch +@AndroidEntryPoint class SearchStatusesFragment : SearchFragment(), StatusActionListener { @Inject lateinit var accountManager: AccountManager diff --git a/app/src/main/java/com/keylesspalace/tusky/components/systemnotifications/NotificationFetcher.kt b/app/src/main/java/com/keylesspalace/tusky/components/systemnotifications/NotificationFetcher.kt index 8e86d5e22f..20b52923c2 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/systemnotifications/NotificationFetcher.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/systemnotifications/NotificationFetcher.kt @@ -14,6 +14,7 @@ import com.keylesspalace.tusky.entity.Notification import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.HttpHeaderLink import com.keylesspalace.tusky.util.isLessThan +import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject import kotlin.math.min import kotlin.time.Duration.Companion.milliseconds @@ -48,7 +49,7 @@ data class Links(val next: String?, val prev: String?) { class NotificationFetcher @Inject constructor( private val mastodonApi: MastodonApi, private val accountManager: AccountManager, - private val context: Context, + @ApplicationContext private val context: Context, private val eventHub: EventHub ) { suspend fun fetchAndShow() { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineFragment.kt index 4eb95f2bb6..b5d5840f9f 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineFragment.kt @@ -52,8 +52,6 @@ import com.keylesspalace.tusky.components.timeline.viewmodel.CachedTimelineViewM import com.keylesspalace.tusky.components.timeline.viewmodel.NetworkTimelineViewModel import com.keylesspalace.tusky.components.timeline.viewmodel.TimelineViewModel import com.keylesspalace.tusky.databinding.FragmentTimelineBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.fragment.SFragment import com.keylesspalace.tusky.interfaces.ActionButtonActivity @@ -77,30 +75,29 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch +@AndroidEntryPoint class TimelineFragment : SFragment(), OnRefreshListener, StatusActionListener, - Injectable, ReselectableFragment, RefreshableFragment, MenuProvider { - @Inject - lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var eventHub: EventHub private val viewModel: TimelineViewModel by unsafeLazy { + val viewModelProvider = ViewModelProvider(viewModelStore, defaultViewModelProviderFactory, defaultViewModelCreationExtras) if (kind == TimelineViewModel.Kind.HOME) { - ViewModelProvider(this, viewModelFactory)[CachedTimelineViewModel::class.java] + viewModelProvider[CachedTimelineViewModel::class.java] } else { - ViewModelProvider(this, viewModelFactory)[NetworkTimelineViewModel::class.java] + viewModelProvider[NetworkTimelineViewModel::class.java] } } diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt index bc3aa9d49c..c3a9d7ec42 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt @@ -48,6 +48,7 @@ import com.keylesspalace.tusky.usecase.TimelineCases import com.keylesspalace.tusky.util.EmptyPagingSource import com.keylesspalace.tusky.viewdata.StatusViewData import com.keylesspalace.tusky.viewdata.TranslationViewData +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -59,6 +60,7 @@ import retrofit2.HttpException /** * TimelineViewModel that caches all statuses in a local database */ +@HiltViewModel class CachedTimelineViewModel @Inject constructor( timelineCases: TimelineCases, private val api: MastodonApi, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt index e2939c97bc..1d6ea27ac1 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt @@ -48,6 +48,7 @@ import com.keylesspalace.tusky.util.isLessThanOrEqual import com.keylesspalace.tusky.util.toViewData import com.keylesspalace.tusky.viewdata.StatusViewData import com.keylesspalace.tusky.viewdata.TranslationViewData +import dagger.hilt.android.lifecycle.HiltViewModel import java.io.IOException import javax.inject.Inject import kotlinx.coroutines.Dispatchers @@ -61,6 +62,7 @@ import retrofit2.Response /** * TimelineViewModel that caches all statuses in an in-memory list */ +@HiltViewModel class NetworkTimelineViewModel @Inject constructor( timelineCases: TimelineCases, private val api: MastodonApi, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingActivity.kt index bdf2cdc793..6e205a21f5 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingActivity.kt @@ -23,14 +23,10 @@ import com.keylesspalace.tusky.BaseActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.ActivityTrendingBinding import com.keylesspalace.tusky.util.viewBinding -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint -class TrendingActivity : BaseActivity(), HasAndroidInjector { - - @Inject - lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector +@AndroidEntryPoint +class TrendingActivity : BaseActivity() { private val binding: ActivityTrendingBinding by viewBinding(ActivityTrendingBinding::inflate) @@ -54,8 +50,6 @@ class TrendingActivity : BaseActivity(), HasAndroidInjector { } } - override fun androidInjector() = dispatchingAndroidInjector - companion object { fun getIntent(context: Context) = Intent(context, TrendingActivity::class.java) } diff --git a/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingTagsFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingTagsFragment.kt index 6b0a62af9d..e746f45047 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingTagsFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingTagsFragment.kt @@ -34,8 +34,6 @@ import com.keylesspalace.tusky.R import com.keylesspalace.tusky.StatusListActivity import com.keylesspalace.tusky.components.trending.viewmodel.TrendingTagsViewModel import com.keylesspalace.tusky.databinding.FragmentTrendingTagsBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.interfaces.ActionButtonActivity import com.keylesspalace.tusky.interfaces.RefreshableFragment import com.keylesspalace.tusky.interfaces.ReselectableFragment @@ -44,21 +42,18 @@ import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.startActivityWithSlideInAnimation import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.viewdata.TrendingViewData -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch +@AndroidEntryPoint class TrendingTagsFragment : Fragment(R.layout.fragment_trending_tags), OnRefreshListener, - Injectable, ReselectableFragment, RefreshableFragment { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: TrendingTagsViewModel by viewModels { viewModelFactory } + private val viewModel: TrendingTagsViewModel by viewModels() private val binding by viewBinding(FragmentTrendingTagsBinding::bind) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/trending/viewmodel/TrendingTagsViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/trending/viewmodel/TrendingTagsViewModel.kt index 3237d8eadb..ea8b4b0929 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/trending/viewmodel/TrendingTagsViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/trending/viewmodel/TrendingTagsViewModel.kt @@ -27,6 +27,7 @@ import com.keylesspalace.tusky.entity.start import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.toViewData import com.keylesspalace.tusky.viewdata.TrendingViewData +import dagger.hilt.android.lifecycle.HiltViewModel import java.io.IOException import javax.inject.Inject import kotlinx.coroutines.async @@ -35,6 +36,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.launch +@HiltViewModel class TrendingTagsViewModel @Inject constructor( private val mastodonApi: MastodonApi, private val eventHub: EventHub diff --git a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadActivity.kt index 70c0df191c..5227fb2934 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadActivity.kt @@ -23,17 +23,13 @@ import com.keylesspalace.tusky.BottomSheetActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.ActivityViewThreadBinding import com.keylesspalace.tusky.util.viewBinding -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasAndroidInjector -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint -class ViewThreadActivity : BottomSheetActivity(), HasAndroidInjector { +@AndroidEntryPoint +class ViewThreadActivity : BottomSheetActivity() { private val binding by viewBinding(ActivityViewThreadBinding::inflate) - @Inject - lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(binding.root) @@ -54,8 +50,6 @@ class ViewThreadActivity : BottomSheetActivity(), HasAndroidInjector { } } - override fun androidInjector() = dispatchingAndroidInjector - companion object { fun startIntent(context: Context, id: String, url: String): Intent { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadFragment.kt index 7a074c4740..7ed5695380 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadFragment.kt @@ -42,8 +42,6 @@ import com.keylesspalace.tusky.components.accountlist.AccountListActivity import com.keylesspalace.tusky.components.accountlist.AccountListActivity.Companion.newIntent import com.keylesspalace.tusky.components.viewthread.edits.ViewEditsFragment import com.keylesspalace.tusky.databinding.FragmentViewThreadBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.fragment.SFragment import com.keylesspalace.tusky.interfaces.StatusActionListener import com.keylesspalace.tusky.settings.PrefKeys @@ -58,23 +56,20 @@ import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.viewdata.AttachmentViewData.Companion.list import com.keylesspalace.tusky.viewdata.StatusViewData import com.keylesspalace.tusky.viewdata.TranslationViewData -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.delay import kotlinx.coroutines.launch +@AndroidEntryPoint class ViewThreadFragment : SFragment(), OnRefreshListener, StatusActionListener, - MenuProvider, - Injectable { + MenuProvider { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: ViewThreadViewModel by viewModels { viewModelFactory } + private val viewModel: ViewThreadViewModel by viewModels() private val binding by viewBinding(FragmentViewThreadBinding::bind) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadViewModel.kt index 3946065200..7934f1cff6 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadViewModel.kt @@ -45,6 +45,7 @@ import com.keylesspalace.tusky.util.toViewData import com.keylesspalace.tusky.viewdata.StatusViewData import com.keylesspalace.tusky.viewdata.TranslationViewData import com.squareup.moshi.Moshi +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.Job import kotlinx.coroutines.async @@ -58,6 +59,7 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +@HiltViewModel class ViewThreadViewModel @Inject constructor( private val api: MastodonApi, private val filterModel: FilterModel, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/edits/ViewEditsFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/edits/ViewEditsFragment.kt index d03ed9e8d8..a0f3cc1e6e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/edits/ViewEditsFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/edits/ViewEditsFragment.kt @@ -38,8 +38,6 @@ import com.keylesspalace.tusky.R import com.keylesspalace.tusky.StatusListActivity import com.keylesspalace.tusky.components.account.AccountActivity import com.keylesspalace.tusky.databinding.FragmentViewEditsBinding -import com.keylesspalace.tusky.di.Injectable -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.interfaces.LinkListener import com.keylesspalace.tusky.settings.PrefKeys import com.keylesspalace.tusky.util.emojify @@ -53,20 +51,17 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch +@AndroidEntryPoint class ViewEditsFragment : Fragment(R.layout.fragment_view_edits), LinkListener, OnRefreshListener, - MenuProvider, - Injectable { + MenuProvider { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: ViewEditsViewModel by viewModels { viewModelFactory } + private val viewModel: ViewEditsViewModel by viewModels() private val binding by viewBinding(FragmentViewEditsBinding::bind) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/edits/ViewEditsViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/edits/ViewEditsViewModel.kt index a110c57a95..96b7ecd1bb 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/edits/ViewEditsViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/edits/ViewEditsViewModel.kt @@ -22,6 +22,7 @@ import com.keylesspalace.tusky.components.viewthread.edits.EditsTagHandler.Compa import com.keylesspalace.tusky.components.viewthread.edits.EditsTagHandler.Companion.INSERTED_TEXT_EL import com.keylesspalace.tusky.entity.StatusEdit import com.keylesspalace.tusky.network.MastodonApi +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -43,13 +44,14 @@ import org.pageseeder.diffx.xml.NamespaceSet import org.pageseeder.xmlwriter.XML.NamespaceAware import org.pageseeder.xmlwriter.XMLStringWriter +@HiltViewModel class ViewEditsViewModel @Inject constructor(private val api: MastodonApi) : ViewModel() { private val _uiState = MutableStateFlow(EditsUiState.Initial as EditsUiState) val uiState: StateFlow = _uiState.asStateFlow() /** The API call to fetch edit history returned less than two items */ - object MissingEditsException : Exception() + class MissingEditsException : Exception() fun loadEdits(statusId: String, force: Boolean = false, refreshing: Boolean = false) { if (!force && _uiState.value !is EditsUiState.Initial) return @@ -69,7 +71,7 @@ class ViewEditsViewModel @Inject constructor(private val api: MastodonApi) : Vie // `edits` might have fewer than the minimum number of entries because of // https://github.com/mastodon/mastodon/issues/25398. if (edits.size < 2) { - _uiState.value = EditsUiState.Error(MissingEditsException) + _uiState.value = EditsUiState.Error(MissingEditsException()) return@launch } diff --git a/app/src/main/java/com/keylesspalace/tusky/di/ActivitiesModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/ActivitiesModule.kt deleted file mode 100644 index a8fe4b9b61..0000000000 --- a/app/src/main/java/com/keylesspalace/tusky/di/ActivitiesModule.kt +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2018 charlag - * - * This file is a part of Tusky. - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Tusky; if not, - * see . */ - -package com.keylesspalace.tusky.di - -import com.keylesspalace.tusky.AboutActivity -import com.keylesspalace.tusky.BaseActivity -import com.keylesspalace.tusky.EditProfileActivity -import com.keylesspalace.tusky.LicenseActivity -import com.keylesspalace.tusky.ListsActivity -import com.keylesspalace.tusky.MainActivity -import com.keylesspalace.tusky.SplashActivity -import com.keylesspalace.tusky.StatusListActivity -import com.keylesspalace.tusky.TabPreferenceActivity -import com.keylesspalace.tusky.ViewMediaActivity -import com.keylesspalace.tusky.components.account.AccountActivity -import com.keylesspalace.tusky.components.accountlist.AccountListActivity -import com.keylesspalace.tusky.components.announcements.AnnouncementsActivity -import com.keylesspalace.tusky.components.compose.ComposeActivity -import com.keylesspalace.tusky.components.domainblocks.DomainBlocksActivity -import com.keylesspalace.tusky.components.drafts.DraftsActivity -import com.keylesspalace.tusky.components.filters.EditFilterActivity -import com.keylesspalace.tusky.components.filters.FiltersActivity -import com.keylesspalace.tusky.components.followedtags.FollowedTagsActivity -import com.keylesspalace.tusky.components.login.LoginActivity -import com.keylesspalace.tusky.components.login.LoginWebViewActivity -import com.keylesspalace.tusky.components.preference.PreferencesActivity -import com.keylesspalace.tusky.components.report.ReportActivity -import com.keylesspalace.tusky.components.scheduled.ScheduledStatusActivity -import com.keylesspalace.tusky.components.search.SearchActivity -import com.keylesspalace.tusky.components.trending.TrendingActivity -import com.keylesspalace.tusky.components.viewthread.ViewThreadActivity -import dagger.Module -import dagger.android.ContributesAndroidInjector - -/** - * Created by charlag on 3/24/18. - */ - -@Module -abstract class ActivitiesModule { - - @ContributesAndroidInjector - abstract fun contributesBaseActivity(): BaseActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesMainActivity(): MainActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesAccountActivity(): AccountActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesListsActivity(): ListsActivity - - @ContributesAndroidInjector - abstract fun contributesComposeActivity(): ComposeActivity - - @ContributesAndroidInjector - abstract fun contributesEditProfileActivity(): EditProfileActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesAccountListActivity(): AccountListActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesViewThreadActivity(): ViewThreadActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesStatusListActivity(): StatusListActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesSearchActivity(): SearchActivity - - @ContributesAndroidInjector - abstract fun contributesAboutActivity(): AboutActivity - - @ContributesAndroidInjector - abstract fun contributesLoginActivity(): LoginActivity - - @ContributesAndroidInjector - abstract fun contributesLoginWebViewActivity(): LoginWebViewActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesPreferencesActivity(): PreferencesActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesViewMediaActivity(): ViewMediaActivity - - @ContributesAndroidInjector - abstract fun contributesLicenseActivity(): LicenseActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesTabPreferenceActivity(): TabPreferenceActivity - - @ContributesAndroidInjector - abstract fun contributesFiltersActivity(): FiltersActivity - - @ContributesAndroidInjector - abstract fun contributesFollowedTagsActivity(): FollowedTagsActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesReportActivity(): ReportActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesInstanceListActivity(): DomainBlocksActivity - - @ContributesAndroidInjector - abstract fun contributesScheduledStatusActivity(): ScheduledStatusActivity - - @ContributesAndroidInjector - abstract fun contributesAnnouncementsActivity(): AnnouncementsActivity - - @ContributesAndroidInjector - abstract fun contributesDraftActivity(): DraftsActivity - - @ContributesAndroidInjector - abstract fun contributesSplashActivity(): SplashActivity - - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributesTrendingActivity(): TrendingActivity - - @ContributesAndroidInjector - abstract fun contributesEditFilterActivity(): EditFilterActivity -} diff --git a/app/src/main/java/com/keylesspalace/tusky/di/AppComponent.kt b/app/src/main/java/com/keylesspalace/tusky/di/AppComponent.kt deleted file mode 100644 index 91045baefb..0000000000 --- a/app/src/main/java/com/keylesspalace/tusky/di/AppComponent.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright 2018 charlag - * - * This file is a part of Tusky. - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Tusky; if not, - * see . */ - -package com.keylesspalace.tusky.di - -import com.keylesspalace.tusky.TuskyApplication -import dagger.BindsInstance -import dagger.Component -import dagger.android.support.AndroidSupportInjectionModule -import javax.inject.Singleton - -/** - * Created by charlag on 3/21/18. - */ - -@Singleton -@Component( - modules = [ - AppModule::class, - CoroutineScopeModule::class, - NetworkModule::class, - AndroidSupportInjectionModule::class, - ActivitiesModule::class, - ServicesModule::class, - BroadcastReceiverModule::class, - ViewModelModule::class, - WorkerModule::class, - PlayerModule::class - ] -) -interface AppComponent { - @Component.Builder - interface Builder { - @BindsInstance - fun application(tuskyApp: TuskyApplication): Builder - - fun build(): AppComponent - } - - fun inject(app: TuskyApplication) -} diff --git a/app/src/main/java/com/keylesspalace/tusky/di/AppInjector.kt b/app/src/main/java/com/keylesspalace/tusky/di/AppInjector.kt deleted file mode 100644 index fa6fae851b..0000000000 --- a/app/src/main/java/com/keylesspalace/tusky/di/AppInjector.kt +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright 2018 charlag - * - * This file is a part of Tusky. - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Tusky; if not, - * see . */ - -package com.keylesspalace.tusky.di - -import android.app.Activity -import android.app.Application -import android.content.Context -import android.os.Bundle -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity -import androidx.fragment.app.FragmentManager -import com.keylesspalace.tusky.TuskyApplication -import dagger.android.AndroidInjection -import dagger.android.HasAndroidInjector -import dagger.android.support.AndroidSupportInjection - -/** - * Created by charlag on 3/24/18. - */ - -object AppInjector { - fun init(app: TuskyApplication) { - DaggerAppComponent.builder().application(app) - .build().inject(app) - - app.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks { - override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { - handleActivity(activity) - } - - override fun onActivityPaused(activity: Activity) { - } - - override fun onActivityResumed(activity: Activity) { - } - - override fun onActivityStarted(activity: Activity) { - } - - override fun onActivityDestroyed(activity: Activity) { - } - - override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) { - } - - override fun onActivityStopped(activity: Activity) { - } - }) - } - - private fun handleActivity(activity: Activity) { - if (activity is HasAndroidInjector || activity is Injectable) { - AndroidInjection.inject(activity) - } - if (activity is FragmentActivity) { - activity.supportFragmentManager.registerFragmentLifecycleCallbacks( - object : FragmentManager.FragmentLifecycleCallbacks() { - override fun onFragmentPreAttached( - fm: FragmentManager, - f: Fragment, - context: Context - ) { - if (f is Injectable) { - AndroidSupportInjection.inject(f) - } - } - }, - true - ) - } - } -} diff --git a/app/src/main/java/com/keylesspalace/tusky/di/BroadcastReceiverModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/BroadcastReceiverModule.kt deleted file mode 100644 index 82c83e1d94..0000000000 --- a/app/src/main/java/com/keylesspalace/tusky/di/BroadcastReceiverModule.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright 2018 Jeremiasz Nelz - * Copyright 2018 Conny Duck - * - * This file is a part of Tusky. - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Tusky; if not, - * see . */ - -package com.keylesspalace.tusky.di - -import com.keylesspalace.tusky.receiver.NotificationBlockStateBroadcastReceiver -import com.keylesspalace.tusky.receiver.SendStatusBroadcastReceiver -import com.keylesspalace.tusky.receiver.UnifiedPushBroadcastReceiver -import dagger.Module -import dagger.android.ContributesAndroidInjector - -@Module -abstract class BroadcastReceiverModule { - @ContributesAndroidInjector - abstract fun contributeSendStatusBroadcastReceiver(): SendStatusBroadcastReceiver - - @ContributesAndroidInjector - abstract fun contributeUnifiedPushBroadcastReceiver(): UnifiedPushBroadcastReceiver - - @ContributesAndroidInjector - abstract fun contributeNotificationBlockStateBroadcastReceiver(): NotificationBlockStateBroadcastReceiver -} diff --git a/app/src/main/java/com/keylesspalace/tusky/di/CoroutineScopeModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/CoroutineScopeModule.kt index 7eef6543a4..61f513f510 100644 --- a/app/src/main/java/com/keylesspalace/tusky/di/CoroutineScopeModule.kt +++ b/app/src/main/java/com/keylesspalace/tusky/di/CoroutineScopeModule.kt @@ -19,6 +19,8 @@ package com.keylesspalace.tusky.di import dagger.Module import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent import javax.inject.Qualifier import javax.inject.Singleton import kotlinx.coroutines.CoroutineScope @@ -38,7 +40,8 @@ import kotlinx.coroutines.SupervisorJob annotation class ApplicationScope @Module -class CoroutineScopeModule { +@InstallIn(SingletonComponent::class) +object CoroutineScopeModule { @ApplicationScope @Provides @Singleton diff --git a/app/src/main/java/com/keylesspalace/tusky/di/FragmentBuildersModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/FragmentBuildersModule.kt deleted file mode 100644 index cf2d05b4ae..0000000000 --- a/app/src/main/java/com/keylesspalace/tusky/di/FragmentBuildersModule.kt +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright 2018 charlag - * - * This file is a part of Tusky. - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Tusky; if not, - * see . */ - -package com.keylesspalace.tusky.di - -import com.keylesspalace.tusky.AccountsInListFragment -import com.keylesspalace.tusky.components.account.list.ListSelectionFragment -import com.keylesspalace.tusky.components.account.media.AccountMediaFragment -import com.keylesspalace.tusky.components.accountlist.AccountListFragment -import com.keylesspalace.tusky.components.conversation.ConversationsFragment -import com.keylesspalace.tusky.components.domainblocks.DomainBlocksFragment -import com.keylesspalace.tusky.components.notifications.NotificationsFragment -import com.keylesspalace.tusky.components.preference.AccountPreferencesFragment -import com.keylesspalace.tusky.components.preference.NotificationPreferencesFragment -import com.keylesspalace.tusky.components.preference.PreferencesFragment -import com.keylesspalace.tusky.components.preference.TabFilterPreferencesFragment -import com.keylesspalace.tusky.components.report.fragments.ReportDoneFragment -import com.keylesspalace.tusky.components.report.fragments.ReportNoteFragment -import com.keylesspalace.tusky.components.report.fragments.ReportStatusesFragment -import com.keylesspalace.tusky.components.search.fragments.SearchAccountsFragment -import com.keylesspalace.tusky.components.search.fragments.SearchHashtagsFragment -import com.keylesspalace.tusky.components.search.fragments.SearchStatusesFragment -import com.keylesspalace.tusky.components.timeline.TimelineFragment -import com.keylesspalace.tusky.components.trending.TrendingTagsFragment -import com.keylesspalace.tusky.components.viewthread.ViewThreadFragment -import com.keylesspalace.tusky.components.viewthread.edits.ViewEditsFragment -import com.keylesspalace.tusky.fragment.ViewVideoFragment -import dagger.Module -import dagger.android.ContributesAndroidInjector - -@Module -abstract class FragmentBuildersModule { - @ContributesAndroidInjector - abstract fun accountListFragment(): AccountListFragment - - @ContributesAndroidInjector - abstract fun accountMediaFragment(): AccountMediaFragment - - @ContributesAndroidInjector - abstract fun viewThreadFragment(): ViewThreadFragment - - @ContributesAndroidInjector - abstract fun viewEditsFragment(): ViewEditsFragment - - @ContributesAndroidInjector - abstract fun timelineFragment(): TimelineFragment - - @ContributesAndroidInjector - abstract fun notificationsFragment(): NotificationsFragment - - @ContributesAndroidInjector - abstract fun notificationPreferencesFragment(): NotificationPreferencesFragment - - @ContributesAndroidInjector - abstract fun accountPreferencesFragment(): AccountPreferencesFragment - - @ContributesAndroidInjector - abstract fun conversationsFragment(): ConversationsFragment - - @ContributesAndroidInjector - abstract fun accountInListsFragment(): AccountsInListFragment - - @ContributesAndroidInjector - abstract fun reportStatusesFragment(): ReportStatusesFragment - - @ContributesAndroidInjector - abstract fun reportNoteFragment(): ReportNoteFragment - - @ContributesAndroidInjector - abstract fun reportDoneFragment(): ReportDoneFragment - - @ContributesAndroidInjector - abstract fun instanceListFragment(): DomainBlocksFragment - - @ContributesAndroidInjector - abstract fun searchStatusesFragment(): SearchStatusesFragment - - @ContributesAndroidInjector - abstract fun searchAccountFragment(): SearchAccountsFragment - - @ContributesAndroidInjector - abstract fun searchHashtagsFragment(): SearchHashtagsFragment - - @ContributesAndroidInjector - abstract fun preferencesFragment(): PreferencesFragment - - @ContributesAndroidInjector - abstract fun listsForAccountFragment(): ListSelectionFragment - - @ContributesAndroidInjector - abstract fun trendingTagsFragment(): TrendingTagsFragment - - @ContributesAndroidInjector - abstract fun viewVideoFragment(): ViewVideoFragment - - @ContributesAndroidInjector - abstract fun tabFilterPreferencesFragment(): TabFilterPreferencesFragment -} diff --git a/app/src/main/java/com/keylesspalace/tusky/di/Injectable.kt b/app/src/main/java/com/keylesspalace/tusky/di/Injectable.kt deleted file mode 100644 index f3b4e81056..0000000000 --- a/app/src/main/java/com/keylesspalace/tusky/di/Injectable.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 charlag - * - * This file is a part of Tusky. - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Tusky; if not, - * see . */ - -package com.keylesspalace.tusky.di - -/** - * Created by charlag on 3/24/18. - */ - -interface Injectable diff --git a/app/src/main/java/com/keylesspalace/tusky/di/NetworkModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/NetworkModule.kt index b06ed2afd4..b1ccfa4be1 100644 --- a/app/src/main/java/com/keylesspalace/tusky/di/NetworkModule.kt +++ b/app/src/main/java/com/keylesspalace/tusky/di/NetworkModule.kt @@ -39,6 +39,9 @@ import com.squareup.moshi.adapters.EnumJsonAdapter import com.squareup.moshi.adapters.Rfc3339DateJsonAdapter import dagger.Module import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent import java.net.IDN import java.net.InetSocketAddress import java.net.Proxy @@ -58,6 +61,7 @@ import retrofit2.create */ @Module +@InstallIn(SingletonComponent::class) object NetworkModule { private const val TAG = "NetworkModule" @@ -89,7 +93,7 @@ object NetworkModule { @Singleton fun providesHttpClient( accountManager: AccountManager, - context: Context, + @ApplicationContext context: Context, preferences: SharedPreferences ): OkHttpClient { val httpProxyEnabled = preferences.getBoolean(HTTP_PROXY_ENABLED, false) diff --git a/app/src/main/java/com/keylesspalace/tusky/di/PlayerModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/PlayerModule.kt index f12587fc55..ac5cf7bab9 100644 --- a/app/src/main/java/com/keylesspalace/tusky/di/PlayerModule.kt +++ b/app/src/main/java/com/keylesspalace/tusky/di/PlayerModule.kt @@ -53,19 +53,26 @@ import androidx.media3.extractor.text.webvtt.WebvttParser import androidx.media3.extractor.wav.WavExtractor import dagger.Module import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent import okhttp3.OkHttpClient @Module +@InstallIn(SingletonComponent::class) @OptIn(UnstableApi::class) object PlayerModule { @Provides - fun provideAudioSink(context: Context): AudioSink { + fun provideAudioSink(@ApplicationContext context: Context): AudioSink { return DefaultAudioSink.Builder(context) .build() } @Provides - fun provideRenderersFactory(context: Context, audioSink: AudioSink): RenderersFactory { + fun provideRenderersFactory( + @ApplicationContext context: Context, + audioSink: AudioSink + ): RenderersFactory { return RenderersFactory { eventHandler, videoRendererEventListener, audioRendererEventListener, @@ -154,7 +161,10 @@ object PlayerModule { } @Provides - fun provideDataSourceFactory(context: Context, okHttpClient: OkHttpClient): DataSource.Factory { + fun provideDataSourceFactory( + @ApplicationContext context: Context, + okHttpClient: OkHttpClient + ): DataSource.Factory { return DefaultDataSource.Factory(context, OkHttpDataSource.Factory(okHttpClient)) } @@ -169,7 +179,7 @@ object PlayerModule { @Provides fun provideExoPlayer( - context: Context, + @ApplicationContext context: Context, renderersFactory: RenderersFactory, mediaSourceFactory: MediaSource.Factory ): ExoPlayer { diff --git a/app/src/main/java/com/keylesspalace/tusky/di/ServicesModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/ServicesModule.kt deleted file mode 100644 index 1d7510a2c2..0000000000 --- a/app/src/main/java/com/keylesspalace/tusky/di/ServicesModule.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2018 Conny Duck - * - * This file is a part of Tusky. - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Tusky; if not, - * see . */ - -package com.keylesspalace.tusky.di - -import com.keylesspalace.tusky.service.SendStatusService -import dagger.Module -import dagger.android.ContributesAndroidInjector - -@Module -abstract class ServicesModule { - @ContributesAndroidInjector - abstract fun contributesSendStatusService(): SendStatusService -} diff --git a/app/src/main/java/com/keylesspalace/tusky/di/AppModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/StorageModule.kt similarity index 88% rename from app/src/main/java/com/keylesspalace/tusky/di/AppModule.kt rename to app/src/main/java/com/keylesspalace/tusky/di/StorageModule.kt index e1b446f5d8..4086aefd57 100644 --- a/app/src/main/java/com/keylesspalace/tusky/di/AppModule.kt +++ b/app/src/main/java/com/keylesspalace/tusky/di/StorageModule.kt @@ -15,16 +15,17 @@ package com.keylesspalace.tusky.di -import android.app.Application import android.content.Context import android.content.SharedPreferences import androidx.preference.PreferenceManager import androidx.room.Room -import com.keylesspalace.tusky.TuskyApplication import com.keylesspalace.tusky.db.AppDatabase import com.keylesspalace.tusky.db.Converters import dagger.Module import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent import javax.inject.Singleton /** @@ -32,22 +33,17 @@ import javax.inject.Singleton */ @Module -class AppModule { +@InstallIn(SingletonComponent::class) +object StorageModule { @Provides - fun providesApplication(app: TuskyApplication): Application = app - - @Provides - fun providesContext(app: Application): Context = app - - @Provides - fun providesSharedPreferences(app: Application): SharedPreferences { - return PreferenceManager.getDefaultSharedPreferences(app) + fun providesSharedPreferences(@ApplicationContext appContext: Context): SharedPreferences { + return PreferenceManager.getDefaultSharedPreferences(appContext) } @Provides @Singleton - fun providesDatabase(appContext: Context, converters: Converters): AppDatabase { + fun providesDatabase(@ApplicationContext appContext: Context, converters: Converters): AppDatabase { return Room.databaseBuilder(appContext, AppDatabase::class.java, "tuskyDB") .addTypeConverter(converters) .allowMainThreadQueries() diff --git a/app/src/main/java/com/keylesspalace/tusky/di/ViewModelFactory.kt b/app/src/main/java/com/keylesspalace/tusky/di/ViewModelFactory.kt deleted file mode 100644 index 3fbcbe096f..0000000000 --- a/app/src/main/java/com/keylesspalace/tusky/di/ViewModelFactory.kt +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2023 Tusky Contributors - * - * This file is a part of Tusky. - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Tusky; if not, - * see . - */ - -// from https://proandroiddev.com/viewmodel-with-dagger2-architecture-components-2e06f06c9455 - -package com.keylesspalace.tusky.di - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import com.keylesspalace.tusky.components.account.AccountViewModel -import com.keylesspalace.tusky.components.account.list.ListsForAccountViewModel -import com.keylesspalace.tusky.components.account.media.AccountMediaViewModel -import com.keylesspalace.tusky.components.announcements.AnnouncementsViewModel -import com.keylesspalace.tusky.components.compose.ComposeViewModel -import com.keylesspalace.tusky.components.conversation.ConversationsViewModel -import com.keylesspalace.tusky.components.domainblocks.DomainBlocksViewModel -import com.keylesspalace.tusky.components.drafts.DraftsViewModel -import com.keylesspalace.tusky.components.filters.EditFilterViewModel -import com.keylesspalace.tusky.components.filters.FiltersViewModel -import com.keylesspalace.tusky.components.followedtags.FollowedTagsViewModel -import com.keylesspalace.tusky.components.login.LoginWebViewViewModel -import com.keylesspalace.tusky.components.notifications.NotificationsViewModel -import com.keylesspalace.tusky.components.report.ReportViewModel -import com.keylesspalace.tusky.components.scheduled.ScheduledStatusViewModel -import com.keylesspalace.tusky.components.search.SearchViewModel -import com.keylesspalace.tusky.components.timeline.viewmodel.CachedTimelineViewModel -import com.keylesspalace.tusky.components.timeline.viewmodel.NetworkTimelineViewModel -import com.keylesspalace.tusky.components.trending.viewmodel.TrendingTagsViewModel -import com.keylesspalace.tusky.components.viewthread.ViewThreadViewModel -import com.keylesspalace.tusky.components.viewthread.edits.ViewEditsViewModel -import com.keylesspalace.tusky.viewmodel.AccountsInListViewModel -import com.keylesspalace.tusky.viewmodel.EditProfileViewModel -import com.keylesspalace.tusky.viewmodel.ListsViewModel -import dagger.Binds -import dagger.MapKey -import dagger.Module -import dagger.multibindings.IntoMap -import javax.inject.Inject -import javax.inject.Provider -import javax.inject.Singleton -import kotlin.reflect.KClass - -@Singleton -class ViewModelFactory @Inject constructor( - private val viewModels: MutableMap, Provider> -) : ViewModelProvider.Factory { - @Suppress("UNCHECKED_CAST") - override fun create(modelClass: Class): T = - viewModels[modelClass]?.get() as T -} - -@Target( - AnnotationTarget.FUNCTION, - AnnotationTarget.PROPERTY_GETTER, - AnnotationTarget.PROPERTY_SETTER -) -@Retention(AnnotationRetention.RUNTIME) -@MapKey -internal annotation class ViewModelKey(val value: KClass) - -@Module -abstract class ViewModelModule { - - @Binds - internal abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory - - @Binds - @IntoMap - @ViewModelKey(AccountViewModel::class) - internal abstract fun accountViewModel(viewModel: AccountViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(EditProfileViewModel::class) - internal abstract fun editProfileViewModel(viewModel: EditProfileViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(ConversationsViewModel::class) - internal abstract fun conversationsViewModel(viewModel: ConversationsViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(ListsViewModel::class) - internal abstract fun listsViewModel(viewModel: ListsViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(AccountsInListViewModel::class) - internal abstract fun accountsInListViewModel(viewModel: AccountsInListViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(ReportViewModel::class) - internal abstract fun reportViewModel(viewModel: ReportViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(SearchViewModel::class) - internal abstract fun searchViewModel(viewModel: SearchViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(ComposeViewModel::class) - internal abstract fun composeViewModel(viewModel: ComposeViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(ScheduledStatusViewModel::class) - internal abstract fun scheduledStatusViewModel(viewModel: ScheduledStatusViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(AnnouncementsViewModel::class) - internal abstract fun announcementsViewModel(viewModel: AnnouncementsViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(DraftsViewModel::class) - internal abstract fun draftsViewModel(viewModel: DraftsViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(CachedTimelineViewModel::class) - internal abstract fun cachedTimelineViewModel(viewModel: CachedTimelineViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(NetworkTimelineViewModel::class) - internal abstract fun networkTimelineViewModel(viewModel: NetworkTimelineViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(ViewThreadViewModel::class) - internal abstract fun viewThreadViewModel(viewModel: ViewThreadViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(ViewEditsViewModel::class) - internal abstract fun viewEditsViewModel(viewModel: ViewEditsViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(AccountMediaViewModel::class) - internal abstract fun accountMediaViewModel(viewModel: AccountMediaViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(LoginWebViewViewModel::class) - internal abstract fun loginWebViewViewModel(viewModel: LoginWebViewViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(FollowedTagsViewModel::class) - internal abstract fun followedTagsViewModel(viewModel: FollowedTagsViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(ListsForAccountViewModel::class) - internal abstract fun listsForAccountViewModel(viewModel: ListsForAccountViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(TrendingTagsViewModel::class) - internal abstract fun trendingTagsViewModel(viewModel: TrendingTagsViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(FiltersViewModel::class) - internal abstract fun filtersViewModel(viewModel: FiltersViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(EditFilterViewModel::class) - internal abstract fun editFilterViewModel(viewModel: EditFilterViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(DomainBlocksViewModel::class) - internal abstract fun instanceMuteViewModel(viewModel: DomainBlocksViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(NotificationsViewModel::class) - internal abstract fun notificationsViewModel(viewModel: NotificationsViewModel): ViewModel - - // Add more ViewModels here -} diff --git a/app/src/main/java/com/keylesspalace/tusky/di/WorkerModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/WorkerModule.kt deleted file mode 100644 index a2cccf992b..0000000000 --- a/app/src/main/java/com/keylesspalace/tusky/di/WorkerModule.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2023 Tusky Contributors - * - * This file is a part of Tusky. - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Tusky; if not, - * see . - */ - -package com.keylesspalace.tusky.di - -import androidx.work.ListenableWorker -import com.keylesspalace.tusky.worker.ChildWorkerFactory -import com.keylesspalace.tusky.worker.NotificationWorker -import com.keylesspalace.tusky.worker.PruneCacheWorker -import dagger.Binds -import dagger.MapKey -import dagger.Module -import dagger.multibindings.IntoMap -import kotlin.reflect.KClass - -@Retention(AnnotationRetention.RUNTIME) -@MapKey -annotation class WorkerKey(val value: KClass) - -@Module -abstract class WorkerModule { - @Binds - @IntoMap - @WorkerKey(NotificationWorker::class) - internal abstract fun bindNotificationWorkerFactory( - worker: NotificationWorker.Factory - ): ChildWorkerFactory - - @Binds - @IntoMap - @WorkerKey(PruneCacheWorker::class) - internal abstract fun bindPruneCacheWorkerFactory( - worker: PruneCacheWorker.Factory - ): ChildWorkerFactory -} diff --git a/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.kt b/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.kt index b624a92070..a5e7b39ca8 100644 --- a/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.kt @@ -52,7 +52,6 @@ import com.keylesspalace.tusky.components.instanceinfo.InstanceInfoRepository import com.keylesspalace.tusky.components.report.ReportActivity.Companion.getIntent import com.keylesspalace.tusky.db.AccountManager import com.keylesspalace.tusky.db.entity.AccountEntity -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.entity.Attachment import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.entity.Translation @@ -74,7 +73,7 @@ import kotlinx.coroutines.launch * adapters. I feel like the profile pages and thread viewer, which I haven't made yet, will also * overlap functionality. So, I'm momentarily leaving it and hopefully working on those will clear * up what needs to be where. */ -abstract class SFragment : Fragment(), Injectable { +abstract class SFragment : Fragment() { protected abstract fun removeItem(position: Int) protected abstract fun onReblog(reblog: Boolean, position: Int) diff --git a/app/src/main/java/com/keylesspalace/tusky/fragment/ViewVideoFragment.kt b/app/src/main/java/com/keylesspalace/tusky/fragment/ViewVideoFragment.kt index 73b144072b..f0c9eafd99 100644 --- a/app/src/main/java/com/keylesspalace/tusky/fragment/ViewVideoFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/fragment/ViewVideoFragment.kt @@ -50,18 +50,19 @@ import com.keylesspalace.tusky.BuildConfig import com.keylesspalace.tusky.R import com.keylesspalace.tusky.ViewMediaActivity import com.keylesspalace.tusky.databinding.FragmentViewVideoBinding -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.entity.Attachment import com.keylesspalace.tusky.util.getParcelableCompat import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.util.visible +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import javax.inject.Provider import kotlin.math.abs +@AndroidEntryPoint @OptIn(UnstableApi::class) -class ViewVideoFragment : ViewMediaFragment(), Injectable { +class ViewVideoFragment : ViewMediaFragment() { interface VideoActionsListener { fun onDismiss() } diff --git a/app/src/main/java/com/keylesspalace/tusky/receiver/NotificationBlockStateBroadcastReceiver.kt b/app/src/main/java/com/keylesspalace/tusky/receiver/NotificationBlockStateBroadcastReceiver.kt index c481a9aa8b..9df766bb44 100644 --- a/app/src/main/java/com/keylesspalace/tusky/receiver/NotificationBlockStateBroadcastReceiver.kt +++ b/app/src/main/java/com/keylesspalace/tusky/receiver/NotificationBlockStateBroadcastReceiver.kt @@ -26,13 +26,12 @@ import com.keylesspalace.tusky.components.systemnotifications.updateUnifiedPushS import com.keylesspalace.tusky.db.AccountManager import com.keylesspalace.tusky.di.ApplicationScope import com.keylesspalace.tusky.network.MastodonApi -import dagger.android.AndroidInjection +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.launch -@DelicateCoroutinesApi +@AndroidEntryPoint class NotificationBlockStateBroadcastReceiver : BroadcastReceiver() { @Inject lateinit var mastodonApi: MastodonApi @@ -45,7 +44,6 @@ class NotificationBlockStateBroadcastReceiver : BroadcastReceiver() { lateinit var externalScope: CoroutineScope override fun onReceive(context: Context, intent: Intent) { - AndroidInjection.inject(this, context) if (Build.VERSION.SDK_INT < 28) return if (!canEnablePushNotifications(context, accountManager)) return diff --git a/app/src/main/java/com/keylesspalace/tusky/receiver/SendStatusBroadcastReceiver.kt b/app/src/main/java/com/keylesspalace/tusky/receiver/SendStatusBroadcastReceiver.kt index fcc8a76b48..16de9593db 100644 --- a/app/src/main/java/com/keylesspalace/tusky/receiver/SendStatusBroadcastReceiver.kt +++ b/app/src/main/java/com/keylesspalace/tusky/receiver/SendStatusBroadcastReceiver.kt @@ -31,11 +31,12 @@ import com.keylesspalace.tusky.service.SendStatusService import com.keylesspalace.tusky.service.StatusToSend import com.keylesspalace.tusky.util.getSerializableExtraCompat import com.keylesspalace.tusky.util.randomAlphanumericString -import dagger.android.AndroidInjection +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject private const val TAG = "SendStatusBR" +@AndroidEntryPoint class SendStatusBroadcastReceiver : BroadcastReceiver() { @Inject @@ -43,8 +44,6 @@ class SendStatusBroadcastReceiver : BroadcastReceiver() { @SuppressLint("MissingPermission") override fun onReceive(context: Context, intent: Intent) { - AndroidInjection.inject(this, context) - if (intent.action == NotificationHelper.REPLY_ACTION) { val serverNotificationId = intent.getStringExtra(NotificationHelper.KEY_SERVER_NOTIFICATION_ID) val senderId = intent.getLongExtra(NotificationHelper.KEY_SENDER_ACCOUNT_ID, -1) diff --git a/app/src/main/java/com/keylesspalace/tusky/receiver/UnifiedPushBroadcastReceiver.kt b/app/src/main/java/com/keylesspalace/tusky/receiver/UnifiedPushBroadcastReceiver.kt index 0e2a011d51..f8a7c8d3f5 100644 --- a/app/src/main/java/com/keylesspalace/tusky/receiver/UnifiedPushBroadcastReceiver.kt +++ b/app/src/main/java/com/keylesspalace/tusky/receiver/UnifiedPushBroadcastReceiver.kt @@ -16,7 +16,6 @@ package com.keylesspalace.tusky.receiver import android.content.Context -import android.content.Intent import android.util.Log import androidx.work.OneTimeWorkRequest import androidx.work.WorkManager @@ -26,14 +25,13 @@ import com.keylesspalace.tusky.db.AccountManager import com.keylesspalace.tusky.di.ApplicationScope import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.worker.NotificationWorker -import dagger.android.AndroidInjection +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.launch import org.unifiedpush.android.connector.MessagingReceiver -@DelicateCoroutinesApi +@AndroidEntryPoint class UnifiedPushBroadcastReceiver : MessagingReceiver() { companion object { const val TAG = "UnifiedPush" @@ -49,13 +47,7 @@ class UnifiedPushBroadcastReceiver : MessagingReceiver() { @ApplicationScope lateinit var externalScope: CoroutineScope - override fun onReceive(context: Context, intent: Intent) { - super.onReceive(context, intent) - AndroidInjection.inject(this, context) - } - override fun onMessage(context: Context, message: ByteArray, instance: String) { - AndroidInjection.inject(this, context) Log.d(TAG, "New message received for account $instance") val workManager = WorkManager.getInstance(context) val request = OneTimeWorkRequest.from(NotificationWorker::class.java) @@ -63,7 +55,6 @@ class UnifiedPushBroadcastReceiver : MessagingReceiver() { } override fun onNewEndpoint(context: Context, endpoint: String, instance: String) { - AndroidInjection.inject(this, context) Log.d(TAG, "Endpoint available for account $instance: $endpoint") accountManager.getAccountById(instance.toLong())?.let { externalScope.launch { @@ -75,7 +66,6 @@ class UnifiedPushBroadcastReceiver : MessagingReceiver() { override fun onRegistrationFailed(context: Context, instance: String) = Unit override fun onUnregistered(context: Context, instance: String) { - AndroidInjection.inject(this, context) Log.d(TAG, "Endpoint unregistered for account $instance") accountManager.getAccountById(instance.toLong())?.let { // It's fine if the account does not exist anymore -- that means it has been logged out diff --git a/app/src/main/java/com/keylesspalace/tusky/service/SendStatusService.kt b/app/src/main/java/com/keylesspalace/tusky/service/SendStatusService.kt index 1fe58676b8..9d77acd4da 100644 --- a/app/src/main/java/com/keylesspalace/tusky/service/SendStatusService.kt +++ b/app/src/main/java/com/keylesspalace/tusky/service/SendStatusService.kt @@ -43,7 +43,6 @@ import com.keylesspalace.tusky.components.compose.UploadEvent import com.keylesspalace.tusky.components.drafts.DraftHelper import com.keylesspalace.tusky.components.systemnotifications.NotificationHelper import com.keylesspalace.tusky.db.AccountManager -import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.entity.Attachment import com.keylesspalace.tusky.entity.MediaAttribute import com.keylesspalace.tusky.entity.NewPoll @@ -53,7 +52,7 @@ import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.getParcelableExtraCompat import com.keylesspalace.tusky.util.unsafeLazy -import dagger.android.AndroidInjection +import dagger.hilt.android.AndroidEntryPoint import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -66,7 +65,8 @@ import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import retrofit2.HttpException -class SendStatusService : Service(), Injectable { +@AndroidEntryPoint +class SendStatusService : Service() { @Inject lateinit var mastodonApi: MastodonApi @@ -93,11 +93,6 @@ class SendStatusService : Service(), Injectable { getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager } - override fun onCreate() { - AndroidInjection.inject(this) - super.onCreate() - } - override fun onBind(intent: Intent): IBinder? = null override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { diff --git a/app/src/main/java/com/keylesspalace/tusky/service/ServiceClient.kt b/app/src/main/java/com/keylesspalace/tusky/service/ServiceClient.kt index d9d08ff700..0269b66c19 100644 --- a/app/src/main/java/com/keylesspalace/tusky/service/ServiceClient.kt +++ b/app/src/main/java/com/keylesspalace/tusky/service/ServiceClient.kt @@ -17,9 +17,10 @@ package com.keylesspalace.tusky.service import android.content.Context import androidx.core.content.ContextCompat +import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject -class ServiceClient @Inject constructor(private val context: Context) { +class ServiceClient @Inject constructor(@ApplicationContext private val context: Context) { fun sendToot(tootToSend: StatusToSend) { val intent = SendStatusService.sendStatusIntent(context, tootToSend) ContextCompat.startForegroundService(context, intent) diff --git a/app/src/main/java/com/keylesspalace/tusky/usecase/LogoutUsecase.kt b/app/src/main/java/com/keylesspalace/tusky/usecase/LogoutUsecase.kt index 11f8937b59..e1556b070b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/usecase/LogoutUsecase.kt +++ b/app/src/main/java/com/keylesspalace/tusky/usecase/LogoutUsecase.kt @@ -8,10 +8,11 @@ import com.keylesspalace.tusky.db.AccountManager import com.keylesspalace.tusky.db.DatabaseCleaner import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.ShareShortcutHelper +import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject class LogoutUsecase @Inject constructor( - private val context: Context, + @ApplicationContext private val context: Context, private val api: MastodonApi, private val databaseCleaner: DatabaseCleaner, private val accountManager: AccountManager, diff --git a/app/src/main/java/com/keylesspalace/tusky/util/LocaleManager.kt b/app/src/main/java/com/keylesspalace/tusky/util/LocaleManager.kt index 8a5dc3d26e..927ab6f33e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/util/LocaleManager.kt +++ b/app/src/main/java/com/keylesspalace/tusky/util/LocaleManager.kt @@ -24,12 +24,13 @@ import androidx.preference.PreferenceDataStore import androidx.preference.PreferenceManager import com.keylesspalace.tusky.R import com.keylesspalace.tusky.settings.PrefKeys +import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject import javax.inject.Singleton @Singleton class LocaleManager @Inject constructor( - val context: Context + @ApplicationContext val context: Context ) : PreferenceDataStore() { private var prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) diff --git a/app/src/main/java/com/keylesspalace/tusky/util/ShareShortcutHelper.kt b/app/src/main/java/com/keylesspalace/tusky/util/ShareShortcutHelper.kt index d3eda1a8fb..873e970ea6 100644 --- a/app/src/main/java/com/keylesspalace/tusky/util/ShareShortcutHelper.kt +++ b/app/src/main/java/com/keylesspalace/tusky/util/ShareShortcutHelper.kt @@ -35,13 +35,14 @@ import com.keylesspalace.tusky.R import com.keylesspalace.tusky.db.AccountManager import com.keylesspalace.tusky.db.entity.AccountEntity import com.keylesspalace.tusky.di.ApplicationScope +import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch class ShareShortcutHelper @Inject constructor( - private val context: Context, + @ApplicationContext private val context: Context, private val accountManager: AccountManager, @ApplicationScope private val externalScope: CoroutineScope ) { diff --git a/app/src/main/java/com/keylesspalace/tusky/viewmodel/AccountsInListViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/viewmodel/AccountsInListViewModel.kt index 5cfb2a31e5..e62da81db4 100644 --- a/app/src/main/java/com/keylesspalace/tusky/viewmodel/AccountsInListViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/viewmodel/AccountsInListViewModel.kt @@ -27,6 +27,7 @@ import com.keylesspalace.tusky.util.Either.Companion.map import com.keylesspalace.tusky.util.Either.Left import com.keylesspalace.tusky.util.Either.Right import com.keylesspalace.tusky.util.withoutFirstWhich +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -37,6 +38,7 @@ data class State( val searchResult: List? ) +@HiltViewModel class AccountsInListViewModel @Inject constructor(private val api: MastodonApi) : ViewModel() { val state: Flow get() = _state diff --git a/app/src/main/java/com/keylesspalace/tusky/viewmodel/EditProfileViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/viewmodel/EditProfileViewModel.kt index b04f5fdf6f..bd1298c69b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/viewmodel/EditProfileViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/viewmodel/EditProfileViewModel.kt @@ -34,6 +34,7 @@ import com.keylesspalace.tusky.util.Resource import com.keylesspalace.tusky.util.Success import com.keylesspalace.tusky.util.getServerErrorMessage import com.keylesspalace.tusky.util.randomAlphanumericString +import dagger.hilt.android.lifecycle.HiltViewModel import java.io.File import javax.inject.Inject import kotlinx.coroutines.flow.Flow @@ -59,6 +60,7 @@ internal data class ProfileDataInUi( val fields: List ) +@HiltViewModel class EditProfileViewModel @Inject constructor( private val mastodonApi: MastodonApi, private val eventHub: EventHub, diff --git a/app/src/main/java/com/keylesspalace/tusky/viewmodel/ListsViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/viewmodel/ListsViewModel.kt index 4a9a6a4844..4e9144d62a 100644 --- a/app/src/main/java/com/keylesspalace/tusky/viewmodel/ListsViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/viewmodel/ListsViewModel.kt @@ -23,6 +23,7 @@ import com.keylesspalace.tusky.entity.MastoList import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.replacedFirstWhich import com.keylesspalace.tusky.util.withoutFirstWhich +import dagger.hilt.android.lifecycle.HiltViewModel import java.io.IOException import java.net.ConnectException import javax.inject.Inject @@ -35,6 +36,7 @@ import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +@HiltViewModel internal class ListsViewModel @Inject constructor(private val api: MastodonApi) : ViewModel() { enum class LoadingState { INITIAL, diff --git a/app/src/main/java/com/keylesspalace/tusky/worker/NotificationWorker.kt b/app/src/main/java/com/keylesspalace/tusky/worker/NotificationWorker.kt index 6dbe92c9ef..be249bc3aa 100644 --- a/app/src/main/java/com/keylesspalace/tusky/worker/NotificationWorker.kt +++ b/app/src/main/java/com/keylesspalace/tusky/worker/NotificationWorker.kt @@ -19,6 +19,7 @@ package com.keylesspalace.tusky.worker import android.app.Notification import android.content.Context +import androidx.hilt.work.HiltWorker import androidx.work.CoroutineWorker import androidx.work.ForegroundInfo import androidx.work.WorkerParameters @@ -26,12 +27,14 @@ import com.keylesspalace.tusky.R import com.keylesspalace.tusky.components.systemnotifications.NotificationFetcher import com.keylesspalace.tusky.components.systemnotifications.NotificationHelper import com.keylesspalace.tusky.components.systemnotifications.NotificationHelper.NOTIFICATION_ID_FETCH_NOTIFICATION -import javax.inject.Inject +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject /** Fetch and show new notifications. */ -class NotificationWorker( - appContext: Context, - params: WorkerParameters, +@HiltWorker +class NotificationWorker @AssistedInject constructor( + @Assisted appContext: Context, + @Assisted params: WorkerParameters, private val notificationsFetcher: NotificationFetcher ) : CoroutineWorker(appContext, params) { val notification: Notification = NotificationHelper.createWorkerNotification( @@ -48,12 +51,4 @@ class NotificationWorker( NOTIFICATION_ID_FETCH_NOTIFICATION, notification ) - - class Factory @Inject constructor( - private val notificationsFetcher: NotificationFetcher - ) : ChildWorkerFactory { - override fun createWorker(appContext: Context, params: WorkerParameters): CoroutineWorker { - return NotificationWorker(appContext, params, notificationsFetcher) - } - } } diff --git a/app/src/main/java/com/keylesspalace/tusky/worker/PruneCacheWorker.kt b/app/src/main/java/com/keylesspalace/tusky/worker/PruneCacheWorker.kt index 3234a7c841..b735ddca2d 100644 --- a/app/src/main/java/com/keylesspalace/tusky/worker/PruneCacheWorker.kt +++ b/app/src/main/java/com/keylesspalace/tusky/worker/PruneCacheWorker.kt @@ -20,21 +20,23 @@ package com.keylesspalace.tusky.worker import android.app.Notification import android.content.Context import android.util.Log +import androidx.hilt.work.HiltWorker import androidx.work.CoroutineWorker import androidx.work.ForegroundInfo -import androidx.work.ListenableWorker import androidx.work.WorkerParameters import com.keylesspalace.tusky.R import com.keylesspalace.tusky.components.systemnotifications.NotificationHelper import com.keylesspalace.tusky.components.systemnotifications.NotificationHelper.NOTIFICATION_ID_PRUNE_CACHE import com.keylesspalace.tusky.db.AccountManager import com.keylesspalace.tusky.db.DatabaseCleaner -import javax.inject.Inject +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject /** Prune the database cache of old statuses. */ -class PruneCacheWorker( - appContext: Context, - workerParams: WorkerParameters, +@HiltWorker +class PruneCacheWorker @AssistedInject constructor( + @Assisted appContext: Context, + @Assisted workerParams: WorkerParameters, private val databaseCleaner: DatabaseCleaner, private val accountManager: AccountManager ) : CoroutineWorker(appContext, workerParams) { @@ -62,13 +64,4 @@ class PruneCacheWorker( private const val MAX_NOTIFICATIONS_IN_CACHE = 1000 const val PERIODIC_WORK_TAG = "PruneCacheWorker_periodic" } - - class Factory @Inject constructor( - private val databaseCleaner: DatabaseCleaner, - private val accountManager: AccountManager - ) : ChildWorkerFactory { - override fun createWorker(appContext: Context, params: WorkerParameters): ListenableWorker { - return PruneCacheWorker(appContext, params, databaseCleaner, accountManager) - } - } } diff --git a/app/src/main/java/com/keylesspalace/tusky/worker/WorkerFactory.kt b/app/src/main/java/com/keylesspalace/tusky/worker/WorkerFactory.kt deleted file mode 100644 index 1d44b2ea88..0000000000 --- a/app/src/main/java/com/keylesspalace/tusky/worker/WorkerFactory.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2023 Tusky Contributors - * - * This file is a part of Tusky. - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Tusky; if not, - * see . - */ - -package com.keylesspalace.tusky.worker - -import android.content.Context -import android.util.Log -import androidx.work.ListenableWorker -import androidx.work.WorkerFactory -import androidx.work.WorkerParameters -import javax.inject.Inject -import javax.inject.Provider -import javax.inject.Singleton - -/** - * Workers implement this and are added to the map in [com.keylesspalace.tusky.di.WorkerModule] - * so they can be created by [WorkerFactory.createWorker]. - */ -interface ChildWorkerFactory { - /** Create a new instance of the given worker. */ - fun createWorker(appContext: Context, params: WorkerParameters): ListenableWorker -} - -/** - * Creates workers, delegating to each worker's [ChildWorkerFactory.createWorker] to do the - * creation. - * - * @see [com.keylesspalace.tusky.worker.NotificationWorker] - */ -@Singleton -class WorkerFactory @Inject constructor( - private val workerFactories: Map, @JvmSuppressWildcards Provider> -) : WorkerFactory() { - override fun createWorker( - appContext: Context, - workerClassName: String, - workerParameters: WorkerParameters - ): ListenableWorker? { - val key = try { - Class.forName(workerClassName) - } catch (e: ClassNotFoundException) { - // Class might be missing if it was renamed / moved to a different package, as - // periodic work requests from before the rename might still exist. Catch and - // return null, which should stop future requests. - Log.d(TAG, "Invalid class: $workerClassName", e) - null - } - workerFactories[key]?.let { - return it.get().createWorker(appContext, workerParameters) - } - return null - } - - companion object { - private const val TAG = "WorkerFactory" - } -} diff --git a/app/src/main/res/layout/activity_license.xml b/app/src/main/res/layout/activity_license.xml index 017eedb971..38e26674de 100644 --- a/app/src/main/res/layout/activity_license.xml +++ b/app/src/main/res/layout/activity_license.xml @@ -121,7 +121,7 @@ android:layout_marginStart="12dp" android:layout_marginTop="12dp" license:license="@string/license_apache_2" - license:link="https://google.github.io/dagger/" + license:link="https://dagger.dev/" license:name="Dagger 2" /> getSpans(start: Int, end: Int, type: Class): Array { return spans.filter { it.start >= start && it.end <= end && type.isInstance(it.span) } .map { it.span } diff --git a/app/src/test/java/com/keylesspalace/tusky/components/compose/ComposeActivityTest.kt b/app/src/test/java/com/keylesspalace/tusky/components/compose/ComposeActivityTest.kt index 14766496bd..654ffe82cb 100644 --- a/app/src/test/java/com/keylesspalace/tusky/components/compose/ComposeActivityTest.kt +++ b/app/src/test/java/com/keylesspalace/tusky/components/compose/ComposeActivityTest.kt @@ -20,6 +20,8 @@ package com.keylesspalace.tusky.components.compose import android.content.Intent import android.os.Looper.getMainLooper import android.widget.EditText +import androidx.lifecycle.viewmodel.initializer +import androidx.lifecycle.viewmodel.viewModelFactory import androidx.test.ext.junit.runners.AndroidJUnit4 import at.connyduck.calladapter.networkresult.NetworkResult import com.keylesspalace.tusky.R @@ -31,7 +33,6 @@ import com.keylesspalace.tusky.db.entity.AccountEntity import com.keylesspalace.tusky.db.entity.EmojisEntity import com.keylesspalace.tusky.db.entity.InstanceInfoEntity import com.keylesspalace.tusky.di.NetworkModule -import com.keylesspalace.tusky.di.ViewModelFactory import com.keylesspalace.tusky.entity.Instance import com.keylesspalace.tusky.entity.InstanceConfiguration import com.keylesspalace.tusky.entity.InstanceV1 @@ -53,7 +54,6 @@ import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.doReturn -import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.robolectric.Robolectric import org.robolectric.Shadows.shadowOf @@ -156,12 +156,12 @@ class ComposeActivityTest { putExtra(ComposeActivity.COMPOSE_OPTIONS_EXTRA, composeOptions) } - val viewModelFactoryMock: ViewModelFactory = mock { - on { create(eq(ComposeViewModel::class.java), any()) } doReturn viewModel + val testViewModelFactory = viewModelFactory { + initializer { viewModel } } activity.accountManager = accountManagerMock - activity.viewModelFactory = viewModelFactoryMock + activity.viewModelProviderFactory = testViewModelFactory controller.create().start() shadowOf(getMainLooper()).idle() diff --git a/build.gradle b/build.gradle index cf2798f38c..6fe4a064a2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,8 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.google.ksp) apply false + alias(libs.plugins.hilt.android) apply false alias(libs.plugins.kotlin.android) apply false - alias(libs.plugins.kotlin.kapt) apply false alias(libs.plugins.kotlin.parcelize) apply false alias(libs.plugins.ktlint) apply false } @@ -15,6 +15,13 @@ allprojects { toolchain.languageVersion = JavaLanguageVersion.of(21) } } + + // Required for Hilt to use the toolchain + tasks.withType(JavaCompile).configureEach { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(21) + } + } } tasks.register('clean') { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e49d01ed51..7f13c53c09 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,6 +8,7 @@ androidx-constraintlayout = "2.1.4" androidx-core = "1.13.1" androidx-exifinterface = "1.3.7" androidx-fragment = "1.7.0" +androidx-hilt = "1.2.0" androidx-junit = "1.1.5" androidx-lifecycle = "2.7.0" androidx-media3 = "1.3.1" @@ -24,7 +25,6 @@ androidx-room = "2.6.1" bouncycastle = "1.70" conscrypt = "2.5.2" coroutines = "1.8.0" -dagger = "2.51.1" diffx = "1.1.1" emoji2 = "1.4.0" espresso = "3.5.1" @@ -32,6 +32,7 @@ filemoji-compat = "3.2.7" glide = "4.16.0" # Deliberate downgrade, https://github.com/tuskyapp/Tusky/issues/3631 glide-animation-plugin = "2.23.0" +hilt = "2.51.1" kotlin = "1.9.23" image-cropper = "4.3.2" material = "1.12.0" @@ -55,8 +56,8 @@ xmlwriter = "1.0.4" [plugins] android-application = { id = "com.android.application", version.ref = "agp" } google-ksp = "com.google.devtools.ksp:1.9.23-1.0.20" +hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } -kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } ktlint = "org.jlleitschuh.gradle.ktlint:12.1.0" @@ -75,6 +76,8 @@ androidx-emoji2-views-core = { module = "androidx.emoji2:emoji2-views", version. androidx-emoji2-view-helper = { module = "androidx.emoji2:emoji2-views-helper", version.ref = "emoji2" } androidx-exifinterface = { module = "androidx.exifinterface:exifinterface", version.ref = "androidx-exifinterface" } androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "androidx-fragment" } +androidx-hilt-compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "androidx-hilt" } +androidx-hilt-work = { module = "androidx.hilt:hilt-work", version.ref = "androidx-hilt" } androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" } androidx-media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "androidx-media3" } androidx-media3-datasource-okhttp = { module = "androidx.media3:media3-datasource-okhttp", version.ref = "androidx-media3" } @@ -94,11 +97,8 @@ androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version androidx-work-testing = { module = "androidx.work:work-testing", version.ref = "androidx-work" } bouncycastle = { module = "org.bouncycastle:bcprov-jdk15on", version.ref = "bouncycastle" } conscrypt-android = { module = "org.conscrypt:conscrypt-android", version.ref = "conscrypt" } -dagger-android-core = { module = "com.google.dagger:dagger-android", version.ref = "dagger" } -dagger-android-processor = { module = "com.google.dagger:dagger-android-processor", version.ref = "dagger" } -dagger-android-support = { module = "com.google.dagger:dagger-android-support", version.ref = "dagger" } -dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" } -dagger-core = { module = "com.google.dagger:dagger", version.ref = "dagger" } +hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } +hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" } diffx = { module = "org.pageseeder.diffx:pso-diffx", version.ref = "diffx" } espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" } filemojicompat-core = { module = "de.c1710:filemojicompat", version.ref = "filemoji-compat" } @@ -141,8 +141,6 @@ androidx = ["androidx-core-ktx", "androidx-appcompat", "androidx-fragment-ktx", "androidx-constraintlayout", "androidx-paging-runtime-ktx", "androidx-viewpager2", "androidx-work-runtime-ktx", "androidx-core-splashscreen", "androidx-activity", "androidx-media3-exoplayer", "androidx-media3-datasource-okhttp", "androidx-media3-ui"] -dagger = ["dagger-core", "dagger-android-core", "dagger-android-support"] -dagger-processors = ["dagger-compiler", "dagger-android-processor"] filemojicompat = ["filemojicompat-core", "filemojicompat-ui", "filemojicompat-defaults"] glide = ["glide-core", "glide-okhttp3-integration", "glide-animation-plugin"] material-drawer = ["material-drawer-core", "material-drawer-iconics"]