-}
\ No newline at end of file
diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/parser/HenNexusParser.kt b/app/src/main/java/com/flamyoad/tsukiviewer/parser/HenNexusParser.kt
deleted file mode 100644
index 38b9d9c..0000000
--- a/app/src/main/java/com/flamyoad/tsukiviewer/parser/HenNexusParser.kt
+++ /dev/null
@@ -1,117 +0,0 @@
-package com.flamyoad.tsukiviewer.parser
-
-import com.flamyoad.tsukiviewer.network.Metadata
-import com.flamyoad.tsukiviewer.network.Result
-import com.flamyoad.tsukiviewer.network.Tags
-import com.flamyoad.tsukiviewer.network.Title
-import org.jsoup.Jsoup
-import java.util.*
-
-class HenNexusParser {
-
- private val baseUrl = "https://hentainexus.com"
-
- // Returns the link of the first item in result
- fun getFirstItemInList(html: String): String {
- val document = Jsoup.parse(html)
-
- val itemList = document.selectFirst(".container > .columns") ?: return ""
-
- val firstItem = itemList.selectFirst("div") ?: return ""
-
- // Example value: "/view/8808"
- val relativeLink = firstItem.select("a").attr("href")
-
- if (relativeLink.isNotBlank()) {
- return relativeLink
- } else {
- return ""
- }
- }
-
- // Returns the title, tags found in+ the HenNexus doujin
- //todo: Surround this method with try/catch..
- fun parseItem(html: String): Metadata {
- val document = Jsoup.parse(html)
-
- val englishTitleContainer = document.selectFirst("h1.title")
-
- // Means no result is found
- if (englishTitleContainer == null) {
- return Metadata(emptyList(), false)
- }
-
- val englishTitle = document.selectFirst("h1.title").text() ?: ""
-
- val table = document.selectFirst("table.view-page-details")
- val tableRows = table.select("tr")
-
- var artistName = ""
- var language = ""
- var magazine = ""
- var parody = ""
- var publisher = ""
-
- for (row in tableRows) {
- // https://stackoverflow.com/questions/7985791/why-jsoup-cannot-select-td-element
- // Jsoup is a HTML5 compliant parser. It cannot detect a that is not inside a
- val correctedHtml = ""
- val correctedRow = Jsoup.parse(correctedHtml)
-
- val rowLabel = correctedRow.selectFirst(".viewcolumn").text()
- val rowContainer = correctedRow.selectFirst("a")
-
- // 'Pages' row does not have link and will return null
- if (rowContainer != null) {
- // Make the string lowercase to be consistent with NHentai e.g. Big Breasts -> big breasts
- val rowValue = rowContainer.text().toLowerCase(Locale.ROOT)
- when (rowLabel) {
- "Artist" -> artistName = rowValue
- "Language" -> language = rowValue
- "Magazine" -> magazine = rowValue
- "Parody" -> parody = rowValue
- "Publisher" -> publisher = rowValue
- }
- }
- }
-
- val spans = tableRows.select("span.tag")
-
- val tagList =
- spans
- .filter { tag -> tag.text().isNotBlank() }
- .map { Tags(id = 0, type = "tag", name = it.text(), count = 0, url = "") }
- .toMutableList()
-
- if (artistName.isNotBlank()) {
- tagList.add(Tags(id = 0, type = "artist", name = artistName, count = 0, url = ""))
- }
-
- if (language.isNotBlank()) {
- tagList.add(Tags(id = 0, type = "language", name = language, count = 0, url = ""))
- }
-
- if (magazine.isNotBlank()) {
- tagList.add(Tags(id = 0, type = "group", name = magazine, count = 0, url = ""))
- }
-
- if (parody.isNotBlank()) {
- tagList.add(Tags(id = 0, type = "parody", name = parody, count = 0, url = ""))
- }
-
- if (publisher.isNotBlank()) {
- tagList.add(Tags(id = 0, type = "group", name = publisher, count = 0, url = ""))
- }
-
- val result = Result(
- nukeCode = 0,
- title = Title(english = englishTitle, japanese = "", pretty = englishTitle),
- scanlator = "",
- upload_date = 0,
- tags = tagList
- )
-
- val metadata = Metadata(listOf(result))
- return metadata
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/BookmarkRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/BookmarkRepository.kt
deleted file mode 100644
index 4f5ace8..0000000
--- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/BookmarkRepository.kt
+++ /dev/null
@@ -1,231 +0,0 @@
-package com.flamyoad.tsukiviewer.repository
-
-import android.content.Context
-import android.util.Log
-import androidx.lifecycle.LiveData
-import androidx.room.withTransaction
-import com.flamyoad.tsukiviewer.db.AppDatabase
-import com.flamyoad.tsukiviewer.db.dao.BookmarkGroupDao
-import com.flamyoad.tsukiviewer.db.dao.BookmarkItemDao
-import com.flamyoad.tsukiviewer.model.BookmarkGroup
-import com.flamyoad.tsukiviewer.model.BookmarkItem
-import com.flamyoad.tsukiviewer.model.Doujin
-import org.threeten.bp.Instant
-import java.io.File
-
-class BookmarkRepository(private val context: Context) {
- 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()
- }
-
- fun getAllItems(group: BookmarkGroup): LiveData> {
- return itemDao.from(group.name)
- }
-
- suspend fun getAllItemsFrom(group: BookmarkGroup): List {
- return itemDao.selectFrom(group.name)
- }
-
- suspend fun getAllItemsFrom(groupName: String): List {
- return itemDao.selectFrom(groupName)
- }
-
- fun getGroup(name: String): LiveData {
- return groupDao.get(name)
- }
-
- fun getAllGroups(): LiveData> {
- return groupDao.getAll()
- }
-
- fun groupNameExists(name: String): LiveData {
- return groupDao.exists(name)
- }
-
- suspend fun getAllGroupsFrom(absolutePath: File): List {
- val collections = groupDao.getAllBlocking()
- val names = groupDao.getCollectionNamesFrom(absolutePath)
-
- for (collection in collections) {
- if (collection.name in names) {
- collection.isTicked = true
- }
- }
- return collections
- }
-
- suspend fun changeGroupName(oldName: String, newName: String) {
- return groupDao.changeName(oldName, newName)
- }
-
- suspend fun removeGroup(group: BookmarkGroup) {
- groupDao.delete(group)
- }
-
- suspend fun removeGroup(name: String) {
- groupDao.delete(name)
- }
-
- suspend fun getAllGroupsBlocking(): List {
- return groupDao.getAllBlocking()
- }
-
- suspend fun insertGroup(collection: BookmarkGroup) {
- groupDao.insert(collection)
- }
-
- suspend fun insertItem(item: BookmarkItem) {
- itemDao.insert(item)
- }
-
- suspend fun moveItemsTo(group: BookmarkGroup, itemsToBeMoved: List): Int {
- val movedItems = db.withTransaction {
- itemDao.delete(itemsToBeMoved)
-
- val itemList = itemsToBeMoved.map { x ->
- BookmarkItem(
- id = null,
- absolutePath = x.absolutePath,
- parentName = group.name,
- dateAdded = x.dateAdded
- )
- }
- return@withTransaction itemDao.insert(itemList)
- }
- return movedItems.size
- }
-
- // Returns: Snackbar message to be shown to user indicating the number of insert and delete
- suspend fun wipeAndInsertNew(
- absolutePath: File,
- hashMap: HashMap
- ): String {
- val namesOfCollectionsToRemoveFrom = hashMap
- .filter { kvp -> kvp.value == false }
- .map { kvp -> kvp.key }
-
- val dateAdded = Instant.now().toEpochMilli()
-
- val itemsToInsert = hashMap
- .filter { kvp -> kvp.value == true }
- .map { kvp ->
- BookmarkItem(
- id = null,
- absolutePath = absolutePath,
- parentName = kvp.key,
- dateAdded = dateAdded
- )
- }
-
- return db.withTransaction {
- try {
- var insertCount = 0
- for (item in itemsToInsert) {
- if (itemDao.exists(item.absolutePath, item.parentName)) {
- continue
- } else {
- val insertedId = itemDao.insert(item)
- if (insertedId > 0) {
- insertCount++
- }
- }
- }
-
- var deleteCount = 0
- for (name in namesOfCollectionsToRemoveFrom) {
- val count = itemDao.delete(absolutePath, name)
- deleteCount += count
- }
-
- // Example message: Added into 1 collection. Removed from 1 collection.
- val stringBuilder = StringBuilder()
-
- if (insertCount > 0) {
- stringBuilder.append("Added into ${insertCount} ${getNoun(insertCount)}. ")
- }
-
- if (deleteCount > 0) {
- stringBuilder.append("Removed from ${deleteCount} ${getNoun(deleteCount)}")
- }
-
- return@withTransaction stringBuilder.toString()
-
- } catch (e: Exception) {
- Log.e("db", e.message ?: "Unknown error")
- e.printStackTrace()
- return@withTransaction "Failed to add or remove current doujin"
- }
- }
- }
-
- suspend fun insertAllItems(doujinList: List, groupNames: List): String {
- val dateAdded = Instant.now().toEpochMilli()
-
- val itemsToInsert = groupNames.flatMap { groupName ->
- doujinList.map { doujin ->
- BookmarkItem(
- id = null,
- absolutePath = doujin.path,
- parentName = groupName,
- dateAdded = dateAdded
- )
- }
- }
-
- return db.withTransaction {
- var insertCount = 0
- for (item in itemsToInsert) {
- if (itemDao.exists(item.absolutePath, item.parentName)) {
- continue
- } else {
- val insertedId = itemDao.insert(item)
- if (insertedId > 0) {
- insertCount++
- }
- }
- }
-
- if (insertCount == 0) {
- return@withTransaction "No items are bookmarked"
- }
-
- val builder = StringBuilder()
-
- when {
- insertCount == 1 -> builder.append("$insertCount item has been bookmarked. ")
- insertCount > 1 -> builder.append("$insertCount items have been bookmarked. ")
- }
-
- val ignoreCount = doujinList.size - insertCount
- when {
- ignoreCount == 1 -> builder.append("$ignoreCount duplicate item ignored")
- ignoreCount > 1 -> builder.append("$ignoreCount duplicate items ignored")
- }
-
- return@withTransaction builder.toString()
- }
- }
-
- private fun getNoun(number: Int): String {
- if (number > 1) {
- return "collections"
- } else {
- return "collection"
- }
- }
-}
-
diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/CollectionRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/CollectionRepository.kt
deleted file mode 100644
index 564e48c..0000000
--- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/CollectionRepository.kt
+++ /dev/null
@@ -1,171 +0,0 @@
-package com.flamyoad.tsukiviewer.repository
-
-import android.content.Context
-import androidx.lifecycle.LiveData
-import androidx.room.withTransaction
-import com.flamyoad.tsukiviewer.db.AppDatabase
-import com.flamyoad.tsukiviewer.db.dao.CollectionCriteriaDao
-import com.flamyoad.tsukiviewer.db.dao.CollectionDao
-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
- private val collectionDoujinDao: CollectionDoujinDao
-
- init {
- collectionDao = db.collectionDao()
- criteriaDao = db.collectionCriteriaDao()
- collectionDoujinDao = db.collectionDoujinDao()
- }
-
- suspend fun get(id: Long): Collection {
- return collectionDao.getBlocking(id)
- }
-
- suspend fun getAll(): List {
- return collectionDao.getAllBlocking()
- }
-
- fun getAllWithCriterias(): LiveData> {
- return collectionDao.getAllWithCriterias()
- }
-
- fun getAllWithCriterias(keyword: String): LiveData> {
- return collectionDao.getAllWithCriterias(keyword)
- }
-
- suspend fun insert(collection: Collection, criterias: List) {
- db.withTransaction {
- val collectionId = collectionDao.insert(collection)
-
- // If editing existing collection, wipe all previous criterias before inserting new ones
- collection.id?.let {
- criteriaDao.delete(it)
- collectionDao.deleteThumbnail(it)
- }
-
- // Fill in criterias with collectionId, which is impossible to get before first inserting the collection
- val completedCriterias = criterias.map { criteria ->
- CollectionCriteria(
- id = null,
- collectionId = collectionId,
- type = criteria.type,
- value = criteria.value,
- valueName = criteria.valueName
- )
- }
-
- for (criteria in completedCriterias) {
- criteriaDao.insert(criteria)
- }
- }
- }
-
- suspend fun delete(collectionId: Long) {
- db.withTransaction {
- collectionDao.delete(collectionId)
- criteriaDao.delete(collectionId)
- }
- }
-
- // It's ok to use INSERT for new/old because onConflictStrategy is REPLACE
- suspend fun update(criterias: List) {
- db.withTransaction {
- for (criteria in criterias) {
- criteriaDao.insert(criteria)
- }
- }
- }
-
- suspend fun updateThumbnail(collectionId: Long?, file: File) {
- if (collectionId == null) return
- collectionDao.updateThumbnail(collectionId, file)
- }
-
- suspend fun getTitles(id: Long): List {
- return criteriaDao.getTitlesBlocking(id)
- }
-
- suspend fun getIncludedTags(id: Long): List {
- return criteriaDao.getIncludedTagsBlocking(id)
- }
-
- suspend fun getExcludedTags(id: Long): List {
- return criteriaDao.getExcludedTagsBlocking(id)
- }
-
- suspend fun getDirectories(id: Long): List {
- return criteriaDao.getDirectoriesBlocking(id)
- }
-
- suspend fun searchIncludedOrExcludedOr(
- includedTags: List,
- excludedTags: List
- ): List {
- val includedTagsId = includedTags.map { tag -> tag.tagId ?: -1 }
- val excludedTagsId = excludedTags.map { tag -> tag.tagId ?: -1 }
-
- if (includedTags.isEmpty())
- return collectionDoujinDao.searchExcludedOr(excludedTagsId)
-
- if (excludedTags.isEmpty())
- return collectionDoujinDao.searchIncludedOr(includedTagsId)
-
- return collectionDoujinDao.searchIncludedOrExcludedOr(includedTagsId, excludedTagsId)
- }
-
- suspend fun searchIncludedOrExcludedAnd(
- includedTags: List,
- excludedTags: List
- ): List {
- val includedTagsId = includedTags.map { tag -> tag.tagId ?: -1 }
- val excludedTagsId = excludedTags.map { tag -> tag.tagId ?: -1 }
-
- if (includedTags.isEmpty())
- return collectionDoujinDao.searchExcludedAnd(excludedTagsId, excludedTagsId.size)
-
- if (excludedTags.isEmpty())
- return collectionDoujinDao.searchIncludedOr(includedTagsId)
-
- return collectionDoujinDao.searchIncludedOrExcludedAnd(includedTagsId, excludedTagsId, excludedTags.size)
- }
-
- suspend fun searchIncludedAndExcludedOr(
- includedTags: List,
- excludedTags: List
- ): List {
- val includedTagsId = includedTags.map { tag -> tag.tagId ?: -1 }
- val excludedTagsId = excludedTags.map { tag -> tag.tagId ?: -1 }
-
- if (includedTags.isEmpty())
- return collectionDoujinDao.searchExcludedOr(excludedTagsId)
-
- if (excludedTags.isEmpty())
- return collectionDoujinDao.searchIncludedAnd(includedTagsId, includedTagsId.size)
-
- return collectionDoujinDao.searchIncludedAndExcludedOr(includedTagsId, excludedTagsId, includedTags.size)
- }
-
- suspend fun searchIncludedAndExcludedAnd(
- includedTags: List,
- excludedTags: List
- ): List {
- val includedTagsId = includedTags.map { tag -> tag.tagId ?: -1 }
- val excludedTagsId = excludedTags.map { tag -> tag.tagId ?: -1 }
-
- if (includedTags.isEmpty())
- return collectionDoujinDao.searchExcludedAnd(excludedTagsId, excludedTagsId.size)
-
- if (excludedTags.isEmpty())
- return collectionDoujinDao.searchIncludedAnd(includedTagsId, includedTagsId.size)
-
- return collectionDoujinDao.searchIncludedAndExcludedAnd(includedTagsId, excludedTagsId, includedTags.size, excludedTags.size)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/DoujinRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/DoujinRepository.kt
deleted file mode 100644
index a014bbc..0000000
--- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/DoujinRepository.kt
+++ /dev/null
@@ -1,169 +0,0 @@
-package com.flamyoad.tsukiviewer.repository
-
-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
-import com.flamyoad.tsukiviewer.model.DoujinDetails
-import com.flamyoad.tsukiviewer.utils.ImageFileFilter
-import com.flamyoad.tsukiviewer.utils.extensions.toDoujin
-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
-
- fun scanForDoujins(keyword: String, tags: String, shouldIncludeAllTags: Boolean)
- : Flow {
- val keywordLowerCase = keyword.toLowerCase(Locale.ROOT)
-
- val flowFromDatabase = searchFromDatabase(keywordLowerCase, tags, shouldIncludeAllTags)
- val flowFromFileExplorer: Flow = if (tags.isBlank()) {
- if (existingList != null) {
- searchFromExistingList(keywordLowerCase)
- } else {
- searchFromFileExplorer(keywordLowerCase)
- }
- } else {
- emptyFlow()
- }
-
- return flowOf(flowFromDatabase, flowFromFileExplorer).flattenMerge()
- }
-
- private fun searchFromDatabase(keyword: String, tags: String, shouldIncludeAllTags: Boolean)
- : Flow = flow {
-
- if (keyword.isNotBlank() && tags.isNotBlank()) { // Search using both title and tags
- val tagList = tags.split(",")
- .map { tagName -> tagName }
-
- val doujinDetailItems = when (shouldIncludeAllTags) {
- true -> doujinDetailsDao.findByTags(tagList, tagList.size) // Searched items must include all tags
- false -> doujinDetailsDao.findByTags(tagList) // Searched items must include at least 1 tag
- }
-
- for (item in doujinDetailItems) {
- val containsKeywordEnglish = item.fullTitleEnglish.toLowerCase(Locale.ROOT).contains(keyword)
- val containsKeywordJap = item.fullTitleJapanese.contains(keyword)
-
- if (containsKeywordEnglish || containsKeywordJap) {
- emit(item.absolutePath.toDoujin() ?: return@flow)
- }
- }
-
- } else if (keyword.isNotBlank() && tags.isBlank()) { // Search using title only
- val doujinDetailItems = doujinDetailsDao.findByTitle(keyword)
-
- for (item in doujinDetailItems) {
- emit(item.absolutePath.toDoujin() ?: return@flow)
- }
-
- } else if (tags.isNotBlank() && keyword.isBlank()) { // Search using tags only
- val tagList = tags.split(",")
- .map { tagName -> tagName }
-
- val doujinDetailItems = when (shouldIncludeAllTags) {
- true -> doujinDetailsDao.findByTags(tagList, tagList.size)
- false -> doujinDetailsDao.findByTags(tagList)
- }
-
- for (item in doujinDetailItems) {
- emit(item.absolutePath.toDoujin() ?: return@flow)
- }
- }
- }
-
- private fun searchFromFileExplorer(keyword: String): Flow = flow {
- val includedDirs = pathDao.getAllBlocking()
- for (dir in includedDirs) {
- val pathName = dir.toString()
-
- val uri = MediaStore.Files.getContentUri("external")
-
- val projection = arrayOf(
- MediaStore.Files.FileColumns.DATA,
- MediaStore.Files.FileColumns.PARENT
- )
-
- val selection =
- "${MediaStore.Files.FileColumns.DATA} LIKE ?" +
- " AND " +
- "${MediaStore.Files.FileColumns.TITLE} LIKE ?"
-
- val params = arrayOf(
- "%" + pathName + "%",
- "%" + keyword + "%"
- )
-
- val cursor = ContentResolverCompat.query(
- contentResolver,
- uri,
- projection,
- selection,
- params,
- null,
- null
- )
-
- while (cursor.moveToNext()) {
- val idSet = mutableSetOf()
-
- val fullPath =
- cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA))
- val parentId =
- cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.PARENT))
-
- if (idSet.add(parentId)) {
- val doujinDir = File(fullPath)
-
- val imageList = doujinDir.listFiles(ImageFileFilter())
-
- if (!imageList.isNullOrEmpty()) {
- val doujin = Doujin(
- pic = imageList.first().toUri(),
- title = doujinDir.name,
- path = doujinDir,
- lastModified = doujinDir.lastModified(),
- numberOfItems = imageList.size
- )
- emit(doujin)
- }
- }
- }
- }
- }
-
- private fun searchFromExistingList(keyword: String): Flow = flow {
- if (existingList == null) {
- return@flow
- }
-
- val newList = mutableListOf()
- for (doujin in existingList) {
- if (doujin.title.toLowerCase(Locale.ROOT).contains(keyword)) {
- newList.add(doujin)
- emit(doujin)
- }
- }
- }
-
- private fun MutableList.addIfNotNull(doujinDetails: DoujinDetails) {
- val doujin = doujinDetails.absolutePath.toDoujin()
- if (doujin != null) {
- this.add(doujin)
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/MetadataRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/MetadataRepository.kt
deleted file mode 100644
index 3139e8e..0000000
--- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/MetadataRepository.kt
+++ /dev/null
@@ -1,368 +0,0 @@
-package com.flamyoad.tsukiviewer.repository
-
-import android.content.Context
-import android.os.Handler
-import android.os.Looper
-import android.util.Log
-import android.webkit.WebSettings
-import android.widget.Toast
-import androidx.room.withTransaction
-import com.flamyoad.tsukiviewer.db.AppDatabase
-import com.flamyoad.tsukiviewer.db.dao.*
-import com.flamyoad.tsukiviewer.model.DoujinDetails
-import com.flamyoad.tsukiviewer.model.DoujinTag
-import com.flamyoad.tsukiviewer.model.Source
-import com.flamyoad.tsukiviewer.model.Tag
-import com.flamyoad.tsukiviewer.network.*
-import com.flamyoad.tsukiviewer.network.api.FakkuService
-import com.flamyoad.tsukiviewer.network.api.HenNexusService
-import com.flamyoad.tsukiviewer.network.api.NHService
-import com.flamyoad.tsukiviewer.parser.HenNexusParser
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.withContext
-import okhttp3.Dispatcher
-import okhttp3.Interceptor
-import okhttp3.OkHttpClient
-import okhttp3.logging.HttpLoggingInterceptor
-import retrofit2.Retrofit
-import retrofit2.converter.gson.GsonConverterFactory
-import java.io.File
-import java.io.IOException
-import java.util.*
-
-class MetadataRepository(private val context: Context) {
- 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]
- After : AzuLan Shikoshiko Bokou Seikatsu
- */
- private val regex by lazy {
- "\\[.*?]|\\(.*?\\)".toRegex()
- }
-
- private var toast: Toast? = null
-
- init {
- initializeNetwork()
-
- db = AppDatabase.getInstance(context)
-
- pathDao = db.includedFolderDao()
- doujinDetailsDao = db.doujinDetailsDao()
- tagDao = db.tagsDao()
- doujinTagDao = db.doujinTagDao()
- folderDao = db.folderDao()
- }
-
- private fun initializeNetwork() {
- // Nhentai API refuses the requests if the user agent is not attached.
- val dispatcher = Dispatcher().apply {
- maxRequests = 3
- }
-
- val httpClient: OkHttpClient = OkHttpClient.Builder()
- .addInterceptor(object : Interceptor {
- override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
- val request = chain.request()
- .newBuilder()
- .removeHeader("User-Agent")
- .addHeader("User-Agent", WebSettings.getDefaultUserAgent(context))
- .build()
-
- return chain.proceed(request)
- }
- })
- .addInterceptor(HttpLoggingInterceptor().apply {
- level = HttpLoggingInterceptor.Level.BODY
- })
- .dispatcher(dispatcher)
- .build()
-
- val nhBuilder = Retrofit.Builder()
- .client(httpClient)
- .baseUrl(NHService.baseUrl)
- .addConverterFactory(GsonConverterFactory.create())
- .build()
-
- nhService = nhBuilder.create(NHService::class.java)
-
- val henNexusBuilder = Retrofit.Builder()
- .client(httpClient)
- .baseUrl(HenNexusService.baseUrl)
- .build()
-
- henNexusService = henNexusBuilder.create(HenNexusService::class.java)
-
-// val fakkuBuilder = Retrofit.Builder()
-// .client(httpClient)
-// .baseUrl(FakkuService.baseUrl)
-// .build()
-//
-// fakkuService = fakkuBuilder.create(FakkuService::class.java)
- }
-
- suspend fun fetchMetadata(dir: File, sources: EnumSet): FetchHistory {
- return withContext(Dispatchers.IO) {
- if (doujinDetailsDao.existsByTitle(dir.name) || doujinDetailsDao.existsByAbsolutePath(dir.toString())) {
- return@withContext FetchHistory(dir, dir.name, FetchStatus.ALREADY_EXISTS)
-
- } else {
- val fetchResult = requestMetadata(dir.name, sources)
- val title = fetchResult.getDoujinTitle() ?: dir.name
-
- val metadata = fetchResult.metadata
-
- if (metadata == null) {
- return@withContext FetchHistory(dir, title, FetchStatus.NO_MATCH)
- } else {
- saveMetadata(metadata, dir)
- return@withContext FetchHistory(dir, title, fetchResult.status)
- }
- }
- }
- }
-
- private fun requestMetadata(fullTitle: String, sources: EnumSet): FetchResult {
- var cleanedTitle: String = ""
-
- if (sources.contains(Source.NHentai)) {
- // First try is attempted with title which contains all these , | [] {} symbols
- val queryNhentaiWithDirName = requestFromNhentai(fullTitle)
- Log.d("fetchbug", "Query NHentai with Dir Name")
- if (queryNhentaiWithDirName.status == FetchStatus.SUCCESS) {
- return queryNhentaiWithDirName
- }
-
- cleanedTitle = fullTitle.replace(regex, "")
- if (cleanedTitle == fullTitle) {
- return queryNhentaiWithDirName // No point retrying if same string
- }
-
- // Retry with cleaned title without symbols
- Log.d("fetchbug", "Query NHentai with Cleaned Name")
- val queryNhentaiWithCleanTitle = requestFromNhentai(cleanedTitle)
- if (queryNhentaiWithCleanTitle.status == FetchStatus.SUCCESS) {
- return queryNhentaiWithCleanTitle
- }
- }
-
-// if (sources.contains(Source.HentaiNexus)) {
-// Log.d("fetchbug", "Query HentaiNexus with Cleaned Name")
-// if (cleanedTitle == "") {
-// cleanedTitle = fullTitle.replace(regex, "")
-// }
-//
-// return requestFromHenNexus(cleanedTitle)
-// }
-
- Log.d("fetchbug", "No match")
- return FetchResult(null, FetchStatus.NO_MATCH)
- }
-
- private fun requestFromNhentai(fullTitle: String): FetchResult {
- try {
- // Wraps query parameter with double quotes to perform exact search
- val response = nhService.getMetadata("\"" + fullTitle + "\"").execute()
- val json = response.body() ?: return FetchResult(status = FetchStatus.NETWORK_ERROR)
-
- return when (json.result.isEmpty()) {
- true -> FetchResult(status = FetchStatus.NO_MATCH)
- false -> FetchResult(json, status = FetchStatus.SUCCESS)
- }
-
- } catch (e: IOException) {
- showToast("Failed to fetch metadata")
- return FetchResult(status = FetchStatus.NETWORK_ERROR)
- }
- }
-
- private fun requestFromHenNexus(fullTitle: String): FetchResult {
- try {
- val searchRequest = henNexusService.getSearchResult(fullTitle).execute()
- val searchResultHtml = searchRequest.body()?.string()
-
- if (searchResultHtml.isNullOrBlank()) {
- return FetchResult(status = FetchStatus.NO_MATCH)
- }
-
- val firstItemLink = henNexusParser.getFirstItemInList(searchResultHtml)
-
- val firstItemRequest = henNexusService.getPageUrl(firstItemLink).execute()
- val firstItemHtml = firstItemRequest.body()?.string()
-
- if (firstItemHtml.isNullOrBlank()) {
- return FetchResult(status = FetchStatus.NO_MATCH)
- }
-
- val metadata = henNexusParser.parseItem(firstItemHtml)
-
- if (!metadata.hasValue) {
- return FetchResult(status = FetchStatus.NO_MATCH)
- } else {
- return FetchResult(metadata, status = FetchStatus.SUCCESS)
- }
-
- } catch (e: IOException) {
- showToast("Failed to fetch metadata")
- return FetchResult(status = FetchStatus.NETWORK_ERROR)
- }
- }
-
- private suspend fun saveMetadata(metadata: Metadata, dir: File): String {
- // Api might return a list of duplicate results. We only want the first one
- val item = metadata.result.first()
-
- val doujinDetails = DoujinDetails(
- nukeCode = item.nukeCode,
- fullTitleEnglish = item.title.english,
- fullTitleJapanese = item.title.japanese ?: "",
- shortTitleEnglish = item.title.pretty ?: "",
- absolutePath = dir,
- folderName = dir.name
- )
-
- db.withTransaction {
- val doujinId = doujinDetailsDao.insert(doujinDetails)
-
- for (tag in item.tags) {
- var tagId: Long
-
- if (tag.name.trim() == "" || tag.name == "null")
- continue
-
- if (tagDao.exists(tag.type, tag.name)) {
- tagDao.incrementCount(tag.type, tag.name)
- tagId = tagDao.getId(tag.type, tag.name)
-
- } else {
- tagId = tagDao.insert(
- Tag(
- tagId = null,
- name = tag.name,
- type = tag.type,
- url = tag.url,
- count = 1
- )
- )
- }
- doujinTagDao.insert(DoujinTag(doujinId, tagId))
- }
- }
- return item.title.english
- }
-
- // Erases previous existing tags and adds tags edited by user
- suspend fun saveEditedMetadata(doujinDetails: DoujinDetails, tags: List) {
- withContext(Dispatchers.IO) {
- db.withTransaction {
- val absolutePath = doujinDetails.absolutePath.absolutePath
-
- val doujinId: Long
-
- // Insert into db if a record identified by its absolute path does not exist yet
- if (!doujinDetailsDao.existsByAbsolutePath(absolutePath)) {
- doujinId = doujinDetailsDao.insert(doujinDetails)
- } else {
- val fetchedItems: List =
- doujinDetailsDao.findByAbsolutePath(absolutePath)
- doujinId = fetchedItems.first().id ?: -1
- }
-
- // Decrements book count for all tags in the previous data
- doujinTagDao.decrementTagCount(doujinId)
-
- // Removes all rows related to chosen id in the table
- doujinTagDao.deleteFromDoujin(doujinId)
-
- // Inserts new tag if has any, increments count for tags that already exist
- tags.forEach { tag ->
- insertTagElseIncrement(doujinId, tag)
- }
- }
- }
- }
-
- private suspend fun insertTagElseIncrement(doujinId: Long, tag: Tag) {
- db.withTransaction {
- val tagId: Long
-
- if (tag.name.trim() == "" || tag.name == "null")
- return@withTransaction
-
- if (tagDao.exists(tag.type, tag.name)) {
- tagDao.incrementCount(tag.type, tag.name)
- tagId = tagDao.getId(tag.type, tag.name)
-
- } else {
- tagId = tagDao.insert(
- Tag(
- tagId = null,
- name = tag.name,
- type = tag.type,
- url = tag.url,
- count = 1
- )
- )
- }
- doujinTagDao.insert(
- DoujinTag(doujinId, tagId)
- )
- }
- }
-
- suspend fun removeMetadata(doujinDetails: DoujinDetails) {
- withContext(Dispatchers.IO) {
- db.withTransaction {
- doujinDetailsDao.delete(doujinDetails)
- doujinTagDao.deleteFromDoujin(doujinDetails.id!!)
- doujinTagDao.decrementTagCount(doujinDetails.id)
- }
- }
- }
-
- suspend fun resetTags(dir: File, sources: EnumSet) {
- withContext(Dispatchers.IO) {
-// val result = requestFromNhentai(dir.name)
- val result = requestMetadata(dir.name, sources)
-
- if (result.status == FetchStatus.SUCCESS) {
- val doujinDetails = doujinDetailsDao
- .findByAbsolutePath(dir.absolutePath)
- .first()
-
- if (result.metadata == null) return@withContext
-
- val tagList = result.metadata.getTags()
- .map { x -> Tag(type = x.type, name = x.name, url = x.url, count = 1) }
- saveEditedMetadata(doujinDetails, tagList)
- } else {
- Log.d("retrofit", "Can't find this sauce")
- }
- }
- }
-
- // Need this because we are running in non-UI thread
- private fun showToast(message: String) {
- val handler = Handler(Looper.getMainLooper())
- handler.post {
- toast?.cancel()
-
- toast = Toast.makeText(context, message, Toast.LENGTH_SHORT)
- toast?.show()
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/SearchHistoryRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/SearchHistoryRepository.kt
deleted file mode 100644
index 1e043b9..0000000
--- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/SearchHistoryRepository.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-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.model.SearchHistory
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.withContext
-
-class SearchHistoryRepository(private val context: Context) {
- private val db: AppDatabase = AppDatabase.getInstance(context)
- val searchHistoryDao = db.searchHistoryDao()
-
- fun getAll(pageSize: Int): LiveData> {
- return searchHistoryDao.getAll()
- .toLiveData(pageSize)
- }
-
- suspend fun insertSearchHistory(item: SearchHistory) {
- withContext(Dispatchers.IO) {
- val lastInsertedItem = searchHistoryDao.getLatestItem()
-
- /* 1st condition: If last inserted item is null, means the search history has 0 items
- 2nd condition: If user inputs the same thing as previous search,
- then there is no need to insert into database
- */
- val shouldInsert = lastInsertedItem == null || !lastInsertedItem.sameWith(item)
- if (shouldInsert) {
- searchHistoryDao.insert(item)
- }
- }
- }
-
- suspend fun deleteSingle(item: SearchHistory) {
- withContext(Dispatchers.IO) {
- searchHistoryDao.delete(item)
- }
- }
-
- suspend fun deleteAll() {
- withContext(Dispatchers.IO) {
- searchHistoryDao.deleteAll()
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/repository/TagRepository.kt b/app/src/main/java/com/flamyoad/tsukiviewer/repository/TagRepository.kt
deleted file mode 100644
index a0609ca..0000000
--- a/app/src/main/java/com/flamyoad/tsukiviewer/repository/TagRepository.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.flamyoad.tsukiviewer.repository
-
-import android.content.Context
-import androidx.lifecycle.LiveData
-import com.flamyoad.tsukiviewer.db.AppDatabase
-import com.flamyoad.tsukiviewer.model.Tag
-
-class TagRepository(private val context: Context) {
- private val db: AppDatabase = AppDatabase.getInstance(context)
- private val tagDao = db.tagsDao()
-
- fun getAll(): LiveData> {
- return tagDao.getAll()
- }
-
- fun getAllWithFilter(keyword: String): LiveData> {
- return tagDao.getAllWithFilter(keyword)
- }
-}
\ 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/service/FetchMetadataService.kt
similarity index 95%
rename from app/src/main/java/com/flamyoad/tsukiviewer/network/FetchMetadataService.kt
rename to app/src/main/java/com/flamyoad/tsukiviewer/service/FetchMetadataService.kt
index 69b7e08..95c809e 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/network/FetchMetadataService.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/service/FetchMetadataService.kt
@@ -1,4 +1,4 @@
-package com.flamyoad.tsukiviewer.network
+package com.flamyoad.tsukiviewer.service
import android.app.*
import android.content.Context
@@ -11,9 +11,13 @@ 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
+import com.flamyoad.tsukiviewer.core.model.Source
+import com.flamyoad.tsukiviewer.core.network.FetchHistory
+import com.flamyoad.tsukiviewer.core.network.FetchPercentage
+import com.flamyoad.tsukiviewer.core.network.FetchStatus
+import com.flamyoad.tsukiviewer.core.repository.MetadataRepository
import com.flamyoad.tsukiviewer.ui.fetcher.FetcherStatusActivity
import kotlinx.coroutines.*
import java.io.File
@@ -65,7 +69,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/ui/doujinpage/BookmarkGroupDialogListener.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/BookmarkGroupDialogListener.kt
index ab97073..1b6c4a4 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/BookmarkGroupDialogListener.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/doujinpage/BookmarkGroupDialogListener.kt
@@ -1,6 +1,6 @@
package com.flamyoad.tsukiviewer.ui.doujinpage
-import com.flamyoad.tsukiviewer.model.BookmarkGroup
+import com.flamyoad.tsukiviewer.core.model.BookmarkGroup
interface BookmarkGroupDialogListener {
fun onBookmarkGroupTicked(collection: BookmarkGroup)
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..c485cb5 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.model.BookmarkGroup
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.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..5f4f79e 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
@@ -5,11 +5,11 @@ import android.net.Uri
import androidx.core.net.toUri
import androidx.lifecycle.*
import com.flamyoad.tsukiviewer.MyAppPreference
-import com.flamyoad.tsukiviewer.model.BookmarkGroup
-import com.flamyoad.tsukiviewer.model.DoujinDetailsWithTags
-import com.flamyoad.tsukiviewer.model.Source
-import com.flamyoad.tsukiviewer.repository.BookmarkRepository
-import com.flamyoad.tsukiviewer.repository.MetadataRepository
+import com.flamyoad.tsukiviewer.core.model.BookmarkGroup
+import com.flamyoad.tsukiviewer.core.model.DoujinDetailsWithTags
+import com.flamyoad.tsukiviewer.core.model.Source
+import com.flamyoad.tsukiviewer.core.repository.BookmarkRepository
+import com.flamyoad.tsukiviewer.core.repository.MetadataRepository
import com.flamyoad.tsukiviewer.utils.ImageFileFilter
import com.flamyoad.tsukiviewer.utils.WindowsExplorerComparator
import kotlinx.coroutines.Dispatchers
@@ -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..a5ad6d6 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,13 +12,16 @@ 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.model.DoujinDetails
-import com.flamyoad.tsukiviewer.model.DoujinDetailsWithTags
-import com.flamyoad.tsukiviewer.model.Source
-import com.flamyoad.tsukiviewer.network.FetchMetadataService
+import com.flamyoad.tsukiviewer.databinding.FragmentDoujinDetailsBinding
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.model.DoujinDetails
+import com.flamyoad.tsukiviewer.core.model.DoujinDetailsWithTags
+import com.flamyoad.tsukiviewer.core.model.Source
+import com.flamyoad.tsukiviewer.service.FetchMetadataService
import com.flamyoad.tsukiviewer.ui.home.local.DialogSelectSource
import com.flamyoad.tsukiviewer.ui.home.local.SelectSourceListener
import com.flamyoad.tsukiviewer.utils.ActivityHistory
@@ -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..196944d 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.model.Tag
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.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..9ceaf1c 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,25 +1,24 @@
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
-import com.flamyoad.tsukiviewer.model.DoujinDetails
-import com.flamyoad.tsukiviewer.model.EditorHistoryItem
-import com.flamyoad.tsukiviewer.model.Mode
-import com.flamyoad.tsukiviewer.model.Tag
-import com.flamyoad.tsukiviewer.repository.MetadataRepository
+import com.flamyoad.tsukiviewer.core.db.dao.DoujinDetailsDao
+import com.flamyoad.tsukiviewer.core.db.dao.TagDao
+import com.flamyoad.tsukiviewer.core.model.DoujinDetails
+import com.flamyoad.tsukiviewer.core.model.EditorHistoryItem
+import com.flamyoad.tsukiviewer.core.model.Mode
+import com.flamyoad.tsukiviewer.core.model.Tag
+import com.flamyoad.tsukiviewer.core.repository.MetadataRepository
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/fetcher/FetcherStatusActivity.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/fetcher/FetcherStatusActivity.kt
index c47332e..5ed5ec3 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/fetcher/FetcherStatusActivity.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/fetcher/FetcherStatusActivity.kt
@@ -13,7 +13,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.flamyoad.tsukiviewer.R
import com.flamyoad.tsukiviewer.adapter.FetchHistoryAdapter
import com.flamyoad.tsukiviewer.databinding.ActivityFetcherStatusBinding
-import com.flamyoad.tsukiviewer.network.FetchMetadataService
+import com.flamyoad.tsukiviewer.service.FetchMetadataService
class FetcherStatusActivity : AppCompatActivity() {
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..01f93c3 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.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 com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.model.BookmarkGroup
+import com.flamyoad.tsukiviewer.core.model.BookmarkItem
+import com.flamyoad.tsukiviewer.core.model.ViewMode
+import com.flamyoad.tsukiviewer.utils.ui.GridItemDecoration
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..409d4d0 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
@@ -5,10 +5,10 @@ import android.net.Uri
import androidx.core.net.toUri
import androidx.lifecycle.*
import com.flamyoad.tsukiviewer.MyApplication
-import com.flamyoad.tsukiviewer.model.BookmarkGroup
-import com.flamyoad.tsukiviewer.model.BookmarkItem
-import com.flamyoad.tsukiviewer.model.Doujin
-import com.flamyoad.tsukiviewer.repository.BookmarkRepository
+import com.flamyoad.tsukiviewer.core.model.BookmarkGroup
+import com.flamyoad.tsukiviewer.core.model.BookmarkItem
+import com.flamyoad.tsukiviewer.core.model.Doujin
+import com.flamyoad.tsukiviewer.core.repository.BookmarkRepository
import com.flamyoad.tsukiviewer.utils.ImageFileFilter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@@ -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..633603e 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.model.Collection
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.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..270b8df 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,11 +9,10 @@ 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
-import com.flamyoad.tsukiviewer.repository.CollectionRepository
+import com.flamyoad.tsukiviewer.core.db.dao.IncludedPathDao
+import com.flamyoad.tsukiviewer.core.model.*
+import com.flamyoad.tsukiviewer.core.model.Collection
+import com.flamyoad.tsukiviewer.core.repository.CollectionRepository
import com.flamyoad.tsukiviewer.utils.ImageFileFilter
import com.flamyoad.tsukiviewer.utils.extensions.toDoujin
import kotlinx.coroutines.Dispatchers
@@ -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..3fe1f5d 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.model.Collection
-import com.flamyoad.tsukiviewer.model.Tag
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.model.Collection
+import com.flamyoad.tsukiviewer.core.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..b261c03 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,27 +1,24 @@
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
-import com.flamyoad.tsukiviewer.repository.CollectionRepository
-import com.flamyoad.tsukiviewer.repository.TagRepository
+import com.flamyoad.tsukiviewer.core.db.dao.IncludedPathDao
+import com.flamyoad.tsukiviewer.core.model.*
+import com.flamyoad.tsukiviewer.core.model.Collection
+import com.flamyoad.tsukiviewer.core.repository.CollectionRepository
+import com.flamyoad.tsukiviewer.core.repository.TagRepository
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..e6d4a69 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,19 +1,20 @@
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
-import com.flamyoad.tsukiviewer.repository.CollectionRepository
+import com.flamyoad.tsukiviewer.core.model.Collection
+import com.flamyoad.tsukiviewer.core.model.Tag
+import com.flamyoad.tsukiviewer.core.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..8f9a8c2 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.model.BookmarkGroup
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.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..6bff3e9 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,11 +18,13 @@ 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.model.Doujin
-import com.flamyoad.tsukiviewer.model.ViewMode
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.model.Doujin
+import com.flamyoad.tsukiviewer.core.model.ViewMode
import com.flamyoad.tsukiviewer.ui.editor.EditorActivity
import com.flamyoad.tsukiviewer.ui.home.collections.CollectionFragment
import com.flamyoad.tsukiviewer.ui.home.collections.DialogCollectionInfo
@@ -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..1b957fc 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,24 +2,22 @@ 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
-import com.flamyoad.tsukiviewer.model.Doujin
-import com.flamyoad.tsukiviewer.model.Tag
-import com.flamyoad.tsukiviewer.repository.BookmarkRepository
-import com.flamyoad.tsukiviewer.repository.CollectionRepository
+import com.flamyoad.tsukiviewer.core.db.dao.DoujinDetailsDao
+import com.flamyoad.tsukiviewer.core.db.dao.IncludedPathDao
+import com.flamyoad.tsukiviewer.core.model.BookmarkGroup
+import com.flamyoad.tsukiviewer.core.model.Doujin
+import com.flamyoad.tsukiviewer.core.model.Tag
+import com.flamyoad.tsukiviewer.core.repository.BookmarkRepository
+import com.flamyoad.tsukiviewer.core.repository.CollectionRepository
import com.flamyoad.tsukiviewer.utils.ImageFileFilter
import com.flamyoad.tsukiviewer.utils.extensions.toDoujin
import kotlinx.coroutines.Dispatchers
@@ -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/DialogBookmarkItems.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogBookmarkItems.kt
index ece294e..bc31a17 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogBookmarkItems.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogBookmarkItems.kt
@@ -15,7 +15,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.flamyoad.tsukiviewer.R
import com.flamyoad.tsukiviewer.adapter.CollectionPickerAdapter
-import com.flamyoad.tsukiviewer.model.BookmarkGroup
+import com.flamyoad.tsukiviewer.core.model.BookmarkGroup
import com.flamyoad.tsukiviewer.ui.doujinpage.BookmarkGroupDialogListener
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/DialogSelectSource.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogSelectSource.kt
index 9a9544c..4c5dc01 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogSelectSource.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/DialogSelectSource.kt
@@ -11,7 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.flamyoad.tsukiviewer.R
import com.flamyoad.tsukiviewer.adapter.SourceSelectorAdapter
-import com.flamyoad.tsukiviewer.model.Source
+import com.flamyoad.tsukiviewer.core.model.Source
import com.google.android.material.button.MaterialButton
import com.google.android.material.textview.MaterialTextView
import java.util.*
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..250385d 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
@@ -9,22 +9,25 @@ import android.os.IBinder
import androidx.core.net.toUri
import androidx.lifecycle.*
import com.flamyoad.tsukiviewer.MyApplication
-import com.flamyoad.tsukiviewer.model.BookmarkGroup
-import com.flamyoad.tsukiviewer.model.Doujin
-import com.flamyoad.tsukiviewer.model.Source
-import com.flamyoad.tsukiviewer.network.FetchMetadataService
-import com.flamyoad.tsukiviewer.repository.BookmarkRepository
-import com.flamyoad.tsukiviewer.repository.MetadataRepository
+import com.flamyoad.tsukiviewer.core.model.BookmarkGroup
+import com.flamyoad.tsukiviewer.core.model.Doujin
+import com.flamyoad.tsukiviewer.core.model.Source
+import com.flamyoad.tsukiviewer.service.FetchMetadataService
+import com.flamyoad.tsukiviewer.core.repository.BookmarkRepository
+import com.flamyoad.tsukiviewer.core.repository.MetadataRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
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..fb165e9 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,12 +18,14 @@ 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.model.Doujin
-import com.flamyoad.tsukiviewer.model.Source
-import com.flamyoad.tsukiviewer.model.ViewMode
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.model.Doujin
+import com.flamyoad.tsukiviewer.core.model.Source
+import com.flamyoad.tsukiviewer.core.model.ViewMode
import com.flamyoad.tsukiviewer.ui.editor.EditorActivity
import com.flamyoad.tsukiviewer.ui.home.collections.doujins.CollectionDoujinsActivity
import com.flamyoad.tsukiviewer.ui.search.SearchActivity
@@ -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/local/SelectSourceListener.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/SelectSourceListener.kt
index d76fda5..9acf113 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/SelectSourceListener.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/local/SelectSourceListener.kt
@@ -1,6 +1,6 @@
package com.flamyoad.tsukiviewer.ui.home.local
-import com.flamyoad.tsukiviewer.model.Source
+import com.flamyoad.tsukiviewer.core.model.Source
import java.util.*
interface SelectSourceListener {
diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DialogDeleteTag.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DialogDeleteTag.kt
index 10c6df1..430c041 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DialogDeleteTag.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DialogDeleteTag.kt
@@ -6,7 +6,7 @@ import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels
-import com.flamyoad.tsukiviewer.model.Tag
+import com.flamyoad.tsukiviewer.core.model.Tag
class DialogDeleteTag: DialogFragment() {
diff --git a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DialogSortTag.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DialogSortTag.kt
index 45a976c..403a675 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DialogSortTag.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/DialogSortTag.kt
@@ -5,7 +5,7 @@ import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels
-import com.flamyoad.tsukiviewer.model.TagSortingMode
+import com.flamyoad.tsukiviewer.core.model.TagSortingMode
private const val CHOSEN_MODE_STRING = "CHOSEN_MODE_STRING"
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..2920fdf 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.model.TagType
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.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..8a75a31 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,22 +1,19 @@
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
-import com.flamyoad.tsukiviewer.model.TagSortingMode
-import com.flamyoad.tsukiviewer.model.TagType
+import com.flamyoad.tsukiviewer.core.db.dao.DoujinTagsDao
+import com.flamyoad.tsukiviewer.core.db.dao.TagDao
+import com.flamyoad.tsukiviewer.core.model.Tag
+import com.flamyoad.tsukiviewer.core.model.TagSortingMode
+import com.flamyoad.tsukiviewer.core.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..be3b531 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,28 +11,39 @@ 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.model.Doujin
-import com.flamyoad.tsukiviewer.model.Tag
-import com.flamyoad.tsukiviewer.model.TagType
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.model.Doujin
+import com.flamyoad.tsukiviewer.core.model.Tag
+import com.flamyoad.tsukiviewer.core.model.TagType
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/home/tags/TagFragmentAdapter.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/TagFragmentAdapter.kt
index df35f0a..25a5036 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/TagFragmentAdapter.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/home/tags/TagFragmentAdapter.kt
@@ -3,7 +3,7 @@ package com.flamyoad.tsukiviewer.ui.home.tags
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
-import com.flamyoad.tsukiviewer.model.TagType
+import com.flamyoad.tsukiviewer.core.model.TagType
class TagFragmentAdapter(activity: FragmentActivity, private val tagList: List) :
FragmentStateAdapter(activity) {
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..7c4311e 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.model.RecentTab
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.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..97535a9 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,25 +4,26 @@ 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.model.RecentTab
+import com.flamyoad.tsukiviewer.core.db.dao.RecentTabDao
+import com.flamyoad.tsukiviewer.core.model.RecentTab
import com.flamyoad.tsukiviewer.utils.FileUtils
import com.flamyoad.tsukiviewer.utils.extensions.imageExtensions
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/RecentTabTouchHelperCallback.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/recents/RecentTabTouchHelperCallback.kt
index ec50862..afa1cb5 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/recents/RecentTabTouchHelperCallback.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/recents/RecentTabTouchHelperCallback.kt
@@ -6,7 +6,7 @@ import android.view.MotionEvent
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.flamyoad.tsukiviewer.adapter.RecentTabsAdapter
-import com.flamyoad.tsukiviewer.model.RecentTab
+import com.flamyoad.tsukiviewer.core.model.RecentTab
class RecentTabTouchHelperCallback(
private val adapter: RecentTabsAdapter,
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..2576b65 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.model.RecentTab
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.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..c31f81c 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 com.flamyoad.tsukiviewer.core.db.dao.RecentTabDao
+import com.flamyoad.tsukiviewer.core.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..1523d8d 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.model.RecentTab
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.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/ReaderTabFragmentAdapter.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/tabs/ReaderTabFragmentAdapter.kt
index 438d5fa..3d2238f 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/tabs/ReaderTabFragmentAdapter.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/reader/tabs/ReaderTabFragmentAdapter.kt
@@ -3,7 +3,7 @@ package com.flamyoad.tsukiviewer.ui.reader.tabs
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
-import com.flamyoad.tsukiviewer.model.RecentTab
+import com.flamyoad.tsukiviewer.core.model.RecentTab
class ReaderTabFragmentAdapter(activity: FragmentActivity): FragmentStateAdapter(activity) {
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..9ccb72b 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,8 +3,8 @@ 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.model.RecentTab
+import com.flamyoad.tsukiviewer.core.db.dao.RecentTabDao
+import com.flamyoad.tsukiviewer.core.model.RecentTab
import com.flamyoad.tsukiviewer.ui.reader.ReaderMode
import com.flamyoad.tsukiviewer.ui.reader.VolumeButtonScrollDirection
import com.flamyoad.tsukiviewer.ui.reader.VolumeButtonScrollMode
@@ -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..ab07fe2 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.model.BookmarkGroup
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.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..26ae260 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.model.SearchHistory
-import com.flamyoad.tsukiviewer.model.Tag
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.model.SearchHistory
+import com.flamyoad.tsukiviewer.core.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..7894ff4 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,11 +18,13 @@ 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.model.Doujin
-import com.flamyoad.tsukiviewer.model.ViewMode
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.model.Doujin
+import com.flamyoad.tsukiviewer.core.model.ViewMode
import com.flamyoad.tsukiviewer.ui.editor.EditorActivity
import com.flamyoad.tsukiviewer.utils.ActivityHistory
import com.flamyoad.tsukiviewer.utils.ActivityStackUtils
@@ -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..1493c79 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,33 +1,30 @@
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
-import com.flamyoad.tsukiviewer.model.IncludedPath
-import com.flamyoad.tsukiviewer.repository.BookmarkRepository
-import com.flamyoad.tsukiviewer.repository.DoujinRepository
+import com.flamyoad.tsukiviewer.core.db.dao.IncludedPathDao
+import com.flamyoad.tsukiviewer.core.model.BookmarkGroup
+import com.flamyoad.tsukiviewer.core.model.Doujin
+import com.flamyoad.tsukiviewer.core.model.IncludedPath
+import com.flamyoad.tsukiviewer.core.repository.BookmarkRepository
+import com.flamyoad.tsukiviewer.core.repository.DoujinRepository
import kotlinx.coroutines.*
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..d13e2c0 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 com.flamyoad.tsukiviewer.core.model.SearchHistory
+import com.flamyoad.tsukiviewer.core.model.Tag
+import com.flamyoad.tsukiviewer.core.repository.SearchHistoryRepository
+import com.flamyoad.tsukiviewer.core.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/search/TagSelectedListener.kt b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/TagSelectedListener.kt
index 74cc6f7..a4e32f7 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/TagSelectedListener.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/ui/search/TagSelectedListener.kt
@@ -1,6 +1,6 @@
package com.flamyoad.tsukiviewer.ui.search
-import com.flamyoad.tsukiviewer.model.Tag
+import com.flamyoad.tsukiviewer.core.model.Tag
interface TagSelectedListener {
fun onTagSelected(tag: Tag)
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..d6b3ea6 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,30 +4,33 @@ 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
-import com.flamyoad.tsukiviewer.db.AppDatabase
-import com.flamyoad.tsukiviewer.db.dao.DoujinDetailsDao
-import com.flamyoad.tsukiviewer.db.dao.DoujinTagsDao
-import com.flamyoad.tsukiviewer.db.dao.SearchHistoryDao
-import com.flamyoad.tsukiviewer.db.dao.TagDao
+import com.flamyoad.tsukiviewer.core.db.AppDatabase
+import com.flamyoad.tsukiviewer.core.db.dao.DoujinDetailsDao
+import com.flamyoad.tsukiviewer.core.db.dao.DoujinTagsDao
+import com.flamyoad.tsukiviewer.core.db.dao.SearchHistoryDao
+import com.flamyoad.tsukiviewer.core.db.dao.TagDao
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..f67bc8d 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.model.IncludedPath
+import com.flamyoad.tsukiviewer.di.ViewModelFactory
+import com.flamyoad.tsukiviewer.core.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..28fae9b 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 com.flamyoad.tsukiviewer.core.db.dao.IncludedPathDao
+import com.flamyoad.tsukiviewer.core.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/app/src/main/java/com/flamyoad/tsukiviewer/utils/extensions/FileExtensions.kt b/app/src/main/java/com/flamyoad/tsukiviewer/utils/extensions/FileExtensions.kt
index b9cc51a..61199a4 100644
--- a/app/src/main/java/com/flamyoad/tsukiviewer/utils/extensions/FileExtensions.kt
+++ b/app/src/main/java/com/flamyoad/tsukiviewer/utils/extensions/FileExtensions.kt
@@ -1,7 +1,7 @@
package com.flamyoad.tsukiviewer.utils.extensions
import androidx.core.net.toUri
-import com.flamyoad.tsukiviewer.model.Doujin
+import com.flamyoad.tsukiviewer.core.model.Doujin
import com.flamyoad.tsukiviewer.utils.ImageFileFilter
import java.io.File
diff --git a/core/build.gradle b/core/build.gradle
new file mode 100644
index 0000000..08bbd89
--- /dev/null
+++ b/core/build.gradle
@@ -0,0 +1,87 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-kapt'
+apply plugin: 'kotlin-parcelize'
+
+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 & OkHttp
+ 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'
+ api 'com.squareup.okhttp3:logging-interceptor:4.9.0'
+
+ 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)
diff --git a/gradlew b/gradlew
old mode 100644
new mode 100755
diff --git a/settings.gradle b/settings.gradle
index df9cca2..4cad682 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,3 @@
rootProject.name='TsukiViewer'
include ':app'
+include ':core'
|