From 5aca08b8bf64206acbe5b5ab07f9b293ec45a683 Mon Sep 17 00:00:00 2001 From: "yizake1820@gmail.com" Date: Mon, 29 Dec 2025 19:54:32 +0800 Subject: [PATCH 1/4] use dagger --- app/build.gradle | 5 +++ .../com/flamyoad/tsukiviewer/MainActivity.kt | 6 ++++ .../com/flamyoad/tsukiviewer/MyApplication.kt | 18 +++++++++- .../network/FetchMetadataService.kt | 4 ++- .../repository/BookmarkRepository.kt | 20 +++++------ .../repository/CollectionRepository.kt | 22 +++++------- .../repository/DoujinRepository.kt | 28 ++++++++------- .../repository/MetadataRepository.kt | 31 +++++++--------- .../repository/SearchHistoryRepository.kt | 12 ++++--- .../tsukiviewer/repository/TagRepository.kt | 12 ++++--- .../ui/doujinpage/DialogCollectionList.kt | 15 +++++++- .../ui/doujinpage/DialogRemoveMetadata.kt | 15 +++++++- .../ui/doujinpage/DialogViewStyle.kt | 15 +++++++- .../ui/doujinpage/DoujinDetailsActivity.kt | 9 ++++- .../ui/doujinpage/DoujinViewModel.kt | 10 +++--- .../ui/doujinpage/FragmentDoujinDetails.kt | 16 +++++++-- .../ui/doujinpage/FragmentGridImages.kt | 14 +++++++- .../tsukiviewer/ui/editor/EditorActivity.kt | 9 ++++- .../tsukiviewer/ui/editor/EditorViewModel.kt | 14 +++----- .../ui/editor/TagBottomSheetDialog.kt | 17 +++++++-- .../ui/home/bookmarks/BookmarkFragment.kt | 16 +++++++-- .../ui/home/bookmarks/BookmarkViewModel.kt | 7 ++-- .../home/bookmarks/DialogChangeGroupName.kt | 15 +++++++- .../ui/home/bookmarks/DialogDeleteItems.kt | 14 +++++++- .../ui/home/bookmarks/DialogNewGroup.kt | 15 +++++++- .../ui/home/collections/CollectionFragment.kt | 15 +++++++- .../home/collections/CollectionViewModel.kt | 21 +++++------ .../collections/CreateCollectionActivity.kt | 9 ++++- .../collections/CreateCollectionViewModel.kt | 18 ++++------ .../home/collections/DialogCollectionInfo.kt | 16 +++++++-- .../DialogCollectionInfoViewModel.kt | 9 ++--- .../collections/DialogCollectionViewStyle.kt | 14 +++++++- .../home/collections/DialogDirectoryPicker.kt | 14 +++++++- .../ui/home/collections/DialogTagPicker.kt | 14 +++++++- .../doujins/BookmarkGroupDialog.kt | 14 +++++++- .../doujins/CollectionDoujinsActivity.kt | 9 ++++- .../doujins/CollectionDoujinsViewModel.kt | 28 ++++++--------- .../ui/home/local/DialogNewGroup.kt | 15 +++++++- .../ui/home/local/DialogSortDoujin.kt | 14 +++++++- .../ui/home/local/LocalDoujinViewModel.kt | 9 +++-- .../ui/home/local/LocalDoujinsFragment.kt | 14 +++++++- .../ui/home/tags/DoujinTagsFragment.kt | 15 +++++++- .../ui/home/tags/DoujinTagsViewModel.kt | 14 +++----- .../tsukiviewer/ui/home/tags/TagFragment.kt | 14 +++++++- .../tsukiviewer/ui/reader/ReaderActivity.kt | 9 ++++- .../tsukiviewer/ui/reader/ReaderViewModel.kt | 13 +++---- .../ui/reader/recents/RecentTabsActivity.kt | 9 ++++- .../ui/reader/recents/RecentTabsViewModel.kt | 19 ++++------ .../ui/reader/tabs/ReaderTabFragment.kt | 35 ++++++++----------- .../ui/reader/tabs/ReaderTabViewModel.kt | 12 ++++--- .../ui/search/BookmarkGroupDialog.kt | 14 +++++++- .../tsukiviewer/ui/search/SearchActivity.kt | 9 ++++- .../ui/search/SearchResultActivity.kt | 9 ++++- .../ui/search/SearchResultViewModel.kt | 22 +++++------- .../tsukiviewer/ui/search/SearchViewModel.kt | 12 +++---- .../ui/settings/SettingsActivity.kt | 9 ++++- .../ui/settings/SettingsViewModel.kt | 30 +++++++--------- .../includedfolders/IncludedFolderActivity.kt | 9 ++++- .../IncludedFolderViewModel.kt | 19 +++------- gradlew | 0 60 files changed, 589 insertions(+), 276 deletions(-) mode change 100644 => 100755 gradlew diff --git a/app/build.gradle b/app/build.gradle index 75643ff..0641054 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -56,6 +56,7 @@ android { dependencies { def preference_version = "1.1.1" + def dagger_version = "2.48" implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" @@ -130,5 +131,9 @@ dependencies { implementation 'jp.wasabeef:recyclerview-animators:4.0.2' + // Dagger 2 + implementation "com.google.dagger:dagger:$dagger_version" + kapt "com.google.dagger:dagger-compiler:$dagger_version" + debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12' } diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/MainActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/MainActivity.kt index 6a23ae8..0afdcf8 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/MainActivity.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/MainActivity.kt @@ -17,20 +17,26 @@ import androidx.core.view.GravityCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import com.flamyoad.tsukiviewer.databinding.ActivityMainBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.ui.home.bookmarks.BookmarkFragment import com.flamyoad.tsukiviewer.ui.home.collections.CollectionFragment import com.flamyoad.tsukiviewer.ui.home.local.LocalDoujinsFragment import com.flamyoad.tsukiviewer.ui.home.tags.DoujinTagsFragment import com.flamyoad.tsukiviewer.ui.settings.SettingsActivity import com.google.android.material.navigation.NavigationView +import javax.inject.Inject class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener { private lateinit var binding: ActivityMainBinding + @Inject + lateinit var viewModelFactory: ViewModelFactory + private var callback: ActionMode.Callback? = null override fun onCreate(savedInstanceState: Bundle?) { + (application as MyApplication).appComponent.inject(this) super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/MyApplication.kt b/app/src/main/java/com/flamyoad/tsukiviewer/MyApplication.kt index 13fede1..e18b480 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/MyApplication.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/MyApplication.kt @@ -4,6 +4,9 @@ import android.app.Application import android.os.StrictMode import android.os.StrictMode.VmPolicy import com.bumptech.glide.Glide +import com.flamyoad.tsukiviewer.di.AppComponent +import com.flamyoad.tsukiviewer.di.AppModule +import com.flamyoad.tsukiviewer.di.DaggerAppComponent import com.flamyoad.tsukiviewer.model.Doujin import com.flamyoad.tsukiviewer.utils.ActivityHistory import com.jakewharton.threetenabp.AndroidThreeTen @@ -14,6 +17,9 @@ import kotlinx.coroutines.plus class MyApplication : Application() { + lateinit var appComponent: AppComponent + private set + val coroutineScope = MainScope() + CoroutineName("Application Scope") val activityStack = mutableListOf() @@ -22,6 +28,12 @@ class MyApplication : Application() { override fun onCreate() { super.onCreate() + + // Initialize Dagger + appComponent = DaggerAppComponent.builder() + .appModule(AppModule(this)) + .build() + AndroidThreeTen.init(this) /* @@ -41,4 +53,8 @@ class MyApplication : Application() { super.onTrimMemory(level) Glide.with(this).onTrimMemory(TRIM_MEMORY_MODERATE) } -} \ No newline at end of file +} + +// Extension function to get AppComponent from any Context +val Application.appComponent: AppComponent + get() = (this as MyApplication).appComponent \ No newline at end of file diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/network/FetchMetadataService.kt b/app/src/main/java/com/flamyoad/tsukiviewer/network/FetchMetadataService.kt index 69b7e08..95edf22 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/network/FetchMetadataService.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/network/FetchMetadataService.kt @@ -11,6 +11,7 @@ import androidx.core.content.ContextCompat import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.map +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.model.Source import com.flamyoad.tsukiviewer.repository.MetadataRepository @@ -65,7 +66,8 @@ class FetchMetadataService : Service() { fun initComponents(context: Context) { if (metadataRepo == null) { - metadataRepo = MetadataRepository(context) + val app = context.applicationContext as MyApplication + metadataRepo = app.appComponent.metadataRepository() } } diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/BookmarkRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/BookmarkRepository.kt index 4f5ace8..dd43306 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/BookmarkRepository.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/repository/BookmarkRepository.kt @@ -1,6 +1,5 @@ package com.flamyoad.tsukiviewer.repository -import android.content.Context import android.util.Log import androidx.lifecycle.LiveData import androidx.room.withTransaction @@ -12,22 +11,19 @@ import com.flamyoad.tsukiviewer.model.BookmarkItem import com.flamyoad.tsukiviewer.model.Doujin import org.threeten.bp.Instant import java.io.File +import javax.inject.Inject +import javax.inject.Singleton -class BookmarkRepository(private val context: Context) { +@Singleton +class BookmarkRepository @Inject constructor( + private val db: AppDatabase, + val groupDao: BookmarkGroupDao, + val itemDao: BookmarkItemDao +) { companion object { const val DEFAULT_BOOKMARK_GROUP = "Default Bookmark Group" } - private val db: AppDatabase = AppDatabase.getInstance(context) - - val groupDao: BookmarkGroupDao - val itemDao: BookmarkItemDao - - init { - groupDao = db.bookmarkGroupDao() - itemDao = db.bookmarkItemDao() - } - fun getAllItems(): LiveData> { return itemDao.selectAll() } diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/CollectionRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/CollectionRepository.kt index 564e48c..c7e8c72 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/CollectionRepository.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/repository/CollectionRepository.kt @@ -1,6 +1,5 @@ package com.flamyoad.tsukiviewer.repository -import android.content.Context import androidx.lifecycle.LiveData import androidx.room.withTransaction import com.flamyoad.tsukiviewer.db.AppDatabase @@ -10,19 +9,16 @@ import com.flamyoad.tsukiviewer.db.dao.CollectionDoujinDao import com.flamyoad.tsukiviewer.model.* import com.flamyoad.tsukiviewer.model.Collection import java.io.File - -class CollectionRepository(context: Context) { - private val db: AppDatabase = AppDatabase.getInstance(context) - - private val collectionDao: CollectionDao - private val criteriaDao: CollectionCriteriaDao +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class CollectionRepository @Inject constructor( + private val db: AppDatabase, + private val collectionDao: CollectionDao, + private val criteriaDao: CollectionCriteriaDao, private val collectionDoujinDao: CollectionDoujinDao - - init { - collectionDao = db.collectionDao() - criteriaDao = db.collectionCriteriaDao() - collectionDoujinDao = db.collectionDoujinDao() - } +) { suspend fun get(id: Long): Collection { return collectionDao.getBlocking(id) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/DoujinRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/DoujinRepository.kt index a014bbc..b8bfd79 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/DoujinRepository.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/repository/DoujinRepository.kt @@ -1,12 +1,11 @@ package com.flamyoad.tsukiviewer.repository +import android.app.Application import android.content.ContentResolver -import android.content.Context import android.provider.MediaStore import androidx.core.content.ContentResolverCompat import androidx.core.net.toUri import com.flamyoad.tsukiviewer.MyApplication -import com.flamyoad.tsukiviewer.db.AppDatabase import com.flamyoad.tsukiviewer.db.dao.DoujinDetailsDao import com.flamyoad.tsukiviewer.db.dao.IncludedPathDao import com.flamyoad.tsukiviewer.model.Doujin @@ -17,13 +16,18 @@ import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.* import java.io.File import java.util.* - -class DoujinRepository(private val context: Context) { - private val contentResolver: ContentResolver = context.contentResolver - private val db: AppDatabase = AppDatabase.getInstance(context) - private val doujinDetailsDao: DoujinDetailsDao = db.doujinDetailsDao() - private val pathDao: IncludedPathDao = db.includedFolderDao() - private val existingList = (context.applicationContext as MyApplication).fullDoujinList +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class DoujinRepository @Inject constructor( + private val application: Application, + private val doujinDetailsDao: DoujinDetailsDao, + private val pathDao: IncludedPathDao +) { + private val contentResolver: ContentResolver = application.contentResolver + private val existingList: MutableList? + get() = (application as MyApplication).fullDoujinList fun scanForDoujins(keyword: String, tags: String, shouldIncludeAllTags: Boolean) : Flow { @@ -147,12 +151,10 @@ class DoujinRepository(private val context: Context) { } private fun searchFromExistingList(keyword: String): Flow = flow { - if (existingList == null) { - return@flow - } + val list = existingList ?: return@flow val newList = mutableListOf() - for (doujin in existingList) { + for (doujin in list) { if (doujin.title.toLowerCase(Locale.ROOT).contains(keyword)) { newList.add(doujin) emit(doujin) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/MetadataRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/MetadataRepository.kt index 3139e8e..185148d 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/MetadataRepository.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/repository/MetadataRepository.kt @@ -29,22 +29,25 @@ import retrofit2.converter.gson.GsonConverterFactory import java.io.File import java.io.IOException import java.util.* - -class MetadataRepository(private val context: Context) { +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class MetadataRepository @Inject constructor( + private val context: Context, + private val db: AppDatabase, + val pathDao: IncludedPathDao, + val doujinDetailsDao: DoujinDetailsDao, + val tagDao: TagDao, + val doujinTagDao: DoujinTagsDao, + val folderDao: IncludedFolderDao +) { private lateinit var nhService: NHService private lateinit var henNexusService: HenNexusService private lateinit var fakkuService: FakkuService private val henNexusParser: HenNexusParser by lazy { HenNexusParser() } - private val db: AppDatabase - - val pathDao: IncludedPathDao - val doujinDetailsDao: DoujinDetailsDao - val tagDao: TagDao - val doujinTagDao: DoujinTagsDao - val folderDao: IncludedFolderDao - /* Regex used to remove text between parentheses and brackets Before : (C97) [Batsu Jirushi (Batsu)] AzuLan Shikoshiko Bokou Seikatsu (Azur Lane) [English] [AntaresNL667] @@ -58,14 +61,6 @@ class MetadataRepository(private val context: Context) { init { initializeNetwork() - - db = AppDatabase.getInstance(context) - - pathDao = db.includedFolderDao() - doujinDetailsDao = db.doujinDetailsDao() - tagDao = db.tagsDao() - doujinTagDao = db.doujinTagDao() - folderDao = db.folderDao() } private fun initializeNetwork() { diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/SearchHistoryRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/SearchHistoryRepository.kt index 1e043b9..abae4a5 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/SearchHistoryRepository.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/repository/SearchHistoryRepository.kt @@ -1,17 +1,19 @@ package com.flamyoad.tsukiviewer.repository -import android.content.Context import androidx.lifecycle.LiveData import androidx.paging.PagedList import androidx.paging.toLiveData -import com.flamyoad.tsukiviewer.db.AppDatabase +import com.flamyoad.tsukiviewer.db.dao.SearchHistoryDao import com.flamyoad.tsukiviewer.model.SearchHistory import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import javax.inject.Inject +import javax.inject.Singleton -class SearchHistoryRepository(private val context: Context) { - private val db: AppDatabase = AppDatabase.getInstance(context) - val searchHistoryDao = db.searchHistoryDao() +@Singleton +class SearchHistoryRepository @Inject constructor( + val searchHistoryDao: SearchHistoryDao +) { fun getAll(pageSize: Int): LiveData> { return searchHistoryDao.getAll() diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/TagRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/TagRepository.kt index a0609ca..9d684f5 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/TagRepository.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/repository/TagRepository.kt @@ -1,13 +1,15 @@ package com.flamyoad.tsukiviewer.repository -import android.content.Context import androidx.lifecycle.LiveData -import com.flamyoad.tsukiviewer.db.AppDatabase +import com.flamyoad.tsukiviewer.db.dao.TagDao import com.flamyoad.tsukiviewer.model.Tag +import javax.inject.Inject +import javax.inject.Singleton -class TagRepository(private val context: Context) { - private val db: AppDatabase = AppDatabase.getInstance(context) - private val tagDao = db.tagsDao() +@Singleton +class TagRepository @Inject constructor( + private val tagDao: TagDao +) { fun getAll(): LiveData> { return tagDao.getAll() diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogCollectionList.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogCollectionList.kt index ba702a1..a6576d1 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogCollectionList.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogCollectionList.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.doujinpage import android.app.Dialog +import android.content.Context import android.graphics.Point import android.os.Bundle import android.view.Display @@ -13,12 +14,19 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.CollectionPickerAdapter +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.BookmarkGroup +import javax.inject.Inject class DialogCollectionList: DialogFragment(), BookmarkGroupDialogListener { - private val viewModel: DoujinViewModel by activityViewModels() + + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: DoujinViewModel by activityViewModels { viewModelFactory } companion object { const val DEFAULT_COLLECTION_NAME = "Default Collection" @@ -31,6 +39,11 @@ class DialogCollectionList: DialogFragment(), BookmarkGroupDialogListener { private lateinit var btnCancel: Button private lateinit var listCollections: RecyclerView + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialogBuilder = AlertDialog.Builder(requireContext()) .setTitle("Bookmark to") diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogRemoveMetadata.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogRemoveMetadata.kt index be594a6..9a21859 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogRemoveMetadata.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogRemoveMetadata.kt @@ -1,14 +1,27 @@ package com.flamyoad.tsukiviewer.ui.doujinpage import android.app.Dialog +import android.content.Context import android.content.DialogInterface import android.os.Bundle import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment import androidx.fragment.app.activityViewModels +import com.flamyoad.tsukiviewer.MyApplication +import com.flamyoad.tsukiviewer.di.ViewModelFactory +import javax.inject.Inject class DialogRemoveMetadata : DialogFragment() { - private val viewModel: DoujinViewModel by activityViewModels() + + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: DoujinViewModel by activityViewModels { viewModelFactory } + + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val builder = AlertDialog.Builder(requireContext()) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogViewStyle.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogViewStyle.kt index e8ae56b..210e453 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogViewStyle.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DialogViewStyle.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.doujinpage import android.app.Dialog +import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.Window @@ -10,16 +11,28 @@ import androidx.core.content.ContextCompat import androidx.fragment.app.DialogFragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R +import com.flamyoad.tsukiviewer.di.ViewModelFactory +import javax.inject.Inject class DialogViewStyle : DialogFragment() { - private val viewModel: DoujinViewModel by activityViewModels() + + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: DoujinViewModel by activityViewModels { viewModelFactory } private lateinit var btnGrid: TextView private lateinit var btnScaled: TextView private lateinit var btnRow: TextView private lateinit var btnList: TextView + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val builder = AlertDialog.Builder(requireContext()) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DoujinDetailsActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DoujinDetailsActivity.kt index 53499e2..e201c03 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DoujinDetailsActivity.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DoujinDetailsActivity.kt @@ -9,22 +9,29 @@ import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Observer import androidx.viewpager.widget.ViewPager +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.DoujinPagerAdapter import com.flamyoad.tsukiviewer.adapter.LocalDoujinsAdapter import com.flamyoad.tsukiviewer.databinding.ActivityDoujinDetailsBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.ui.editor.EditorActivity import com.flamyoad.tsukiviewer.utils.ActivityStackUtils import com.flamyoad.tsukiviewer.utils.extensions.toast import com.google.android.material.snackbar.Snackbar +import javax.inject.Inject class DoujinDetailsActivity : AppCompatActivity() { private lateinit var binding: ActivityDoujinDetailsBinding - private val viewModel: DoujinViewModel by viewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: DoujinViewModel by viewModels { viewModelFactory } override fun onCreate(savedInstanceState: Bundle?) { + (application as MyApplication).appComponent.inject(this) super.onCreate(savedInstanceState) binding = ActivityDoujinDetailsBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DoujinViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DoujinViewModel.kt index 7cfc6bc..21f3552 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DoujinViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/DoujinViewModel.kt @@ -17,11 +17,13 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File import java.util.* +import javax.inject.Inject -class DoujinViewModel(application: Application) : AndroidViewModel(application) { - - private val metadataRepo = MetadataRepository(application) - private val bookmarkRepo = BookmarkRepository(application) +class DoujinViewModel @Inject constructor( + private val application: Application, + private val metadataRepo: MetadataRepository, + private val bookmarkRepo: BookmarkRepository +) : ViewModel() { private val myAppPreference = MyAppPreference.getInstance(application.applicationContext) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/FragmentDoujinDetails.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/FragmentDoujinDetails.kt index b8b3aee..d8060c4 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/FragmentDoujinDetails.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/FragmentDoujinDetails.kt @@ -1,5 +1,6 @@ package com.flamyoad.tsukiviewer.ui.doujinpage +import android.content.Context import android.graphics.Typeface import android.os.Bundle import android.text.Spannable @@ -11,9 +12,12 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import com.bumptech.glide.Glide +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.DoujinTagsAdapter import com.flamyoad.tsukiviewer.adapter.LocalDoujinsAdapter +import com.flamyoad.tsukiviewer.databinding.FragmentDoujinDetailsBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.DoujinDetails import com.flamyoad.tsukiviewer.model.DoujinDetailsWithTags import com.flamyoad.tsukiviewer.model.Source @@ -26,9 +30,9 @@ import com.flamyoad.tsukiviewer.utils.TimeUtils import com.google.android.flexbox.FlexDirection import com.google.android.flexbox.FlexWrap import com.google.android.flexbox.FlexboxLayoutManager -import com.flamyoad.tsukiviewer.databinding.FragmentDoujinDetailsBinding import java.io.File import java.util.* +import javax.inject.Inject private const val COLLECTION_DIALOG_TAG = "collection_dialog" @@ -36,7 +40,15 @@ class FragmentDoujinDetails : Fragment(), SelectSourceListener { private var _binding: FragmentDoujinDetailsBinding? = null private val binding get() = _binding!! - private val viewModel: DoujinViewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: DoujinViewModel by activityViewModels { viewModelFactory } + + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/FragmentGridImages.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/FragmentGridImages.kt index 1c45a6a..0efe78e 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/FragmentGridImages.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/FragmentGridImages.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.doujinpage import android.app.Activity +import android.content.Context import android.content.Intent import android.content.res.Configuration import android.os.Bundle @@ -11,12 +12,15 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import androidx.recyclerview.widget.GridLayoutManager import com.bumptech.glide.Glide +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.DoujinImagesAdapter import com.flamyoad.tsukiviewer.adapter.DoujinImagesAdapter.ItemType import com.flamyoad.tsukiviewer.adapter.LocalDoujinsAdapter import com.flamyoad.tsukiviewer.databinding.FragmentGridImagesBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.utils.ui.GridItemDecoration +import javax.inject.Inject const val GRID_ITEM_SPAN_PORTRAIT = 3 const val GRID_ITEM_SPAN_LANDSCAPE = 5 @@ -34,7 +38,10 @@ class FragmentGridImages : Fragment() { private var _binding: FragmentGridImagesBinding? = null private val binding get() = _binding!! - private val viewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: DoujinViewModel by activityViewModels { viewModelFactory } private var adapter: DoujinImagesAdapter? = null @@ -42,6 +49,11 @@ class FragmentGridImages : Fragment() { private var readerPosition: Int = -1 + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/EditorActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/EditorActivity.kt index 2e52adf..e11b934 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/EditorActivity.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/EditorActivity.kt @@ -7,13 +7,16 @@ import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.view.children import androidx.lifecycle.Observer +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.databinding.ActivityEditorBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.Tag import com.flamyoad.tsukiviewer.utils.extensions.toast import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.chip.Chip import com.google.android.material.chip.ChipGroup +import javax.inject.Inject private const val BACKMOST_POSITION = -1 @@ -21,9 +24,13 @@ class EditorActivity : AppCompatActivity(), CreateTagListener { private lateinit var binding: ActivityEditorBinding - private val viewModel: EditorViewModel by viewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: EditorViewModel by viewModels { viewModelFactory } override fun onCreate(savedInstanceState: Bundle?) { + (application as MyApplication).appComponent.inject(this) super.onCreate(savedInstanceState) binding = ActivityEditorBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/EditorViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/EditorViewModel.kt index e6afc45..b9d09a0 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/EditorViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/EditorViewModel.kt @@ -1,6 +1,5 @@ package com.flamyoad.tsukiviewer.ui.editor -import android.app.Application import androidx.lifecycle.* import com.flamyoad.tsukiviewer.db.dao.DoujinDetailsDao import com.flamyoad.tsukiviewer.db.dao.TagDao @@ -13,13 +12,13 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File +import javax.inject.Inject -class EditorViewModel(application: Application) : AndroidViewModel(application) { - private val metadataRepo = MetadataRepository(application) - - private val doujinDetailsDao: DoujinDetailsDao - +class EditorViewModel @Inject constructor( + private val metadataRepo: MetadataRepository, + private val doujinDetailsDao: DoujinDetailsDao, private val tagDao: TagDao +) : ViewModel() { private val undoStack = mutableListOf() @@ -44,9 +43,6 @@ class EditorViewModel(application: Application) : AndroidViewModel(application) private var currentPath: String = "" init { - doujinDetailsDao = metadataRepo.doujinDetailsDao - tagDao = metadataRepo.tagDao - tagsByCategory = selectedCategory.switchMap { category -> tagDao.getByCategory(category) } diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/TagBottomSheetDialog.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/TagBottomSheetDialog.kt index e6073d4..d87ef78 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/TagBottomSheetDialog.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/editor/TagBottomSheetDialog.kt @@ -1,19 +1,24 @@ package com.flamyoad.tsukiviewer.ui.editor +import android.content.Context import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.EditorNewTagAdapter import com.flamyoad.tsukiviewer.databinding.EditorNewTagBottomsheetBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import javax.inject.Inject class TagBottomSheetDialog() : BottomSheetDialogFragment() { @@ -21,7 +26,15 @@ class TagBottomSheetDialog() private var _binding: EditorNewTagBottomsheetBinding? = null private val binding get() = _binding!! - private lateinit var viewmodel: EditorViewModel + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewmodel: EditorViewModel by activityViewModels { viewModelFactory } + + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } override fun onCreateView( inflater: LayoutInflater, @@ -40,8 +53,6 @@ class TagBottomSheetDialog() override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewmodel = ViewModelProvider(requireActivity()).get(EditorViewModel::class.java) - viewmodel.selectedCategory().observe(viewLifecycleOwner, Observer { category -> binding.lblCategory.text = category.capitalize() }) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/BookmarkFragment.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/BookmarkFragment.kt index 71286eb..1cea9ba 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/BookmarkFragment.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/BookmarkFragment.kt @@ -1,5 +1,6 @@ package com.flamyoad.tsukiviewer.ui.home.bookmarks +import android.content.Context import android.content.DialogInterface import android.content.res.Configuration import android.os.Bundle @@ -18,15 +19,18 @@ import androidx.recyclerview.widget.LinearSnapHelper import com.flamyoad.tsukiviewer.ActionModeListener import com.flamyoad.tsukiviewer.BaseFragment import com.flamyoad.tsukiviewer.MyAppPreference +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.BookmarkGroupAdapter import com.flamyoad.tsukiviewer.adapter.BookmarkItemsAdapter +import com.flamyoad.tsukiviewer.databinding.FragmentBookmarkBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.BookmarkGroup import com.flamyoad.tsukiviewer.model.BookmarkItem import com.flamyoad.tsukiviewer.model.ViewMode import com.flamyoad.tsukiviewer.utils.ui.GridItemDecoration -import com.flamyoad.tsukiviewer.databinding.FragmentBookmarkBinding import java.util.* +import javax.inject.Inject private const val ACTION_MODE = "action_mode" private const val SEARCH_VIEW = "search_view" @@ -39,7 +43,10 @@ class BookmarkFragment : BaseFragment(), private var _binding: FragmentBookmarkBinding? = null private val binding get() = _binding!! - private val viewModel: BookmarkViewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: BookmarkViewModel by activityViewModels { viewModelFactory } private val groupAdapter = BookmarkGroupAdapter(this::onGroupChange, this::showNewGroupDialog) private val itemAdapter = BookmarkItemsAdapter(false) .apply { setHasStableIds(true) } @@ -53,6 +60,11 @@ class BookmarkFragment : BaseFragment(), private var statusBarColor: Int = -1 private var previousSearchQuery: String = "" + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) previousSearchQuery = savedInstanceState?.getString(SEARCH_VIEW) ?: "" diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/BookmarkViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/BookmarkViewModel.kt index 767fd1f..49aafe5 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/BookmarkViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/BookmarkViewModel.kt @@ -16,9 +16,12 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File import java.util.* +import javax.inject.Inject -class BookmarkViewModel(app: Application) : AndroidViewModel(app) { - private val bookmarkRepo = BookmarkRepository(app) +class BookmarkViewModel @Inject constructor( + private val app: Application, + private val bookmarkRepo: BookmarkRepository +) : ViewModel() { private val fullDoujinList: List diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogChangeGroupName.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogChangeGroupName.kt index ee7eaad..f7e5e25 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogChangeGroupName.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogChangeGroupName.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.home.bookmarks import android.app.Dialog +import android.content.Context import android.content.DialogInterface import android.os.Bundle import android.text.Editable @@ -9,12 +10,24 @@ import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout +import javax.inject.Inject class DialogChangeGroupName: DialogFragment() { - private val viewModel: BookmarkViewModel by activityViewModels() + + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: BookmarkViewModel by activityViewModels { viewModelFactory } + + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val oldName = requireArguments().getString(COLLECTION_NAME) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogDeleteItems.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogDeleteItems.kt index 2b22b52..65ea29e 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogDeleteItems.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogDeleteItems.kt @@ -8,9 +8,21 @@ import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import com.flamyoad.tsukiviewer.MyApplication +import com.flamyoad.tsukiviewer.di.ViewModelFactory +import javax.inject.Inject class DialogDeleteItems(): DialogFragment() { - private val viewModel: BookmarkViewModel by activityViewModels() + + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: BookmarkViewModel by activityViewModels { viewModelFactory } + + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val listener = parentFragment as DeleteItemsListener diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogNewGroup.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogNewGroup.kt index 81d025b..214abe6 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogNewGroup.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/bookmarks/DialogNewGroup.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.home.bookmarks import android.app.Dialog +import android.content.Context import android.content.DialogInterface import android.os.Bundle import android.text.Editable @@ -9,12 +10,24 @@ import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout +import javax.inject.Inject class DialogNewGroup: DialogFragment() { - private val viewModel: BookmarkViewModel by activityViewModels() + + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: BookmarkViewModel by activityViewModels { viewModelFactory } + + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val builder = AlertDialog.Builder(requireContext()) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CollectionFragment.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CollectionFragment.kt index 6f853a8..cddf127 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CollectionFragment.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CollectionFragment.kt @@ -1,5 +1,6 @@ package com.flamyoad.tsukiviewer.ui.home.collections +import android.content.Context import android.content.DialogInterface import android.content.Intent import android.content.res.Configuration @@ -12,13 +13,20 @@ import androidx.lifecycle.Observer import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import com.flamyoad.tsukiviewer.BaseFragment +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.CollectionListAdapter import com.flamyoad.tsukiviewer.databinding.FragmentCollectionBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.Collection +import javax.inject.Inject class CollectionFragment : BaseFragment(), SearchView.OnQueryTextListener { - private val viewModel: CollectionViewModel by activityViewModels() + + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: CollectionViewModel by activityViewModels { viewModelFactory } private var _binding: FragmentCollectionBinding? = null private val binding get() = _binding!! @@ -26,6 +34,11 @@ class CollectionFragment : BaseFragment(), SearchView.OnQueryTextListener { private var searchView: SearchView? = null private var previousSearchQuery: String = "" + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CollectionViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CollectionViewModel.kt index 0cf064a..a54e725 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CollectionViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CollectionViewModel.kt @@ -9,7 +9,6 @@ import androidx.core.net.toFile import androidx.lifecycle.* import com.flamyoad.tsukiviewer.MyAppPreference import com.flamyoad.tsukiviewer.MyApplication -import com.flamyoad.tsukiviewer.db.AppDatabase import com.flamyoad.tsukiviewer.db.dao.IncludedPathDao import com.flamyoad.tsukiviewer.model.* import com.flamyoad.tsukiviewer.model.Collection @@ -21,14 +20,15 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.launch import java.io.File import java.util.* +import javax.inject.Inject -class CollectionViewModel(private val app: Application) : AndroidViewModel(app) { - private val db: AppDatabase - private val pathDao: IncludedPathDao - private val contentResolver: ContentResolver = app.contentResolver - private val myAppPreference = MyAppPreference.getInstance(app.applicationContext) - +class CollectionViewModel @Inject constructor( + private val application: Application, + private val pathDao: IncludedPathDao, private val collectionRepo: CollectionRepository +) : ViewModel() { + private val contentResolver: ContentResolver = application.contentResolver + private val myAppPreference = MyAppPreference.getInstance(application.applicationContext) private var initThumbnailJob: Job? = null @@ -40,13 +40,8 @@ class CollectionViewModel(private val app: Application) : AndroidViewModel(app) val collectionWithCriterias: LiveData> init { - db = AppDatabase.getInstance(app.applicationContext) - pathDao = db.includedFolderDao() - collectionViewStyle.value = myAppPreference.getCollectionViewStyle() - collectionRepo = CollectionRepository(app.applicationContext) - collectionWithCriterias = searchQuery.switchMap { query -> collectionRepo.getAllWithCriterias(query) } @@ -111,7 +106,7 @@ class CollectionViewModel(private val app: Application) : AndroidViewModel(app) // If tags are not specified in the query, then we have to search from file explorer too if (includedTags.isEmpty() && excludedTags.isEmpty()) { - val existingList = (app as MyApplication).fullDoujinList + val existingList = (application as MyApplication).fullDoujinList if (existingList != null) { thumbnail = getThumbnailFromExistingList(existingList.toList(), collectionSearchInput) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CreateCollectionActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CreateCollectionActivity.kt index 3fc2317..a93a3ab 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CreateCollectionActivity.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CreateCollectionActivity.kt @@ -11,15 +11,18 @@ import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.DialogFragment import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.CollectionFilterDirectoryAdapter import com.flamyoad.tsukiviewer.databinding.ActivityCreateCollectionBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.Collection import com.flamyoad.tsukiviewer.model.Tag import com.flamyoad.tsukiviewer.ui.search.TagSelectedListener import com.flamyoad.tsukiviewer.utils.extensions.toast import com.google.android.material.chip.Chip import java.io.File +import javax.inject.Inject private const val REQUEST_DIR_PICKER = 101 @@ -27,11 +30,15 @@ class CreateCollectionActivity : AppCompatActivity(), TagSelectedListener { private lateinit var binding: ActivityCreateCollectionBinding - private val viewModel: CreateCollectionViewModel by viewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: CreateCollectionViewModel by viewModels { viewModelFactory } private lateinit var dirAdapter: CollectionFilterDirectoryAdapter override fun onCreate(savedInstanceState: Bundle?) { + (application as MyApplication).appComponent.inject(this) super.onCreate(savedInstanceState) binding = ActivityCreateCollectionBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CreateCollectionViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CreateCollectionViewModel.kt index ae72f0c..8d4d3fc 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CreateCollectionViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/CreateCollectionViewModel.kt @@ -1,8 +1,6 @@ package com.flamyoad.tsukiviewer.ui.home.collections -import android.app.Application import androidx.lifecycle.* -import com.flamyoad.tsukiviewer.db.AppDatabase import com.flamyoad.tsukiviewer.db.dao.IncludedPathDao import com.flamyoad.tsukiviewer.model.* import com.flamyoad.tsukiviewer.model.Collection @@ -12,16 +10,15 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File +import javax.inject.Inject -class CreateCollectionViewModel(application: Application) : AndroidViewModel(application) { - private val db: AppDatabase = AppDatabase.getInstance(application.applicationContext) - - private val tagRepo = TagRepository(application.applicationContext) - private val collectionRepo = CollectionRepository(application.applicationContext) - +class CreateCollectionViewModel @Inject constructor( + private val tagRepo: TagRepository, + private val collectionRepo: CollectionRepository, private val includedPathDao: IncludedPathDao +) : ViewModel() { - val includedPaths: LiveData> + val includedPaths: LiveData> = includedPathDao.getAll() private val tagQuery = MutableLiveData("") @@ -54,9 +51,6 @@ class CreateCollectionViewModel(application: Application) : AndroidViewModel(app var tagPickerMode = DialogTagPicker.Mode.None init { - includedPathDao = db.includedFolderDao() - includedPaths = includedPathDao.getAll() - tagList = tagQuery.switchMap { tagRepo.getAllWithFilter(it) } diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionInfo.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionInfo.kt index 48a7a34..5873585 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionInfo.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionInfo.kt @@ -1,5 +1,6 @@ package com.flamyoad.tsukiviewer.ui.home.collections +import android.content.Context import android.graphics.Point import android.os.Bundle import android.view.* @@ -9,24 +10,35 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.CollectionInfoDirectoryAdapter import com.flamyoad.tsukiviewer.adapter.CollectionInfoTagAdapter +import com.flamyoad.tsukiviewer.databinding.DialogCollectionInfoBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.google.android.flexbox.FlexDirection import com.google.android.flexbox.FlexWrap import com.google.android.flexbox.FlexboxLayoutManager -import com.flamyoad.tsukiviewer.databinding.DialogCollectionInfoBinding +import javax.inject.Inject class DialogCollectionInfo : DialogFragment() { private var _binding: DialogCollectionInfoBinding? = null private val binding get() = _binding!! - private val viewModel: DialogCollectionInfoViewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: DialogCollectionInfoViewModel by activityViewModels { viewModelFactory } private val includedTagsAdapter = CollectionInfoTagAdapter(DialogTagPicker.Mode.Inclusive) private val excludedTagsAdapter = CollectionInfoTagAdapter(DialogTagPicker.Mode.Exclusive) private val dirAdapter = CollectionInfoDirectoryAdapter() + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionInfoViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionInfoViewModel.kt index 1a8c83f..0e9a5db 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionInfoViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionInfoViewModel.kt @@ -1,9 +1,8 @@ package com.flamyoad.tsukiviewer.ui.home.collections -import android.app.Application -import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.flamyoad.tsukiviewer.model.Collection import com.flamyoad.tsukiviewer.model.Tag @@ -11,9 +10,11 @@ import com.flamyoad.tsukiviewer.repository.CollectionRepository import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.File +import javax.inject.Inject -class DialogCollectionInfoViewModel(application: Application) : AndroidViewModel(application) { - private val collectionRepo = CollectionRepository(application.applicationContext) +class DialogCollectionInfoViewModel @Inject constructor( + private val collectionRepo: CollectionRepository +) : ViewModel() { private val currentCollection = MutableLiveData() fun currentCollection(): LiveData = currentCollection diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionViewStyle.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionViewStyle.kt index d1886f8..6aeafd9 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionViewStyle.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogCollectionViewStyle.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.home.collections import android.app.Dialog +import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.Window @@ -10,15 +11,26 @@ import androidx.core.content.ContextCompat import androidx.fragment.app.DialogFragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.CollectionListAdapter +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.ui.doujinpage.GridViewStyle +import javax.inject.Inject class DialogCollectionViewStyle: DialogFragment() { private lateinit var btnGrid: TextView private lateinit var btnList: TextView - private val viewModel: CollectionViewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: CollectionViewModel by activityViewModels { viewModelFactory } + + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val builder = AlertDialog.Builder(requireContext()) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogDirectoryPicker.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogDirectoryPicker.kt index eb1e3ac..323be8f 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogDirectoryPicker.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogDirectoryPicker.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.home.collections import android.app.Dialog +import android.content.Context import android.graphics.Point import android.os.Bundle import android.view.Display @@ -13,16 +14,27 @@ import androidx.lifecycle.Observer import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.DirectoryPickerAdapter +import com.flamyoad.tsukiviewer.di.ViewModelFactory import java.io.File +import javax.inject.Inject class DialogDirectoryPicker: DialogFragment() { - private val viewModel: CreateCollectionViewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: CreateCollectionViewModel by activityViewModels { viewModelFactory } private lateinit var listDirs: RecyclerView + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val builder = AlertDialog.Builder(requireContext()) builder.setTitle("Pick a directory") diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogTagPicker.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogTagPicker.kt index bd6e090..8f4b284 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogTagPicker.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/DialogTagPicker.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.home.collections import android.app.Dialog +import android.content.Context import android.content.DialogInterface import android.os.Bundle import android.text.Editable @@ -12,9 +13,12 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.TagPickerAdapter +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.ui.search.TagSelectedListener +import javax.inject.Inject class DialogTagPicker: DialogFragment() { enum class Mode { @@ -23,10 +27,18 @@ class DialogTagPicker: DialogFragment() { None } - private val viewModel: CreateCollectionViewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: CreateCollectionViewModel by activityViewModels { viewModelFactory } private lateinit var listTags: RecyclerView private lateinit var fieldTag: EditText + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putString(SEARCH_QUERY, fieldTag.text.toString()) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/BookmarkGroupDialog.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/BookmarkGroupDialog.kt index 1d7b6b3..e391cfd 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/BookmarkGroupDialog.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/BookmarkGroupDialog.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.home.collections.doujins import android.app.Dialog +import android.content.Context import android.graphics.Point import android.os.Bundle import android.view.Display @@ -13,12 +14,15 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.CollectionPickerAdapter +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.BookmarkGroup import com.flamyoad.tsukiviewer.ui.doujinpage.BookmarkGroupDialogListener import com.flamyoad.tsukiviewer.ui.doujinpage.DialogCollectionList import com.flamyoad.tsukiviewer.ui.doujinpage.DialogNewCollection +import javax.inject.Inject class BookmarkGroupDialog : DialogFragment(), BookmarkGroupDialogListener { @@ -26,7 +30,10 @@ class BookmarkGroupDialog : DialogFragment(), BookmarkGroupDialogListener { fun newInstance() = BookmarkGroupDialog() } - private val viewModel: CollectionDoujinsViewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: CollectionDoujinsViewModel by activityViewModels { viewModelFactory } private val collectionAdapter: CollectionPickerAdapter = CollectionPickerAdapter(this) @@ -34,6 +41,11 @@ class BookmarkGroupDialog : DialogFragment(), BookmarkGroupDialogListener { private lateinit var btnCancel: Button private lateinit var listCollections: RecyclerView + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialogBuilder = AlertDialog.Builder(requireContext()) .setTitle("Bookmark to") diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/CollectionDoujinsActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/CollectionDoujinsActivity.kt index e169405..c92ce1d 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/CollectionDoujinsActivity.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/CollectionDoujinsActivity.kt @@ -18,9 +18,11 @@ import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import com.flamyoad.tsukiviewer.ActionModeListener import com.flamyoad.tsukiviewer.MyAppPreference +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.LocalDoujinsAdapter import com.flamyoad.tsukiviewer.databinding.ActivityCollectionDoujinsBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.Doujin import com.flamyoad.tsukiviewer.model.ViewMode import com.flamyoad.tsukiviewer.ui.editor.EditorActivity @@ -31,6 +33,7 @@ import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch +import javax.inject.Inject private const val ACTION_MODE = "action_mode" private const val ADD_BOOKMARK_DIALOG = "add_bookmark_dialog" @@ -42,7 +45,10 @@ class CollectionDoujinsActivity : AppCompatActivity(), private lateinit var binding: ActivityCollectionDoujinsBinding - private val viewModel: CollectionDoujinsViewModel by viewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: CollectionDoujinsViewModel by viewModels { viewModelFactory } private val adapter = LocalDoujinsAdapter(this).apply { setHasStableIds(true) @@ -59,6 +65,7 @@ class CollectionDoujinsActivity : AppCompatActivity(), private var queryJob: Job? = null override fun onCreate(savedInstanceState: Bundle?) { + (application as MyApplication).appComponent.inject(this) super.onCreate(savedInstanceState) binding = ActivityCollectionDoujinsBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/CollectionDoujinsViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/CollectionDoujinsViewModel.kt index 545e884..6e470f6 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/CollectionDoujinsViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/collections/doujins/CollectionDoujinsViewModel.kt @@ -2,17 +2,15 @@ package com.flamyoad.tsukiviewer.ui.home.collections.doujins import android.app.Application import android.content.ContentResolver -import android.content.Context import android.provider.MediaStore import android.util.Log import androidx.core.content.ContentResolverCompat import androidx.core.net.toUri -import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.flamyoad.tsukiviewer.MyApplication -import com.flamyoad.tsukiviewer.db.AppDatabase import com.flamyoad.tsukiviewer.db.dao.DoujinDetailsDao import com.flamyoad.tsukiviewer.db.dao.IncludedPathDao import com.flamyoad.tsukiviewer.model.BookmarkGroup @@ -28,17 +26,16 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File import java.util.* +import javax.inject.Inject -class CollectionDoujinsViewModel(private val app: Application) : AndroidViewModel(app) { - private val context: Context = app.applicationContext - private val contentResolver: ContentResolver = app.contentResolver - - private val db: AppDatabase = AppDatabase.getInstance(app) - private val doujinDetailsDao: DoujinDetailsDao - private val pathDao: IncludedPathDao - - private val bookmarkRepo = BookmarkRepository(app) - private val collectionRepo = CollectionRepository(app) +class CollectionDoujinsViewModel @Inject constructor( + private val application: Application, + private val doujinDetailsDao: DoujinDetailsDao, + private val pathDao: IncludedPathDao, + private val bookmarkRepo: BookmarkRepository, + private val collectionRepo: CollectionRepository +) : ViewModel() { + private val contentResolver: ContentResolver = application.contentResolver private val doujinList = mutableListOf() @@ -73,9 +70,6 @@ class CollectionDoujinsViewModel(private val app: Application) : AndroidViewMode val bookmarkGroupTickStatus = hashMapOf() init { - pathDao = db.includedFolderDao() - doujinDetailsDao = db.doujinDetailsDao() - viewModelScope.launch(Dispatchers.IO) { bookmarkGroupList.postValue(bookmarkRepo.getAllGroupsBlocking()) } @@ -102,7 +96,7 @@ class CollectionDoujinsViewModel(private val app: Application) : AndroidViewMode // If tags are not specified in the query, then we have to search from file explorer too if (includedTags.isEmpty() && excludedTags.isEmpty()) { - val existingList = (app as MyApplication).fullDoujinList + val existingList = (application as MyApplication).fullDoujinList if (existingList != null) { searchFromExistingList(existingList.toList()) } else { diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogNewGroup.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogNewGroup.kt index ed8cfd4..025415a 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogNewGroup.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogNewGroup.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.home.local import android.app.Dialog +import android.content.Context import android.content.DialogInterface import android.os.Bundle import android.text.Editable @@ -9,13 +10,25 @@ import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.ui.home.bookmarks.BookmarkViewModel import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout +import javax.inject.Inject class DialogNewGroup: DialogFragment() { - private val viewModel: LocalDoujinViewModel by activityViewModels() + + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: LocalDoujinViewModel by activityViewModels { viewModelFactory } + + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val builder = AlertDialog.Builder(requireContext()) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogSortDoujin.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogSortDoujin.kt index 00c0615..dcdb9d9 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogSortDoujin.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogSortDoujin.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.home.local import android.app.Dialog +import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.Window @@ -10,11 +11,22 @@ import androidx.core.content.ContextCompat import androidx.fragment.app.DialogFragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R +import com.flamyoad.tsukiviewer.di.ViewModelFactory +import javax.inject.Inject class DialogSortDoujin : DialogFragment() { - private val viewModel: LocalDoujinViewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: LocalDoujinViewModel by activityViewModels { viewModelFactory } + + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val builder = AlertDialog.Builder(requireContext()) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/LocalDoujinViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/LocalDoujinViewModel.kt index 4f693b6..72390c1 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/LocalDoujinViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/LocalDoujinViewModel.kt @@ -21,10 +21,13 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File import java.util.* +import javax.inject.Inject -class LocalDoujinViewModel(private val app: Application) : AndroidViewModel(app) { - private val metadataRepo = MetadataRepository(app) - private val bookmarkRepo = BookmarkRepository(app) +class LocalDoujinViewModel @Inject constructor( + private val app: Application, + private val metadataRepo: MetadataRepository, + private val bookmarkRepo: BookmarkRepository +) : ViewModel() { private val selectedDoujins = mutableListOf() diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/LocalDoujinsFragment.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/LocalDoujinsFragment.kt index fded117..90ef38d 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/LocalDoujinsFragment.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/LocalDoujinsFragment.kt @@ -1,5 +1,6 @@ package com.flamyoad.tsukiviewer.ui.home.local +import android.content.Context import android.content.Intent import android.content.res.Configuration import android.os.Bundle @@ -17,9 +18,11 @@ import androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy import com.flamyoad.tsukiviewer.ActionModeListener import com.flamyoad.tsukiviewer.BaseFragment import com.flamyoad.tsukiviewer.MyAppPreference +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.LocalDoujinsAdapter import com.flamyoad.tsukiviewer.databinding.FragmentLocalDoujinsBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.Doujin import com.flamyoad.tsukiviewer.model.Source import com.flamyoad.tsukiviewer.model.ViewMode @@ -33,6 +36,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.launch import java.io.File import java.util.* +import javax.inject.Inject private const val ACTION_MODE = "action_mode" private const val ADD_BOOKMARK_DIALOG = "add_bookmark_dialog" @@ -43,7 +47,10 @@ class LocalDoujinsFragment : BaseFragment(), LocalDoujinsContextualListener, SelectSourceListener { - private val viewModel: LocalDoujinViewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: LocalDoujinViewModel by activityViewModels { viewModelFactory } private var _binding: FragmentLocalDoujinsBinding? = null private val binding get() = _binding!! @@ -61,6 +68,11 @@ class LocalDoujinsFragment : BaseFragment(), private lateinit var progressBar: ProgressBar private lateinit var toast: Toast + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DoujinTagsFragment.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DoujinTagsFragment.kt index 7643276..f7bdf40 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DoujinTagsFragment.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DoujinTagsFragment.kt @@ -1,22 +1,30 @@ package com.flamyoad.tsukiviewer.ui.home.tags +import android.content.Context import android.os.Bundle import android.view.* import androidx.appcompat.widget.SearchView import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import com.flamyoad.tsukiviewer.BaseFragment +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.databinding.FragmentDoujinTagsBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.TagType import com.flamyoad.tsukiviewer.utils.extensions.reduceDragSensitivity import com.google.android.material.tabs.TabLayoutMediator +import javax.inject.Inject private const val SEARCH_VIEW = "search_view" class DoujinTagsFragment : BaseFragment(), SearchView.OnQueryTextListener { - private val viewModel by activityViewModels() + + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: DoujinTagsViewModel by activityViewModels { viewModelFactory } private var _binding: FragmentDoujinTagsBinding? = null private val binding get() = _binding!! @@ -36,6 +44,11 @@ class DoujinTagsFragment : BaseFragment(), SearchView.OnQueryTextListener { TagType.Categories ) + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DoujinTagsViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DoujinTagsViewModel.kt index fc4516d..2a41fac 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DoujinTagsViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DoujinTagsViewModel.kt @@ -1,8 +1,6 @@ package com.flamyoad.tsukiviewer.ui.home.tags -import android.app.Application import androidx.lifecycle.* -import com.flamyoad.tsukiviewer.db.AppDatabase import com.flamyoad.tsukiviewer.db.dao.DoujinTagsDao import com.flamyoad.tsukiviewer.db.dao.TagDao import com.flamyoad.tsukiviewer.model.Tag @@ -10,13 +8,12 @@ import com.flamyoad.tsukiviewer.model.TagSortingMode import com.flamyoad.tsukiviewer.model.TagType import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import javax.inject.Inject -class DoujinTagsViewModel(application: Application) : AndroidViewModel(application) { - - private val db: AppDatabase = AppDatabase.getInstance(application) - - private val tagDao: TagDao +class DoujinTagsViewModel @Inject constructor( + private val tagDao: TagDao, private val doujinTagDao: DoujinTagsDao +) : ViewModel() { // First object in the Pair : Keyword of the search // Second object in the Pair: The sorting mode (e.g. Sort by number of items ascending) @@ -34,9 +31,6 @@ class DoujinTagsViewModel(application: Application) : AndroidViewModel(applicati private val categories: LiveData> init { - tagDao = db.tagsDao() - doujinTagDao = db.doujinTagDao() - searchTerms.value = Pair("", TagSortingMode.NAME_ASCENDING) allTags = searchTerms.switchMap { searchTerm -> diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/TagFragment.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/TagFragment.kt index 182f941..8a582ea 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/TagFragment.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/TagFragment.kt @@ -1,5 +1,6 @@ package com.flamyoad.tsukiviewer.ui.home.tags +import android.content.Context import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater @@ -10,9 +11,11 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.DoujinTagsAdapter import com.flamyoad.tsukiviewer.databinding.FragmentTagBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.Doujin import com.flamyoad.tsukiviewer.model.Tag import com.flamyoad.tsukiviewer.model.TagType @@ -20,18 +23,27 @@ import com.google.android.flexbox.FlexDirection import com.google.android.flexbox.FlexWrap import com.google.android.flexbox.FlexboxItemDecoration import com.google.android.flexbox.FlexboxLayoutManager +import javax.inject.Inject private const val TAG_NAME = "tag_name" class TagFragment : Fragment() { - private val viewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: DoujinTagsViewModel by activityViewModels { viewModelFactory } private var _binding: FragmentTagBinding? = null private val binding get() = _binding!! private val adapter = DoujinTagsAdapter(true) + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) adapter.setListener(this::showDeleteDialog) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/ReaderActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/ReaderActivity.kt index 0c43243..cead36d 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/ReaderActivity.kt @@ -13,15 +13,18 @@ import androidx.lifecycle.Observer import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.DoujinImagesAdapter import com.flamyoad.tsukiviewer.databinding.ActivityReaderBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.RecentTab import com.flamyoad.tsukiviewer.ui.reader.recents.RecentTabsActivity import com.flamyoad.tsukiviewer.ui.reader.tabs.ReaderTabFragmentAdapter import com.flamyoad.tsukiviewer.ui.reader.tabs.ReaderTabListener import com.flamyoad.tsukiviewer.utils.extensions.reduceDragSensitivitySlightly import com.flamyoad.tsukiviewer.utils.extensions.toast +import javax.inject.Inject const val MY_KEY_DOWN_INTENT = "my_key_down_intent" @@ -31,7 +34,10 @@ class ReaderActivity : AppCompatActivity(), ViewPagerListener, ReaderTabListener private lateinit var binding: ActivityReaderBinding - private val viewModel: ReaderViewModel by viewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: ReaderViewModel by viewModels { viewModelFactory } private var positionFromImageGrid = 0 @@ -44,6 +50,7 @@ class ReaderActivity : AppCompatActivity(), ViewPagerListener, ReaderTabListener private lateinit var tabFragmentAdapter: ReaderTabFragmentAdapter override fun onCreate(savedInstanceState: Bundle?) { + (application as MyApplication).appComponent.inject(this) super.onCreate(savedInstanceState) binding = ActivityReaderBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/ReaderViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/ReaderViewModel.kt index d70149c..3966978 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/ReaderViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/ReaderViewModel.kt @@ -4,7 +4,7 @@ import android.app.Application import androidx.core.net.toUri import androidx.lifecycle.* import com.flamyoad.tsukiviewer.MyAppPreference -import com.flamyoad.tsukiviewer.db.AppDatabase +import com.flamyoad.tsukiviewer.db.dao.RecentTabDao import com.flamyoad.tsukiviewer.model.RecentTab import com.flamyoad.tsukiviewer.utils.FileUtils import com.flamyoad.tsukiviewer.utils.extensions.imageExtensions @@ -12,17 +12,18 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File +import javax.inject.Inject -class ReaderViewModel(application: Application) : AndroidViewModel(application) { +class ReaderViewModel @Inject constructor( + private val application: Application, + private val recentTabDao: RecentTabDao +) : ViewModel() { private val appPreference = MyAppPreference.getInstance(application.applicationContext) private val directoryNoLongerExists = MutableLiveData(false) fun directoryNoLongerExists(): LiveData = directoryNoLongerExists - private val db = AppDatabase.getInstance(application) - private val recentTabDao = db.recentTabDao() - var lastReadImagePosition: Int = 0 private val readerMode = MutableLiveData() @@ -34,7 +35,7 @@ class ReaderViewModel(application: Application) : AndroidViewModel(application) val recentTabs: LiveData> init { - recentTabs = db.recentTabDao().getAll() + recentTabs = recentTabDao.getAll() val defaultReaderMode = appPreference.getDefaultReaderMode() readerMode.value = defaultReaderMode } diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/recents/RecentTabsActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/recents/RecentTabsActivity.kt index 791318c..5c708b3 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/recents/RecentTabsActivity.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/recents/RecentTabsActivity.kt @@ -9,25 +9,32 @@ import androidx.lifecycle.Observer import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.RecentTabsAdapter import com.flamyoad.tsukiviewer.databinding.ActivityRecentTabsBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.RecentTab import com.flamyoad.tsukiviewer.ui.reader.tabs.ReaderTabFragment import com.flamyoad.tsukiviewer.utils.extensions.toast import jp.wasabeef.recyclerview.animators.SlideInUpAnimator +import javax.inject.Inject class RecentTabsActivity : AppCompatActivity() { private lateinit var binding: ActivityRecentTabsBinding - private val viewModel: RecentTabsViewModel by viewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: RecentTabsViewModel by viewModels { viewModelFactory } private var touchHelper: ItemTouchHelper? = null private var linearLayoutManager: LinearLayoutManager? = null override fun onCreate(savedInstanceState: Bundle?) { + (application as MyApplication).appComponent.inject(this) super.onCreate(savedInstanceState) binding = ActivityRecentTabsBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/recents/RecentTabsViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/recents/RecentTabsViewModel.kt index f4dd7eb..04be759 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/recents/RecentTabsViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/recents/RecentTabsViewModel.kt @@ -3,30 +3,25 @@ package com.flamyoad.tsukiviewer.ui.reader.recents import android.app.Application import androidx.lifecycle.* import com.flamyoad.tsukiviewer.MyApplication -import com.flamyoad.tsukiviewer.db.AppDatabase import com.flamyoad.tsukiviewer.db.dao.RecentTabDao import com.flamyoad.tsukiviewer.model.RecentTab import kotlinx.coroutines.* +import javax.inject.Inject -class RecentTabsViewModel(application: Application) : AndroidViewModel(application) { +class RecentTabsViewModel @Inject constructor( + private val application: Application, + private val recentTabDao: RecentTabDao +) : ViewModel() { - private val applicationScope: CoroutineScope - - private val db = AppDatabase.getInstance(application) - private val recentTabDao: RecentTabDao = db.recentTabDao() + private val applicationScope: CoroutineScope = (application as MyApplication).coroutineScope val toast = MutableLiveData("") fun toast(): LiveData = toast - val tabList: LiveData> + val tabList: LiveData> = recentTabDao.getAll() var hasScrolledList: Boolean = false - init { - tabList = recentTabDao.getAll() - applicationScope = (application as MyApplication).coroutineScope - } - fun removeRecentTab(tab: RecentTab) { viewModelScope.launch(Dispatchers.IO) { recentTabDao.delete(tab) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/tabs/ReaderTabFragment.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/tabs/ReaderTabFragment.kt index bbe6598..688f38e 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/tabs/ReaderTabFragment.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/tabs/ReaderTabFragment.kt @@ -15,15 +15,18 @@ import androidx.recyclerview.widget.LinearSnapHelper import androidx.recyclerview.widget.RecyclerView import androidx.transition.Slide import androidx.transition.TransitionManager +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.BottomThumbnailAdapter import com.flamyoad.tsukiviewer.databinding.FragmentReaderTabBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.RecentTab import com.flamyoad.tsukiviewer.ui.reader.* import com.flamyoad.tsukiviewer.ui.reader.ReaderActivity.Companion.RECENT_TAB_REQUEST_CODE import com.flamyoad.tsukiviewer.ui.reader.recents.RecentTabsActivity import com.flamyoad.tsukiviewer.utils.extensions.toast import java.io.File +import javax.inject.Inject private const val SWIPE_READER = "swipe_reader" @@ -34,8 +37,11 @@ class ReaderTabFragment : Fragment(), private var _binding: FragmentReaderTabBinding? = null private val binding get() = _binding!! - private val viewModel: ReaderTabViewModel by viewModels() - private val parentViewModel: ReaderViewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: ReaderTabViewModel by viewModels { viewModelFactory } + private val parentViewModel: ReaderViewModel by activityViewModels { viewModelFactory } private var viewPagerListener: ViewPagerListener? = null private var readerListener: ReaderTabListener? = null @@ -43,32 +49,19 @@ class ReaderTabFragment : Fragment(), private var shouldReturnLastReadPosition: Boolean = false private var isFirstLoad: Boolean = true - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - shouldReturnLastReadPosition = arguments?.getBoolean(RETURN_LAST_READ_POSITION) ?: false - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - _binding = FragmentReaderTabBinding.inflate(inflater, container, false) - return binding.root - } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onAttach(context: Context) { super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) viewPagerListener = context as ViewPagerListener readerListener = context as ReaderTabListener lastReadPageNumberListener = context as LastReadPageNumberListener } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + shouldReturnLastReadPosition = arguments?.getBoolean(RETURN_LAST_READ_POSITION) ?: false + } + override fun onResume() { super.onResume() if (!isFirstLoad) { diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/tabs/ReaderTabViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/tabs/ReaderTabViewModel.kt index 6275955..29cd4c1 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/tabs/ReaderTabViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/tabs/ReaderTabViewModel.kt @@ -3,7 +3,7 @@ package com.flamyoad.tsukiviewer.ui.reader.tabs import android.app.Application import androidx.lifecycle.* import com.flamyoad.tsukiviewer.MyAppPreference -import com.flamyoad.tsukiviewer.db.AppDatabase +import com.flamyoad.tsukiviewer.db.dao.RecentTabDao import com.flamyoad.tsukiviewer.model.RecentTab import com.flamyoad.tsukiviewer.ui.reader.ReaderMode import com.flamyoad.tsukiviewer.ui.reader.VolumeButtonScrollDirection @@ -15,13 +15,15 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File import java.util.* +import javax.inject.Inject -class ReaderTabViewModel(application: Application) : AndroidViewModel(application) { +class ReaderTabViewModel @Inject constructor( + private val application: Application, + private val recentTabDao: RecentTabDao +) : ViewModel() { private val appPreference = MyAppPreference.getInstance(application.applicationContext) - private val db = AppDatabase.getInstance(application) - private val imageList = MutableLiveData>() fun imageList(): LiveData> = imageList @@ -53,7 +55,7 @@ class ReaderTabViewModel(application: Application) : AndroidViewModel(applicatio private set init { - recentTabs = db.recentTabDao().getAll() + recentTabs = recentTabDao.getAll() shouldScrollWithVolumeButton = appPreference.shouldScrollWithVolumeButton() diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/BookmarkGroupDialog.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/BookmarkGroupDialog.kt index 55761d1..66bac2b 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/BookmarkGroupDialog.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/BookmarkGroupDialog.kt @@ -1,6 +1,7 @@ package com.flamyoad.tsukiviewer.ui.search import android.app.Dialog +import android.content.Context import android.graphics.Point import android.os.Bundle import android.view.Display @@ -13,19 +14,25 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.CollectionPickerAdapter +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.BookmarkGroup import com.flamyoad.tsukiviewer.ui.doujinpage.BookmarkGroupDialogListener import com.flamyoad.tsukiviewer.ui.doujinpage.DialogCollectionList import com.flamyoad.tsukiviewer.ui.doujinpage.DialogNewCollection +import javax.inject.Inject class BookmarkGroupDialog : DialogFragment(), BookmarkGroupDialogListener { companion object { fun newInstance() = BookmarkGroupDialog() } - private val viewModel: SearchResultViewModel by activityViewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: SearchResultViewModel by activityViewModels { viewModelFactory } private val collectionAdapter: CollectionPickerAdapter = CollectionPickerAdapter(this) @@ -33,6 +40,11 @@ class BookmarkGroupDialog : DialogFragment(), BookmarkGroupDialogListener { private lateinit var btnCancel: Button private lateinit var listCollections: RecyclerView + override fun onAttach(context: Context) { + super.onAttach(context) + (requireActivity().application as MyApplication).appComponent.inject(this) + } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialogBuilder = AlertDialog.Builder(requireContext()) .setTitle("Bookmark to") diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchActivity.kt index 1a1e93f..34b74e7 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchActivity.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchActivity.kt @@ -12,19 +12,25 @@ import androidx.lifecycle.Observer import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.SearchHistoryAdapter import com.flamyoad.tsukiviewer.databinding.ActivitySearchBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.SearchHistory import com.flamyoad.tsukiviewer.model.Tag import com.flamyoad.tsukiviewer.utils.ActivityStackUtils import com.google.android.material.chip.Chip +import javax.inject.Inject class SearchActivity : AppCompatActivity(), TagSelectedListener { private lateinit var binding: ActivitySearchBinding - private val viewModel: SearchViewModel by viewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: SearchViewModel by viewModels { viewModelFactory } companion object { const val SEARCH_TITLE = "SearchActivity.SEARCH_TITLE" @@ -36,6 +42,7 @@ class SearchActivity : AppCompatActivity(), TagSelectedListener { } override fun onCreate(savedInstanceState: Bundle?) { + (application as MyApplication).appComponent.inject(this) super.onCreate(savedInstanceState) binding = ActivitySearchBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchResultActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchResultActivity.kt index cb59afd..ad42b88 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchResultActivity.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchResultActivity.kt @@ -18,9 +18,11 @@ import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import com.flamyoad.tsukiviewer.ActionModeListener import com.flamyoad.tsukiviewer.MyAppPreference +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.LocalDoujinsAdapter import com.flamyoad.tsukiviewer.databinding.ActivitySearchResultBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.Doujin import com.flamyoad.tsukiviewer.model.ViewMode import com.flamyoad.tsukiviewer.ui.editor.EditorActivity @@ -31,6 +33,7 @@ import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch +import javax.inject.Inject private const val ACTION_MODE = "action_mode" private const val ADD_BOOKMARK_DIALOG = "add_bookmark_dialog" @@ -42,7 +45,10 @@ class SearchResultActivity : AppCompatActivity(), private lateinit var binding: ActivitySearchResultBinding - private val viewModel: SearchResultViewModel by viewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: SearchResultViewModel by viewModels { viewModelFactory } private val adapter = LocalDoujinsAdapter(this, this::saveActivityInfo) .apply { setHasStableIds(true) } @@ -56,6 +62,7 @@ class SearchResultActivity : AppCompatActivity(), private var queryJob: Job? = null override fun onCreate(savedInstanceState: Bundle?) { + (application as MyApplication).appComponent.inject(this) super.onCreate(savedInstanceState) binding = ActivitySearchResultBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchResultViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchResultViewModel.kt index 98cf42f..62663e9 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchResultViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchResultViewModel.kt @@ -1,9 +1,7 @@ package com.flamyoad.tsukiviewer.ui.search import android.app.Application -import android.content.Context import androidx.lifecycle.* -import com.flamyoad.tsukiviewer.db.AppDatabase import com.flamyoad.tsukiviewer.db.dao.IncludedPathDao import com.flamyoad.tsukiviewer.model.BookmarkGroup import com.flamyoad.tsukiviewer.model.Doujin @@ -15,19 +13,18 @@ import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.flow.onStart import java.util.* +import javax.inject.Inject -class SearchResultViewModel(private val app: Application) : AndroidViewModel(app) { - private val db: AppDatabase = AppDatabase.getInstance(app) - private val context: Context = app.applicationContext - - private val bookmarkRepo = BookmarkRepository(app) - private val doujinRepo = DoujinRepository(app) +class SearchResultViewModel @Inject constructor( + private val application: Application, + private val bookmarkRepo: BookmarkRepository, + private val doujinRepo: DoujinRepository, + private val pathDao: IncludedPathDao +) : ViewModel() { private val selectedDoujins = mutableListOf() - private val pathDao: IncludedPathDao - - private val includedPathList: LiveData> + private val includedPathList: LiveData> = pathDao.getAll() private val doujinList = mutableListOf() @@ -53,9 +50,6 @@ class SearchResultViewModel(private val app: Application) : AndroidViewModel(app val bookmarkGroupTickStatus = hashMapOf() init { - pathDao = db.includedFolderDao() - includedPathList = pathDao.getAll() - viewModelScope.launch(Dispatchers.IO) { bookmarkGroupList.postValue(bookmarkRepo.getAllGroupsBlocking()) } diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchViewModel.kt index 7c714f9..920f877 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/SearchViewModel.kt @@ -1,20 +1,18 @@ package com.flamyoad.tsukiviewer.ui.search -import android.app.Application import androidx.lifecycle.* import androidx.paging.PagedList -import com.flamyoad.tsukiviewer.db.AppDatabase import com.flamyoad.tsukiviewer.model.SearchHistory import com.flamyoad.tsukiviewer.model.Tag import com.flamyoad.tsukiviewer.repository.SearchHistoryRepository import com.flamyoad.tsukiviewer.repository.TagRepository import kotlinx.coroutines.launch +import javax.inject.Inject -class SearchViewModel(application: Application) : AndroidViewModel(application) { - private val db: AppDatabase = AppDatabase.getInstance(application) - - private val searchHistoryRepo = SearchHistoryRepository(application.applicationContext) - private val tagRepo = TagRepository(application.applicationContext) +class SearchViewModel @Inject constructor( + private val searchHistoryRepo: SearchHistoryRepository, + private val tagRepo: TagRepository +) : ViewModel() { private val tagQuery = MutableLiveData("") diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/SettingsActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/SettingsActivity.kt index 1a68284..0bd3fb8 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/SettingsActivity.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/SettingsActivity.kt @@ -8,10 +8,13 @@ import androidx.activity.viewModels import androidx.lifecycle.Observer import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.databinding.ActivitySettingsBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.ui.settings.preferences.MainPreferences import com.flamyoad.tsukiviewer.utils.extensions.toast +import javax.inject.Inject private const val TOOLBAR_TITLE = "settings_toolbar_title" @@ -20,9 +23,13 @@ class SettingsActivity : AppCompatActivity(), private lateinit var binding: ActivitySettingsBinding - private val viewModel: SettingsViewModel by viewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: SettingsViewModel by viewModels { viewModelFactory } override fun onCreate(savedInstanceState: Bundle?) { + (application as MyApplication).appComponent.inject(this) super.onCreate(savedInstanceState) binding = ActivitySettingsBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/SettingsViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/SettingsViewModel.kt index 3f6b8e7..87d8c9b 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/SettingsViewModel.kt @@ -4,9 +4,9 @@ import android.app.Application import android.content.Intent import android.content.SharedPreferences import android.content.pm.ResolveInfo -import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.preference.PreferenceManager import androidx.room.withTransaction @@ -19,15 +19,18 @@ import com.flamyoad.tsukiviewer.ui.settings.preferences.MainPreferences import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext - -class SettingsViewModel(application: Application) : AndroidViewModel(application) { - private val prefs: SharedPreferences - private val db: AppDatabase - - private val doujinDetailsDao: DoujinDetailsDao - private val doujinTagsDao: DoujinTagsDao - private val tagDao: TagDao +import javax.inject.Inject + +class SettingsViewModel @Inject constructor( + private val application: Application, + private val db: AppDatabase, + private val doujinDetailsDao: DoujinDetailsDao, + private val doujinTagsDao: DoujinTagsDao, + private val tagDao: TagDao, private val searchHistoryDao: SearchHistoryDao +) : ViewModel() { + + private val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(application.applicationContext) private val isRemovingItems = MutableLiveData() fun isRemovingItems(): LiveData = isRemovingItems @@ -42,15 +45,6 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application val pkgAppList: List = application.packageManager.queryIntentActivities(intent, 0) packageAppList.value = pkgAppList - - prefs = PreferenceManager.getDefaultSharedPreferences(application.applicationContext) - - db = AppDatabase.getInstance(application.applicationContext) - - doujinDetailsDao = db.doujinDetailsDao() - doujinTagsDao = db.doujinTagDao() - tagDao = db.tagsDao() - searchHistoryDao = db.searchHistoryDao() } fun setThirdPartyGallery(packageName: String) { diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/includedfolders/IncludedFolderActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/includedfolders/IncludedFolderActivity.kt index 86e322f..eee452d 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/includedfolders/IncludedFolderActivity.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/includedfolders/IncludedFolderActivity.kt @@ -17,16 +17,19 @@ import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager +import com.flamyoad.tsukiviewer.MyApplication import com.flamyoad.tsukiviewer.ui.settings.folderpicker.FolderPickerDialog import com.flamyoad.tsukiviewer.R import com.flamyoad.tsukiviewer.adapter.IncludedFolderAdapter import com.flamyoad.tsukiviewer.databinding.ActivityIncludedFolderBinding +import com.flamyoad.tsukiviewer.di.ViewModelFactory import com.flamyoad.tsukiviewer.model.IncludedPath import com.gun0912.tedpermission.coroutine.TedPermission import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.File +import javax.inject.Inject class IncludedFolderActivity : AppCompatActivity(), AddFolderListener, @@ -34,11 +37,15 @@ class IncludedFolderActivity : AppCompatActivity(), private lateinit var binding: ActivityIncludedFolderBinding - private val viewModel: IncludedFolderViewModel by viewModels() + @Inject + lateinit var viewModelFactory: ViewModelFactory + + private val viewModel: IncludedFolderViewModel by viewModels { viewModelFactory } private lateinit var adapter: IncludedFolderAdapter override fun onCreate(savedInstanceState: Bundle?) { + (application as MyApplication).appComponent.inject(this) super.onCreate(savedInstanceState) binding = ActivityIncludedFolderBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/includedfolders/IncludedFolderViewModel.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/includedfolders/IncludedFolderViewModel.kt index 17f2d96..665b856 100644 --- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/includedfolders/IncludedFolderViewModel.kt +++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/settings/includedfolders/IncludedFolderViewModel.kt @@ -1,29 +1,20 @@ package com.flamyoad.tsukiviewer.ui.settings.includedfolders -import android.app.Application import android.util.Log -import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData +import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.flamyoad.tsukiviewer.db.AppDatabase import com.flamyoad.tsukiviewer.db.dao.IncludedPathDao import com.flamyoad.tsukiviewer.model.IncludedPath import kotlinx.coroutines.launch import java.io.File +import javax.inject.Inject -class IncludedFolderViewModel(application: Application) : AndroidViewModel(application) { - - private val db: AppDatabase - +class IncludedFolderViewModel @Inject constructor( private val pathDao: IncludedPathDao +) : ViewModel() { - val pathList: LiveData> - - init { - db = AppDatabase.getInstance(application) - pathDao = db.includedFolderDao() - pathList = pathDao.getAll() - } + val pathList: LiveData> = pathDao.getAll() fun insert(dir: File) { Log.d("files", dir.canonicalFile.toString()) diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 From 90b4250db5fcb20daf253f2cea1dfc8126cf6f2d Mon Sep 17 00:00:00 2001 From: "yizake1820@gmail.com" Date: Tue, 30 Dec 2025 10:22:50 +0800 Subject: [PATCH 2/4] Dagger --- .../flamyoad/tsukiviewer/di/AppComponent.kt | 102 ++++++++++++++++ .../com/flamyoad/tsukiviewer/di/AppModule.kt | 20 ++++ .../flamyoad/tsukiviewer/di/DatabaseModule.kt | 66 +++++++++++ .../tsukiviewer/di/RepositoryModule.kt | 10 ++ .../tsukiviewer/di/ViewModelFactory.kt | 20 ++++ .../flamyoad/tsukiviewer/di/ViewModelKey.kt | 14 +++ .../tsukiviewer/di/ViewModelModule.kt | 110 ++++++++++++++++++ core/build.gradle | 85 ++++++++++++++ core/consumer-rules.pro | 1 + core/proguard-rules.pro | 1 + core/src/main/AndroidManifest.xml | 3 + .../tsukiviewer/core/di/DatabaseModule.kt | 53 +++++++++ .../tsukiviewer/core/di/RepositoryModule.kt | 39 +++++++ .../tsukiviewer/core/di/ViewModelFactory.kt | 20 ++++ .../tsukiviewer/core/di/ViewModelKey.kt | 14 +++ 15 files changed, 558 insertions(+) create mode 100644 app/src/main/java/com/flamyoad/tsukiviewer/di/AppComponent.kt create mode 100644 app/src/main/java/com/flamyoad/tsukiviewer/di/AppModule.kt create mode 100644 app/src/main/java/com/flamyoad/tsukiviewer/di/DatabaseModule.kt create mode 100644 app/src/main/java/com/flamyoad/tsukiviewer/di/RepositoryModule.kt create mode 100644 app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelFactory.kt create mode 100644 app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelKey.kt create mode 100644 app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelModule.kt create mode 100644 core/build.gradle create mode 100644 core/consumer-rules.pro create mode 100644 core/proguard-rules.pro create mode 100644 core/src/main/AndroidManifest.xml create mode 100644 core/src/main/java/com/flamyoad/tsukiviewer/core/di/DatabaseModule.kt create mode 100644 core/src/main/java/com/flamyoad/tsukiviewer/core/di/RepositoryModule.kt create mode 100644 core/src/main/java/com/flamyoad/tsukiviewer/core/di/ViewModelFactory.kt create mode 100644 core/src/main/java/com/flamyoad/tsukiviewer/core/di/ViewModelKey.kt diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/di/AppComponent.kt b/app/src/main/java/com/flamyoad/tsukiviewer/di/AppComponent.kt new file mode 100644 index 0000000..b5b9029 --- /dev/null +++ b/app/src/main/java/com/flamyoad/tsukiviewer/di/AppComponent.kt @@ -0,0 +1,102 @@ +package com.flamyoad.tsukiviewer.di + +import android.app.Application +import com.flamyoad.tsukiviewer.MainActivity +import com.flamyoad.tsukiviewer.MyApplication +import com.flamyoad.tsukiviewer.network.FetchMetadataService +import com.flamyoad.tsukiviewer.repository.MetadataRepository +import com.flamyoad.tsukiviewer.ui.doujinpage.DialogCollectionList +import com.flamyoad.tsukiviewer.ui.doujinpage.DialogRemoveMetadata +import com.flamyoad.tsukiviewer.ui.doujinpage.DialogViewStyle +import com.flamyoad.tsukiviewer.ui.doujinpage.DoujinDetailsActivity +import com.flamyoad.tsukiviewer.ui.doujinpage.FragmentDoujinDetails +import com.flamyoad.tsukiviewer.ui.doujinpage.FragmentGridImages +import com.flamyoad.tsukiviewer.ui.editor.EditorActivity +import com.flamyoad.tsukiviewer.ui.editor.TagBottomSheetDialog +import com.flamyoad.tsukiviewer.ui.fetcher.FetcherStatusActivity +import com.flamyoad.tsukiviewer.ui.home.bookmarks.BookmarkFragment +import com.flamyoad.tsukiviewer.ui.home.bookmarks.DialogChangeGroupName +import com.flamyoad.tsukiviewer.ui.home.bookmarks.DialogDeleteItems +import com.flamyoad.tsukiviewer.ui.home.bookmarks.DialogNewGroup +import com.flamyoad.tsukiviewer.ui.home.collections.CollectionFragment +import com.flamyoad.tsukiviewer.ui.home.collections.CreateCollectionActivity +import com.flamyoad.tsukiviewer.ui.home.collections.DialogCollectionInfo +import com.flamyoad.tsukiviewer.ui.home.collections.DialogCollectionViewStyle +import com.flamyoad.tsukiviewer.ui.home.collections.DialogDirectoryPicker +import com.flamyoad.tsukiviewer.ui.home.collections.DialogTagPicker +import com.flamyoad.tsukiviewer.ui.home.collections.doujins.BookmarkGroupDialog +import com.flamyoad.tsukiviewer.ui.home.collections.doujins.CollectionDoujinsActivity +import com.flamyoad.tsukiviewer.ui.home.local.DialogSortDoujin +import com.flamyoad.tsukiviewer.ui.home.local.LocalDoujinsFragment +import com.flamyoad.tsukiviewer.ui.home.tags.DoujinTagsFragment +import com.flamyoad.tsukiviewer.ui.home.tags.TagFragment +import com.flamyoad.tsukiviewer.ui.reader.ReaderActivity +import com.flamyoad.tsukiviewer.ui.reader.recents.RecentTabsActivity +import com.flamyoad.tsukiviewer.ui.reader.tabs.ReaderTabFragment +import com.flamyoad.tsukiviewer.ui.search.SearchActivity +import com.flamyoad.tsukiviewer.ui.search.SearchResultActivity +import com.flamyoad.tsukiviewer.ui.settings.SettingsActivity +import com.flamyoad.tsukiviewer.ui.settings.includedfolders.IncludedFolderActivity +import dagger.Component +import javax.inject.Singleton + +@Singleton +@Component( + modules = [ + AppModule::class, + DatabaseModule::class, + RepositoryModule::class, + ViewModelModule::class + ] +) +interface AppComponent { + + fun application(): Application + + // Exposed dependencies + fun metadataRepository(): MetadataRepository + + // Activities + fun inject(activity: MainActivity) + fun inject(activity: DoujinDetailsActivity) + fun inject(activity: EditorActivity) + fun inject(activity: FetcherStatusActivity) + fun inject(activity: CreateCollectionActivity) + fun inject(activity: CollectionDoujinsActivity) + fun inject(activity: ReaderActivity) + fun inject(activity: RecentTabsActivity) + fun inject(activity: SearchActivity) + fun inject(activity: SearchResultActivity) + fun inject(activity: SettingsActivity) + fun inject(activity: IncludedFolderActivity) + + // Fragments + fun inject(fragment: LocalDoujinsFragment) + fun inject(fragment: BookmarkFragment) + fun inject(fragment: CollectionFragment) + fun inject(fragment: DoujinTagsFragment) + fun inject(fragment: TagFragment) + fun inject(fragment: FragmentDoujinDetails) + fun inject(fragment: FragmentGridImages) + fun inject(fragment: ReaderTabFragment) + + // Dialogs + fun inject(dialog: TagBottomSheetDialog) + fun inject(dialog: DialogCollectionInfo) + fun inject(dialog: DialogViewStyle) + fun inject(dialog: DialogCollectionList) + fun inject(dialog: DialogRemoveMetadata) + fun inject(dialog: DialogTagPicker) + fun inject(dialog: DialogDirectoryPicker) + fun inject(dialog: DialogCollectionViewStyle) + fun inject(dialog: BookmarkGroupDialog) + fun inject(dialog: DialogNewGroup) + fun inject(dialog: DialogDeleteItems) + fun inject(dialog: DialogChangeGroupName) + fun inject(dialog: DialogSortDoujin) + fun inject(dialog: com.flamyoad.tsukiviewer.ui.home.local.DialogNewGroup) + fun inject(dialog: com.flamyoad.tsukiviewer.ui.search.BookmarkGroupDialog) + + // Application + fun inject(application: MyApplication) +} diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/di/AppModule.kt b/app/src/main/java/com/flamyoad/tsukiviewer/di/AppModule.kt new file mode 100644 index 0000000..69c49cd --- /dev/null +++ b/app/src/main/java/com/flamyoad/tsukiviewer/di/AppModule.kt @@ -0,0 +1,20 @@ +package com.flamyoad.tsukiviewer.di + +import android.app.Application +import android.content.Context +import com.flamyoad.tsukiviewer.MyApplication +import dagger.Module +import dagger.Provides +import javax.inject.Singleton + +@Module +class AppModule(private val application: MyApplication) { + + @Provides + @Singleton + fun provideApplication(): Application = application + + @Provides + @Singleton + fun provideContext(): Context = application.applicationContext +} diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/di/DatabaseModule.kt b/app/src/main/java/com/flamyoad/tsukiviewer/di/DatabaseModule.kt new file mode 100644 index 0000000..62abb38 --- /dev/null +++ b/app/src/main/java/com/flamyoad/tsukiviewer/di/DatabaseModule.kt @@ -0,0 +1,66 @@ +package com.flamyoad.tsukiviewer.di + +import android.content.Context +import com.flamyoad.tsukiviewer.db.AppDatabase +import com.flamyoad.tsukiviewer.db.dao.* +import dagger.Module +import dagger.Provides +import javax.inject.Singleton + +@Module +class DatabaseModule { + + @Provides + @Singleton + fun provideAppDatabase(context: Context): AppDatabase { + return AppDatabase.getInstance(context) + } + + @Provides + fun provideIncludedPathDao(database: AppDatabase): IncludedPathDao = + database.includedFolderDao() + + @Provides + fun provideDoujinDetailsDao(database: AppDatabase): DoujinDetailsDao = + database.doujinDetailsDao() + + @Provides + fun provideTagsDao(database: AppDatabase): TagDao = + database.tagsDao() + + @Provides + fun provideDoujinTagDao(database: AppDatabase): DoujinTagsDao = + database.doujinTagDao() + + @Provides + fun provideFolderDao(database: AppDatabase): IncludedFolderDao = + database.folderDao() + + @Provides + fun provideBookmarkGroupDao(database: AppDatabase): BookmarkGroupDao = + database.bookmarkGroupDao() + + @Provides + fun provideBookmarkItemDao(database: AppDatabase): BookmarkItemDao = + database.bookmarkItemDao() + + @Provides + fun provideSearchHistoryDao(database: AppDatabase): SearchHistoryDao = + database.searchHistoryDao() + + @Provides + fun provideCollectionDao(database: AppDatabase): CollectionDao = + database.collectionDao() + + @Provides + fun provideCollectionCriteriaDao(database: AppDatabase): CollectionCriteriaDao = + database.collectionCriteriaDao() + + @Provides + fun provideCollectionDoujinDao(database: AppDatabase): CollectionDoujinDao = + database.collectionDoujinDao() + + @Provides + fun provideRecentTabDao(database: AppDatabase): RecentTabDao = + database.recentTabDao() +} diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/di/RepositoryModule.kt b/app/src/main/java/com/flamyoad/tsukiviewer/di/RepositoryModule.kt new file mode 100644 index 0000000..71a474a --- /dev/null +++ b/app/src/main/java/com/flamyoad/tsukiviewer/di/RepositoryModule.kt @@ -0,0 +1,10 @@ +package com.flamyoad.tsukiviewer.di + +import dagger.Module + +/** + * Repositories are provided via constructor injection with @Inject annotation. + * This module is kept for potential future bindings or providing interfaces. + */ +@Module +class RepositoryModule diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelFactory.kt b/app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelFactory.kt new file mode 100644 index 0000000..936bae1 --- /dev/null +++ b/app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelFactory.kt @@ -0,0 +1,20 @@ +package com.flamyoad.tsukiviewer.di + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import javax.inject.Inject +import javax.inject.Provider + +class ViewModelFactory @Inject constructor( + private val viewModels: MutableMap, @JvmSuppressWildcards Provider> +) : ViewModelProvider.Factory { + + @Suppress("UNCHECKED_CAST") + override fun create(modelClass: Class): T { + val viewModelProvider = viewModels[modelClass] + ?: viewModels.entries.firstOrNull { modelClass.isAssignableFrom(it.key) }?.value + ?: throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}") + + return viewModelProvider.get() as T + } +} diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelKey.kt b/app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelKey.kt new file mode 100644 index 0000000..33953e1 --- /dev/null +++ b/app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelKey.kt @@ -0,0 +1,14 @@ +package com.flamyoad.tsukiviewer.di + +import androidx.lifecycle.ViewModel +import dagger.MapKey +import kotlin.reflect.KClass + +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER +) +@Retention(AnnotationRetention.RUNTIME) +@MapKey +annotation class ViewModelKey(val value: KClass) diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelModule.kt b/app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelModule.kt new file mode 100644 index 0000000..fb87415 --- /dev/null +++ b/app/src/main/java/com/flamyoad/tsukiviewer/di/ViewModelModule.kt @@ -0,0 +1,110 @@ +package com.flamyoad.tsukiviewer.di + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.flamyoad.tsukiviewer.ui.doujinpage.DoujinViewModel +import com.flamyoad.tsukiviewer.ui.editor.EditorViewModel +import com.flamyoad.tsukiviewer.ui.home.bookmarks.BookmarkViewModel +import com.flamyoad.tsukiviewer.ui.home.collections.CollectionViewModel +import com.flamyoad.tsukiviewer.ui.home.collections.CreateCollectionViewModel +import com.flamyoad.tsukiviewer.ui.home.collections.DialogCollectionInfoViewModel +import com.flamyoad.tsukiviewer.ui.home.collections.doujins.CollectionDoujinsViewModel +import com.flamyoad.tsukiviewer.ui.home.local.LocalDoujinViewModel +import com.flamyoad.tsukiviewer.ui.home.tags.DoujinTagsViewModel +import com.flamyoad.tsukiviewer.ui.reader.ReaderViewModel +import com.flamyoad.tsukiviewer.ui.reader.recents.RecentTabsViewModel +import com.flamyoad.tsukiviewer.ui.reader.tabs.ReaderTabViewModel +import com.flamyoad.tsukiviewer.ui.search.SearchResultViewModel +import com.flamyoad.tsukiviewer.ui.search.SearchViewModel +import com.flamyoad.tsukiviewer.ui.settings.SettingsViewModel +import com.flamyoad.tsukiviewer.ui.settings.includedfolders.IncludedFolderViewModel +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap + +@Module +abstract class ViewModelModule { + + @Binds + abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory + + @Binds + @IntoMap + @ViewModelKey(LocalDoujinViewModel::class) + abstract fun bindLocalDoujinViewModel(viewModel: LocalDoujinViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(BookmarkViewModel::class) + abstract fun bindBookmarkViewModel(viewModel: BookmarkViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(CollectionViewModel::class) + abstract fun bindCollectionViewModel(viewModel: CollectionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(CreateCollectionViewModel::class) + abstract fun bindCreateCollectionViewModel(viewModel: CreateCollectionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(CollectionDoujinsViewModel::class) + abstract fun bindCollectionDoujinsViewModel(viewModel: CollectionDoujinsViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(DialogCollectionInfoViewModel::class) + abstract fun bindDialogCollectionInfoViewModel(viewModel: DialogCollectionInfoViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(DoujinTagsViewModel::class) + abstract fun bindDoujinTagsViewModel(viewModel: DoujinTagsViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(DoujinViewModel::class) + abstract fun bindDoujinViewModel(viewModel: DoujinViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(EditorViewModel::class) + abstract fun bindEditorViewModel(viewModel: EditorViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(ReaderViewModel::class) + abstract fun bindReaderViewModel(viewModel: ReaderViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(ReaderTabViewModel::class) + abstract fun bindReaderTabViewModel(viewModel: ReaderTabViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(RecentTabsViewModel::class) + abstract fun bindRecentTabsViewModel(viewModel: RecentTabsViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(SearchViewModel::class) + abstract fun bindSearchViewModel(viewModel: SearchViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(SearchResultViewModel::class) + abstract fun bindSearchResultViewModel(viewModel: SearchResultViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(SettingsViewModel::class) + abstract fun bindSettingsViewModel(viewModel: SettingsViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(IncludedFolderViewModel::class) + abstract fun bindIncludedFolderViewModel(viewModel: IncludedFolderViewModel): ViewModel +} diff --git a/core/build.gradle b/core/build.gradle new file mode 100644 index 0000000..2947f2a --- /dev/null +++ b/core/build.gradle @@ -0,0 +1,85 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-kapt' + +android { + namespace 'com.flamyoad.tsukiviewer.core' + compileSdkVersion 34 + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = "17" + } + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 34 + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + + javaCompileOptions { + annotationProcessorOptions { + arguments += ["room.schemaLocation": + "$projectDir/schemas".toString()] + } + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'androidx.core:core-ktx:1.3.0' + implementation 'androidx.appcompat:appcompat:1.1.0' + + // Lifecycle + def lifecycle_version = "2.6.2" + api "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" + api "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" + kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" + + // Room + def room_version = "2.6.1" + api "androidx.room:room-runtime:$room_version" + kapt "androidx.room:room-compiler:$room_version" + api "androidx.room:room-ktx:$room_version" + + // Paging + def paging_version = "3.2.1" + api "androidx.paging:paging-runtime-ktx:$paging_version" + + // Dagger 2 + def dagger_version = "2.48" + api "com.google.dagger:dagger:$dagger_version" + kapt "com.google.dagger:dagger-compiler:$dagger_version" + + // Coroutines + api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3" + api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3" + + // ThreeTenABP for date/time + api 'com.jakewharton.threetenabp:threetenabp:1.2.4' + + // Jsoup for HTML parsing (used in metadata fetching) + api 'org.jsoup:jsoup:1.13.1' + + // Retrofit + def retrofit_version = '2.9.0' + api "com.squareup.retrofit2:retrofit:$retrofit_version" + api "com.squareup.retrofit2:converter-gson:$retrofit_version" + api 'com.google.code.gson:gson:2.8.6' + + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' +} diff --git a/core/consumer-rules.pro b/core/consumer-rules.pro new file mode 100644 index 0000000..da141b0 --- /dev/null +++ b/core/consumer-rules.pro @@ -0,0 +1 @@ +# Proguard rules for consumers of this library diff --git a/core/proguard-rules.pro b/core/proguard-rules.pro new file mode 100644 index 0000000..fb164d6 --- /dev/null +++ b/core/proguard-rules.pro @@ -0,0 +1 @@ +# Add project specific ProGuard rules here. diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9a40236 --- /dev/null +++ b/core/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + diff --git a/core/src/main/java/com/flamyoad/tsukiviewer/core/di/DatabaseModule.kt b/core/src/main/java/com/flamyoad/tsukiviewer/core/di/DatabaseModule.kt new file mode 100644 index 0000000..423418e --- /dev/null +++ b/core/src/main/java/com/flamyoad/tsukiviewer/core/di/DatabaseModule.kt @@ -0,0 +1,53 @@ +package com.flamyoad.tsukiviewer.core.di + +import android.content.Context +import com.flamyoad.tsukiviewer.core.db.AppDatabase +import dagger.Module +import dagger.Provides +import javax.inject.Singleton + +@Module +class DatabaseModule { + + @Provides + @Singleton + fun provideAppDatabase(context: Context): AppDatabase { + return AppDatabase.getInstance(context) + } + + @Provides + fun provideIncludedPathDao(database: AppDatabase) = database.includedFolderDao() + + @Provides + fun provideDoujinDetailsDao(database: AppDatabase) = database.doujinDetailsDao() + + @Provides + fun provideTagsDao(database: AppDatabase) = database.tagsDao() + + @Provides + fun provideDoujinTagDao(database: AppDatabase) = database.doujinTagDao() + + @Provides + fun provideFolderDao(database: AppDatabase) = database.folderDao() + + @Provides + fun provideBookmarkGroupDao(database: AppDatabase) = database.bookmarkGroupDao() + + @Provides + fun provideBookmarkItemDao(database: AppDatabase) = database.bookmarkItemDao() + + @Provides + fun provideSearchHistoryDao(database: AppDatabase) = database.searchHistoryDao() + + @Provides + fun provideCollectionDao(database: AppDatabase) = database.collectionDao() + + @Provides + fun provideCollectionCriteriaDao(database: AppDatabase) = database.collectionCriteriaDao() + + @Provides + fun provideCollectionDoujinDao(database: AppDatabase) = database.collectionDoujinDao() + + @Provides + fun provideRecentTabDao(database: AppDatabase) = database.recentTabDao() +} diff --git a/core/src/main/java/com/flamyoad/tsukiviewer/core/di/RepositoryModule.kt b/core/src/main/java/com/flamyoad/tsukiviewer/core/di/RepositoryModule.kt new file mode 100644 index 0000000..cbc760e --- /dev/null +++ b/core/src/main/java/com/flamyoad/tsukiviewer/core/di/RepositoryModule.kt @@ -0,0 +1,39 @@ +package com.flamyoad.tsukiviewer.core.di + +import com.flamyoad.tsukiviewer.core.repository.BookmarkRepository +import com.flamyoad.tsukiviewer.core.repository.CollectionRepository +import com.flamyoad.tsukiviewer.core.repository.DoujinRepository +import com.flamyoad.tsukiviewer.core.repository.MetadataRepository +import com.flamyoad.tsukiviewer.core.repository.SearchHistoryRepository +import com.flamyoad.tsukiviewer.core.repository.TagRepository +import dagger.Module +import dagger.Provides +import javax.inject.Singleton + +@Module +class RepositoryModule { + + @Provides + @Singleton + fun provideBookmarkRepository(impl: BookmarkRepository): BookmarkRepository = impl + + @Provides + @Singleton + fun provideCollectionRepository(impl: CollectionRepository): CollectionRepository = impl + + @Provides + @Singleton + fun provideDoujinRepository(impl: DoujinRepository): DoujinRepository = impl + + @Provides + @Singleton + fun provideMetadataRepository(impl: MetadataRepository): MetadataRepository = impl + + @Provides + @Singleton + fun provideSearchHistoryRepository(impl: SearchHistoryRepository): SearchHistoryRepository = impl + + @Provides + @Singleton + fun provideTagRepository(impl: TagRepository): TagRepository = impl +} diff --git a/core/src/main/java/com/flamyoad/tsukiviewer/core/di/ViewModelFactory.kt b/core/src/main/java/com/flamyoad/tsukiviewer/core/di/ViewModelFactory.kt new file mode 100644 index 0000000..852c0cf --- /dev/null +++ b/core/src/main/java/com/flamyoad/tsukiviewer/core/di/ViewModelFactory.kt @@ -0,0 +1,20 @@ +package com.flamyoad.tsukiviewer.core.di + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import javax.inject.Inject +import javax.inject.Provider + +class ViewModelFactory @Inject constructor( + private val viewModels: MutableMap, Provider> +) : ViewModelProvider.Factory { + + @Suppress("UNCHECKED_CAST") + override fun create(modelClass: Class): T { + val viewModelProvider = viewModels[modelClass] + ?: viewModels.entries.firstOrNull { modelClass.isAssignableFrom(it.key) }?.value + ?: throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}") + + return viewModelProvider.get() as T + } +} diff --git a/core/src/main/java/com/flamyoad/tsukiviewer/core/di/ViewModelKey.kt b/core/src/main/java/com/flamyoad/tsukiviewer/core/di/ViewModelKey.kt new file mode 100644 index 0000000..d9ab126 --- /dev/null +++ b/core/src/main/java/com/flamyoad/tsukiviewer/core/di/ViewModelKey.kt @@ -0,0 +1,14 @@ +package com.flamyoad.tsukiviewer.core.di + +import androidx.lifecycle.ViewModel +import dagger.MapKey +import kotlin.reflect.KClass + +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER +) +@Retention(AnnotationRetention.RUNTIME) +@MapKey +annotation class ViewModelKey(val value: KClass) From 0d0e862482388d05c7e704ef34f8f3f89e7a8a88 Mon Sep 17 00:00:00 2001 From: "yizake1820@gmail.com" Date: Wed, 31 Dec 2025 14:36:22 +0800 Subject: [PATCH 3/4] f --- .idea/gradle.xml | 5 ++--- .idea/misc.xml | 4 +++- .idea/runConfigurations.xml | 8 ++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 5cd135a..639c779 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,16 +4,15 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index 906a17d..274ccf3 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,10 +1,12 @@ + - + + diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml index 7f68460..72f00ed 100644 --- a/.idea/runConfigurations.xml +++ b/.idea/runConfigurations.xml @@ -3,6 +3,14 @@