Save bookmark images
This commit is contained in:
@@ -39,6 +39,7 @@ import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
|||||||
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||||
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
|
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
|
import org.koitharu.kotatsu.reader.ui.PageSaveHelper
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
@@ -52,10 +53,19 @@ class AllBookmarksFragment :
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var settings: AppSettings
|
lateinit var settings: AppSettings
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var pageSaveHelperFactory: PageSaveHelper.Factory
|
||||||
|
|
||||||
|
private lateinit var pageSaveHelper: PageSaveHelper
|
||||||
private val viewModel by viewModels<AllBookmarksViewModel>()
|
private val viewModel by viewModels<AllBookmarksViewModel>()
|
||||||
private var bookmarksAdapter: BookmarksAdapter? = null
|
private var bookmarksAdapter: BookmarksAdapter? = null
|
||||||
private var selectionController: ListSelectionController? = null
|
private var selectionController: ListSelectionController? = null
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
pageSaveHelper = pageSaveHelperFactory.create(this)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateViewBinding(
|
override fun onCreateViewBinding(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
@@ -179,6 +189,12 @@ class AllBookmarksFragment :
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.action_save -> {
|
||||||
|
viewModel.savePages(pageSaveHelper, selectionController?.snapshot() ?: return false)
|
||||||
|
mode?.finish()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.koitharu.kotatsu.list.ui.model.ListModel
|
|||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
|
import org.koitharu.kotatsu.reader.ui.PageSaveHelper
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@@ -56,6 +57,23 @@ class AllBookmarksViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun savePages(pageSaveHelper: PageSaveHelper, ids: Set<Long>) {
|
||||||
|
launchLoadingJob(Dispatchers.Default) {
|
||||||
|
val tasks = content.value.mapNotNull {
|
||||||
|
if (it !is Bookmark || it.pageId !in ids) return@mapNotNull null
|
||||||
|
PageSaveHelper.Task(
|
||||||
|
manga = it.manga,
|
||||||
|
chapterId = it.chapterId,
|
||||||
|
pageNumber = it.page + 1,
|
||||||
|
page = it.toMangaPage(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val dest = pageSaveHelper.save(tasks)
|
||||||
|
val msg = if (dest.size == 1) R.string.page_saved else R.string.pages_saved
|
||||||
|
onActionDone.call(ReversibleAction(msg, null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun mapList(data: Map<Manga, List<Bookmark>>): List<ListModel> {
|
private fun mapList(data: Map<Manga, List<Bookmark>>): List<ListModel> {
|
||||||
val result = ArrayList<ListModel>(data.values.sumOf { it.size + 1 })
|
val result = ArrayList<ListModel>(data.values.sumOf { it.size + 1 })
|
||||||
for ((manga, bookmarks) in data) {
|
for ((manga, bookmarks) in data) {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import org.koitharu.kotatsu.details.ui.pager.ChaptersPagesViewModel
|
|||||||
import org.koitharu.kotatsu.list.ui.GridSpanResolver
|
import org.koitharu.kotatsu.list.ui.GridSpanResolver
|
||||||
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||||
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
|
||||||
|
import org.koitharu.kotatsu.reader.ui.PageSaveHelper
|
||||||
import org.koitharu.kotatsu.reader.ui.ReaderNavigationCallback
|
import org.koitharu.kotatsu.reader.ui.ReaderNavigationCallback
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -54,9 +55,13 @@ class BookmarksFragment : BaseFragment<FragmentMangaBookmarksBinding>(),
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var settings: AppSettings
|
lateinit var settings: AppSettings
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var pageSaveHelperFactory: PageSaveHelper.Factory
|
||||||
|
|
||||||
override val recyclerView: RecyclerView?
|
override val recyclerView: RecyclerView?
|
||||||
get() = viewBinding?.recyclerView
|
get() = viewBinding?.recyclerView
|
||||||
|
|
||||||
|
private lateinit var pageSaveHelper: PageSaveHelper
|
||||||
private var bookmarksAdapter: BookmarksAdapter? = null
|
private var bookmarksAdapter: BookmarksAdapter? = null
|
||||||
private var spanResolver: GridSpanResolver? = null
|
private var spanResolver: GridSpanResolver? = null
|
||||||
private var selectionController: ListSelectionController? = null
|
private var selectionController: ListSelectionController? = null
|
||||||
@@ -68,6 +73,7 @@ class BookmarksFragment : BaseFragment<FragmentMangaBookmarksBinding>(),
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
pageSaveHelper = pageSaveHelperFactory.create(this)
|
||||||
activityViewModel.mangaDetails.observe(this, viewModel)
|
activityViewModel.mangaDetails.observe(this, viewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,6 +186,12 @@ class BookmarksFragment : BaseFragment<FragmentMangaBookmarksBinding>(),
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.action_save -> {
|
||||||
|
viewModel.savePages(pageSaveHelper, selectionController?.snapshot() ?: return false)
|
||||||
|
mode?.finish()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,12 +21,14 @@ import org.koitharu.kotatsu.core.ui.BaseViewModel
|
|||||||
import org.koitharu.kotatsu.core.ui.util.ReversibleAction
|
import org.koitharu.kotatsu.core.ui.util.ReversibleAction
|
||||||
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
||||||
import org.koitharu.kotatsu.core.util.ext.call
|
import org.koitharu.kotatsu.core.util.ext.call
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.requireValue
|
||||||
import org.koitharu.kotatsu.details.data.MangaDetails
|
import org.koitharu.kotatsu.details.data.MangaDetails
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
|
import org.koitharu.kotatsu.reader.ui.PageSaveHelper
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@@ -62,6 +64,24 @@ class BookmarksViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun savePages(pageSaveHelper: PageSaveHelper, ids: Set<Long>) {
|
||||||
|
launchLoadingJob(Dispatchers.Default) {
|
||||||
|
val m = manga.requireValue()
|
||||||
|
val tasks = content.value.mapNotNull {
|
||||||
|
if (it !is Bookmark || it.pageId !in ids) return@mapNotNull null
|
||||||
|
PageSaveHelper.Task(
|
||||||
|
manga = m,
|
||||||
|
chapterId = it.chapterId,
|
||||||
|
pageNumber = it.page + 1,
|
||||||
|
page = it.toMangaPage(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val dest = pageSaveHelper.save(tasks)
|
||||||
|
val msg = if (dest.size == 1) R.string.page_saved else R.string.pages_saved
|
||||||
|
onActionDone.call(ReversibleAction(msg, null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun mapList(manga: Manga, bookmarks: List<Bookmark>): List<ListModel>? {
|
private fun mapList(manga: Manga, bookmarks: List<Bookmark>): List<ListModel>? {
|
||||||
val chapters = manga.chapters ?: return null
|
val chapters = manga.chapters ?: return null
|
||||||
val bookmarksMap = bookmarks.groupBy { it.chapterId }
|
val bookmarksMap = bookmarks.groupBy { it.chapterId }
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class PagesViewModel @Inject constructor(
|
|||||||
val tasks = pages.map {
|
val tasks = pages.map {
|
||||||
PageSaveHelper.Task(
|
PageSaveHelper.Task(
|
||||||
manga = manga,
|
manga = manga,
|
||||||
chapter = manga.requireChapterById(it.chapterId),
|
chapterId = it.chapterId,
|
||||||
pageNumber = it.index + 1,
|
pageNumber = it.index + 1,
|
||||||
page = it.toMangaPage(),
|
page = it.toMangaPage(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -178,15 +178,17 @@ class PageSaveHelper @AssistedInject constructor(
|
|||||||
|
|
||||||
data class Task(
|
data class Task(
|
||||||
val manga: Manga,
|
val manga: Manga,
|
||||||
val chapter: MangaChapter,
|
val chapterId: Long,
|
||||||
val pageNumber: Int,
|
val pageNumber: Int,
|
||||||
val page: MangaPage,
|
val page: MangaPage,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getFileBaseName() = buildString {
|
fun getFileBaseName() = buildString {
|
||||||
append(manga.title.toFileNameSafe().take(MAX_BASENAME_LENGTH))
|
append(manga.title.toFileNameSafe().take(MAX_BASENAME_LENGTH))
|
||||||
append('-')
|
manga.findChapterById(chapterId)?.let { chapter ->
|
||||||
append(chapter.number)
|
append('-')
|
||||||
|
append(chapter.number)
|
||||||
|
}
|
||||||
append('-')
|
append('-')
|
||||||
append(pageNumber)
|
append(pageNumber)
|
||||||
append('_')
|
append('_')
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ class ReaderViewModel @Inject constructor(
|
|||||||
val currentManga = manga.requireValue()
|
val currentManga = manga.requireValue()
|
||||||
val task = PageSaveHelper.Task(
|
val task = PageSaveHelper.Task(
|
||||||
manga = currentManga,
|
manga = currentManga,
|
||||||
chapter = currentManga.requireChapterById(state.chapterId),
|
chapterId = state.chapterId,
|
||||||
pageNumber = state.page + 1,
|
pageNumber = state.page + 1,
|
||||||
page = checkNotNull(getCurrentPage()) { "Cannot find current page" },
|
page = checkNotNull(getCurrentPage()) { "Cannot find current page" },
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,4 +9,10 @@
|
|||||||
android:title="@string/remove"
|
android:title="@string/remove"
|
||||||
app:showAsAction="ifRoom|withText" />
|
app:showAsAction="ifRoom|withText" />
|
||||||
|
|
||||||
</menu>
|
<item
|
||||||
|
android:id="@+id/action_save"
|
||||||
|
android:icon="@drawable/ic_save"
|
||||||
|
android:title="@string/save"
|
||||||
|
app:showAsAction="ifRoom|withText" />
|
||||||
|
|
||||||
|
</menu>
|
||||||
|
|||||||
Reference in New Issue
Block a user