diff --git a/app/build.gradle b/app/build.gradle index fbe7b8233..d53675dc4 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 d0a7fcc00..af012d301 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 0e88e0c7e..952addaab 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 c7f78d6ab..52f1dc7a4 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.Nullable; 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.adapter.AccountSelectionAdapter; 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 javax.inject.Inject; 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 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab 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 e0f6a3bc8..ab459ae09 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 02e9b1a51..426fa1c88 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 f8a2e9465..54d76ca6a 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 b7848b974..cde6a5deb 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 638f0e5be..6acabf03f 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 a06c47d95..2e41ddd6b 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 23d8450cb..2fddb882f 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 bc1dacfce..cb0cc615e 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 a8d4e6061..10bfffb5f 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 a13f3882f..53eb3cc91 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 91d6dd0ea..8716ee826 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 585c7e311..7a1cb6c87 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 b0546eceb..692aa2d38 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 49f19390a..73065b39d 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 b42a7282d..0f9077286 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 70888bbf3..b8d972c43 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 b77e05699..b0390efef 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 1ed3b3779..a12460b9c 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 1e1503c6e..3834c5d97 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 d589d85bb..59a3263e4 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 c37644cee..25d78d3af 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 5ba8f9a06..652ba1cda 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 4f32d8dc0..9c5520c3c 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 14d6ba7f8..828c8957a 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 2972293ae..f26936451 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 618174907..3a1ae69a0 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 1adfb911c..5cadce707 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 aa316c651..a07cd84bc 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 0cd378024..e68896029 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 5f83a3a32..d6668c189 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 db46ba1ff..32b36bbed 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 a10b709f6..d2d49b091 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 83c8dacf1..ad213e271 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 0acc043ae..31dedc59c 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 0f1a5a2ac..39c802039 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 e250dc989..bd235c25b 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 f3376c13b..742967243 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 05d6e9035..bd4c6965a 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 a3e65d577..c2ea86b3b 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 6c4caf8aa..7ce8cfdbb 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 547495779..ed8eb30e5 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 78362b897..361b102d5 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 fcd5a3ba4..708e44a1a 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 922d081fb..4b8eb03f6 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 c2972fa18..d1acec2b1 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 3385d079e..a0d4f3112 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 93fe05cd0..032b80ced 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 72ebbd203..7cbb97782 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 b2b84d5ae..a8960756c 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 2b5ed2628..6961caea4 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 215414ff9..87f5c1708 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 9f20265f1..416bedb87 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 89da2e12d..e8d995518 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 821364b9e..6b5b84f15 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 7cdff23fa..a36cfdd84 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 6040bac3c..5e9b57a82 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 8e1c8100f..dff440b07 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 1b0a92466..526e47cc8 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 8c4f41fb0..7bd3c9d35 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 e9d421569..9a4be2ed6 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 8e86d5e22..20b52923c 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 4eb95f2bb..b5d5840f9 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 bc3aa9d49..c3a9d7ec4 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 e2939c97b..1d6ea27ac 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 bdf2cdc79..6e205a21f 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 6b0a62af9..e746f4504 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 3237d8ead..ea8b4b092 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 70c0df191..5227fb293 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 7a074c474..7ed569538 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 394606520..7934f1cff 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 d03ed9e8d..a0f3cc1e6 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 a110c57a9..96b7ecd1b 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 a8fe4b9b6..000000000 --- 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 91045baef..000000000 --- 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 fa6fae851..000000000 --- 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 82c83e1d9..000000000 --- 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 7eef6543a..61f513f51 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 cf2d05b4a..000000000 --- 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 f3b4e8105..000000000 --- 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 b06ed2afd..b1ccfa4be 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 f12587fc5..ac5cf7bab 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 1d7510a2c..000000000 --- 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 e1b446f5d..4086aefd5 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 3fbcbe096..000000000 --- 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 a2cccf992..000000000 --- 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 b624a9207..a5e7b39ca 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 73b144072..f0c9eafd9 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 c481a9aa8..9df766bb4 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 fcc8a76b4..16de9593d 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 0e2a011d5..f8a7c8d3f 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 1fe58676b..9d77acd4d 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 d9d08ff70..0269b66c1 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 11f8937b5..e1556b070 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 8a5dc3d26..927ab6f33 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 d3eda1a8f..873e970ea 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 5cfb2a31e..e62da81db 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 b04f5fdf6..bd1298c69 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 4a9a6a484..4e9144d62 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 6dbe92c9e..be249bc3a 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 3234a7c84..b735ddca2 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 1d44b2ea8..000000000 --- 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 017eedb97..38e26674d 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 14766496b..654ffe82c 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 cf2798f38..6fe4a064a 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 e49d01ed5..7f13c53c0 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"]