mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-14 17:05:07 +01:00
Running kotlinter
This commit is contained in:
parent
7914b26488
commit
fccd3a0ddb
@ -25,7 +25,6 @@ import uy.kohesive.injekt.api.get
|
|||||||
class AppModule(val app: Application) : InjektModule {
|
class AppModule(val app: Application) : InjektModule {
|
||||||
|
|
||||||
override fun InjektRegistrar.registerInjectables() {
|
override fun InjektRegistrar.registerInjectables() {
|
||||||
|
|
||||||
addSingleton(app)
|
addSingleton(app)
|
||||||
|
|
||||||
addSingletonFactory { PreferencesHelper(app) }
|
addSingletonFactory { PreferencesHelper(app) }
|
||||||
|
@ -70,8 +70,9 @@ object Migrations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (oldVersion < 54)
|
if (oldVersion < 54) {
|
||||||
DownloadProvider(context).renameChapters()
|
DownloadProvider(context).renameChapters()
|
||||||
|
}
|
||||||
if (oldVersion < 62) {
|
if (oldVersion < 62) {
|
||||||
LibraryPresenter.updateDB()
|
LibraryPresenter.updateDB()
|
||||||
// Restore jobs after migrating from Evernote's job scheduler to WorkManager.
|
// Restore jobs after migrating from Evernote's job scheduler to WorkManager.
|
||||||
|
@ -79,8 +79,9 @@ class ChapterCache(private val context: Context) {
|
|||||||
*/
|
*/
|
||||||
fun removeFileFromCache(file: String): Boolean {
|
fun removeFileFromCache(file: String): Boolean {
|
||||||
// Make sure we don't delete the journal file (keeps track of cache).
|
// Make sure we don't delete the journal file (keeps track of cache).
|
||||||
if (file == "journal" || file.startsWith("journal."))
|
if (file == "journal" || file.startsWith("journal.")) {
|
||||||
return false
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Remove the extension from the file to get the key of the cache
|
// Remove the extension from the file to get the key of the cache
|
||||||
|
@ -41,9 +41,9 @@ class CategoryPutResolver : DefaultPutResolver<Category>() {
|
|||||||
put(COL_NAME, obj.name)
|
put(COL_NAME, obj.name)
|
||||||
put(COL_ORDER, obj.order)
|
put(COL_ORDER, obj.order)
|
||||||
put(COL_FLAGS, obj.flags)
|
put(COL_FLAGS, obj.flags)
|
||||||
if (obj.mangaSort != null)
|
if (obj.mangaSort != null) {
|
||||||
put(COL_MANGA_ORDER, obj.mangaSort.toString())
|
put(COL_MANGA_ORDER, obj.mangaSort.toString())
|
||||||
else {
|
} else {
|
||||||
val orderString = obj.mangaOrder.joinToString("/")
|
val orderString = obj.mangaOrder.joinToString("/")
|
||||||
put(COL_MANGA_ORDER, orderString)
|
put(COL_MANGA_ORDER, orderString)
|
||||||
}
|
}
|
||||||
|
@ -105,17 +105,17 @@ interface Manga : SManga {
|
|||||||
{ tag ->
|
{ tag ->
|
||||||
tag == "long strip" || tag == "manhwa" || tag.contains("webtoon")
|
tag == "long strip" || tag == "manhwa" || tag.contains("webtoon")
|
||||||
} == true || isWebtoonSource(sourceName)
|
} == true || isWebtoonSource(sourceName)
|
||||||
)
|
) {
|
||||||
ReaderActivity.WEBTOON
|
ReaderActivity.WEBTOON
|
||||||
else if (currentTags?.any
|
} else if (currentTags?.any
|
||||||
{ tag ->
|
{ tag ->
|
||||||
tag == "chinese" || tag == "manhua" ||
|
tag == "chinese" || tag == "manhua" ||
|
||||||
tag.startsWith("english") || tag == "comic"
|
tag.startsWith("english") || tag == "comic"
|
||||||
} == true || (isComicSource(sourceName) && !sourceName.contains("tapas", true)) ||
|
} == true || (isComicSource(sourceName) && !sourceName.contains("tapas", true)) ||
|
||||||
sourceName.contains("manhua", true)
|
sourceName.contains("manhua", true)
|
||||||
)
|
) {
|
||||||
ReaderActivity.LEFT_TO_RIGHT
|
ReaderActivity.LEFT_TO_RIGHT
|
||||||
else 0
|
} else 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isMangaTag(tag: String): Boolean {
|
fun isMangaTag(tag: String): Boolean {
|
||||||
@ -127,7 +127,7 @@ interface Manga : SManga {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun isManhwaTag(tag: String): Boolean {
|
fun isManhwaTag(tag: String): Boolean {
|
||||||
return tag in listOf("long strip", "manhwa", "манхва", "kr") || tag.startsWith("korean")
|
return tag in listOf("long strip", "manhwa", "манхва", "kr") || tag.startsWith("korean")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isComicTag(tag: String): Boolean {
|
fun isComicTag(tag: String): Boolean {
|
||||||
|
@ -90,7 +90,6 @@ class DownloadCache(
|
|||||||
checkRenew()
|
checkRenew()
|
||||||
|
|
||||||
if (forceCheckFolder) {
|
if (forceCheckFolder) {
|
||||||
|
|
||||||
val source = sourceManager.get(manga.source) ?: return 0
|
val source = sourceManager.get(manga.source) ?: return 0
|
||||||
val mangaDir = provider.findMangaDir(manga, source)
|
val mangaDir = provider.findMangaDir(manga, source)
|
||||||
|
|
||||||
@ -173,7 +172,6 @@ class DownloadCache(
|
|||||||
*/
|
*/
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun addChapter(chapterDirName: String, mangaUniFile: UniFile, manga: Manga) {
|
fun addChapter(chapterDirName: String, mangaUniFile: UniFile, manga: Manga) {
|
||||||
|
|
||||||
val id = manga.id ?: return
|
val id = manga.id ?: return
|
||||||
val files = mangaFiles[id]
|
val files = mangaFiles[id]
|
||||||
if (files == null) {
|
if (files == null) {
|
||||||
|
@ -110,10 +110,11 @@ class DownloadManager(val context: Context) {
|
|||||||
queue.add(0, download)
|
queue.add(0, download)
|
||||||
reorderQueue(queue)
|
reorderQueue(queue)
|
||||||
if (isPaused()) {
|
if (isPaused()) {
|
||||||
if (DownloadService.isRunning(context))
|
if (DownloadService.isRunning(context)) {
|
||||||
downloader.start()
|
downloader.start()
|
||||||
else
|
} else {
|
||||||
DownloadService.start(context)
|
DownloadService.start(context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +55,9 @@ internal class DownloadNotifier(private val context: Context) {
|
|||||||
* Clear old actions if they exist.
|
* Clear old actions if they exist.
|
||||||
*/
|
*/
|
||||||
private fun clearActions() = with(notification) {
|
private fun clearActions() = with(notification) {
|
||||||
if (!mActions.isEmpty())
|
if (!mActions.isEmpty()) {
|
||||||
mActions.clear()
|
mActions.clear()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -201,10 +201,11 @@ class DownloadService : Service() {
|
|||||||
*/
|
*/
|
||||||
private fun listenDownloaderState() {
|
private fun listenDownloaderState() {
|
||||||
subscriptions += downloadManager.runningRelay.subscribe { running ->
|
subscriptions += downloadManager.runningRelay.subscribe { running ->
|
||||||
if (running)
|
if (running) {
|
||||||
wakeLock.acquireIfNeeded()
|
wakeLock.acquireIfNeeded()
|
||||||
else
|
} else {
|
||||||
wakeLock.releaseIfNeeded()
|
wakeLock.releaseIfNeeded()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,7 +469,6 @@ class Downloader(
|
|||||||
tmpDir: UniFile,
|
tmpDir: UniFile,
|
||||||
dirname: String
|
dirname: String
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// Ensure that the chapter folder has all the images.
|
// Ensure that the chapter folder has all the images.
|
||||||
val downloadedImages = tmpDir.listFiles().orEmpty().filterNot { it.name!!.endsWith(".tmp") }
|
val downloadedImages = tmpDir.listFiles().orEmpty().filterNot { it.name!!.endsWith(".tmp") }
|
||||||
|
|
||||||
|
@ -11,11 +11,14 @@ class Download(val source: HttpSource, val manga: Manga, val chapter: Chapter) {
|
|||||||
|
|
||||||
var pages: List<Page>? = null
|
var pages: List<Page>? = null
|
||||||
|
|
||||||
@Volatile @Transient var totalProgress: Int = 0
|
@Volatile @Transient
|
||||||
|
var totalProgress: Int = 0
|
||||||
|
|
||||||
@Volatile @Transient var downloadedImages: Int = 0
|
@Volatile @Transient
|
||||||
|
var downloadedImages: Int = 0
|
||||||
|
|
||||||
@Volatile @Transient var status: Int = 0
|
@Volatile @Transient
|
||||||
|
var status: Int = 0
|
||||||
set(status) {
|
set(status) {
|
||||||
field = status
|
field = status
|
||||||
statusSubject?.onNext(this)
|
statusSubject?.onNext(this)
|
||||||
|
@ -37,8 +37,9 @@ class DownloadQueue(
|
|||||||
store.remove(download)
|
store.remove(download)
|
||||||
download.setStatusSubject(null)
|
download.setStatusSubject(null)
|
||||||
download.setStatusCallback(null)
|
download.setStatusCallback(null)
|
||||||
if (download.status == Download.DOWNLOADING || download.status == Download.QUEUE)
|
if (download.status == Download.DOWNLOADING || download.status == Download.QUEUE) {
|
||||||
download.status = Download.NOT_DOWNLOADED
|
download.status = Download.NOT_DOWNLOADED
|
||||||
|
}
|
||||||
downloadListeners.forEach { it.updateDownload(download) }
|
downloadListeners.forEach { it.updateDownload(download) }
|
||||||
if (removed) {
|
if (removed) {
|
||||||
updatedRelay.call(Unit)
|
updatedRelay.call(Unit)
|
||||||
@ -65,8 +66,9 @@ class DownloadQueue(
|
|||||||
queue.forEach { download ->
|
queue.forEach { download ->
|
||||||
download.setStatusSubject(null)
|
download.setStatusSubject(null)
|
||||||
download.setStatusCallback(null)
|
download.setStatusCallback(null)
|
||||||
if (download.status == Download.DOWNLOADING || download.status == Download.QUEUE)
|
if (download.status == Download.DOWNLOADING || download.status == Download.QUEUE) {
|
||||||
download.status = Download.NOT_DOWNLOADED
|
download.status = Download.NOT_DOWNLOADED
|
||||||
|
}
|
||||||
downloadListeners.forEach { it.updateDownload(download) }
|
downloadListeners.forEach { it.updateDownload(download) }
|
||||||
}
|
}
|
||||||
queue.clear()
|
queue.clear()
|
||||||
@ -85,11 +87,12 @@ class DownloadQueue(
|
|||||||
|
|
||||||
private fun setPagesFor(download: Download) {
|
private fun setPagesFor(download: Download) {
|
||||||
if (download.status == Download.DOWNLOADING) {
|
if (download.status == Download.DOWNLOADING) {
|
||||||
if (download.pages != null)
|
if (download.pages != null) {
|
||||||
for (page in download.pages!!)
|
for (page in download.pages!!)
|
||||||
page.setStatusCallback {
|
page.setStatusCallback {
|
||||||
callListeners(download)
|
callListeners(download)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
downloadListeners.forEach { it.updateDownload(download) }
|
downloadListeners.forEach { it.updateDownload(download) }
|
||||||
} else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) {
|
} else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) {
|
||||||
setPagesSubject(download.pages, null)
|
setPagesSubject(download.pages, null)
|
||||||
|
@ -31,10 +31,11 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||||||
if (interval > 0) {
|
if (interval > 0) {
|
||||||
val restrictions = preferences.libraryUpdateRestriction()!!
|
val restrictions = preferences.libraryUpdateRestriction()!!
|
||||||
val acRestriction = "ac" in restrictions
|
val acRestriction = "ac" in restrictions
|
||||||
val wifiRestriction = if ("wifi" in restrictions)
|
val wifiRestriction = if ("wifi" in restrictions) {
|
||||||
NetworkType.UNMETERED
|
NetworkType.UNMETERED
|
||||||
else
|
} else {
|
||||||
NetworkType.CONNECTED
|
NetworkType.CONNECTED
|
||||||
|
}
|
||||||
|
|
||||||
val constraints = Constraints.Builder()
|
val constraints = Constraints.Builder()
|
||||||
.setRequiredNetworkType(wifiRestriction)
|
.setRequiredNetworkType(wifiRestriction)
|
||||||
|
@ -195,7 +195,6 @@ class LibraryUpdateNotifier(private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NotificationManagerCompat.from(context).apply {
|
NotificationManagerCompat.from(context).apply {
|
||||||
|
|
||||||
notify(
|
notify(
|
||||||
Notifications.ID_NEW_CHAPTERS,
|
Notifications.ID_NEW_CHAPTERS,
|
||||||
context.notification(Notifications.CHANNEL_NEW_CHAPTERS) {
|
context.notification(Notifications.CHANNEL_NEW_CHAPTERS) {
|
||||||
|
@ -114,7 +114,9 @@ class LibraryUpdateService(
|
|||||||
enum class Target {
|
enum class Target {
|
||||||
|
|
||||||
CHAPTERS, // Manga chapters
|
CHAPTERS, // Manga chapters
|
||||||
|
|
||||||
DETAILS, // Manga metadata
|
DETAILS, // Manga metadata
|
||||||
|
|
||||||
TRACKING // Tracking metadata
|
TRACKING // Tracking metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,8 +174,9 @@ class LibraryUpdateService(
|
|||||||
*/
|
*/
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
job?.cancel()
|
job?.cancel()
|
||||||
if (instance == this)
|
if (instance == this) {
|
||||||
instance = null
|
instance = null
|
||||||
|
}
|
||||||
if (wakeLock.isHeld) {
|
if (wakeLock.isHeld) {
|
||||||
wakeLock.release()
|
wakeLock.release()
|
||||||
}
|
}
|
||||||
@ -380,47 +383,47 @@ class LibraryUpdateService(
|
|||||||
shouldDownload: Boolean
|
shouldDownload: Boolean
|
||||||
):
|
):
|
||||||
Boolean {
|
Boolean {
|
||||||
try {
|
try {
|
||||||
var hasDownloads = false
|
var hasDownloads = false
|
||||||
if (job?.isCancelled == true) {
|
if (job?.isCancelled == true) {
|
||||||
return false
|
|
||||||
}
|
|
||||||
notifier.showProgressNotification(manga, progress, mangaToUpdate.size)
|
|
||||||
val source = sourceManager.get(manga.source) as? HttpSource ?: return false
|
|
||||||
val fetchedChapters = withContext(Dispatchers.IO) {
|
|
||||||
source.fetchChapterList(manga).toBlocking().single()
|
|
||||||
} ?: emptyList()
|
|
||||||
if (fetchedChapters.isNotEmpty()) {
|
|
||||||
val newChapters = syncChaptersWithSource(db, fetchedChapters, manga, source)
|
|
||||||
if (newChapters.first.isNotEmpty()) {
|
|
||||||
if (shouldDownload) {
|
|
||||||
downloadChapters(manga, newChapters.first.sortedBy { it.chapter_number })
|
|
||||||
hasDownloads = true
|
|
||||||
}
|
|
||||||
newUpdates[manga] =
|
|
||||||
newChapters.first.sortedBy { it.chapter_number }.toTypedArray()
|
|
||||||
}
|
|
||||||
if (deleteRemoved && newChapters.second.isNotEmpty()) {
|
|
||||||
val removedChapters = newChapters.second.filter {
|
|
||||||
downloadManager.isChapterDownloaded(it, manga)
|
|
||||||
}
|
|
||||||
if (removedChapters.isNotEmpty()) {
|
|
||||||
downloadManager.deleteChapters(removedChapters, manga, source)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (newChapters.first.size + newChapters.second.size > 0) listener?.onUpdateManga(
|
|
||||||
manga
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return hasDownloads
|
|
||||||
} catch (e: Exception) {
|
|
||||||
if (e !is CancellationException) {
|
|
||||||
failedUpdates[manga] = e.message
|
|
||||||
Timber.e("Failed updating: ${manga.title}: $e")
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
notifier.showProgressNotification(manga, progress, mangaToUpdate.size)
|
||||||
|
val source = sourceManager.get(manga.source) as? HttpSource ?: return false
|
||||||
|
val fetchedChapters = withContext(Dispatchers.IO) {
|
||||||
|
source.fetchChapterList(manga).toBlocking().single()
|
||||||
|
} ?: emptyList()
|
||||||
|
if (fetchedChapters.isNotEmpty()) {
|
||||||
|
val newChapters = syncChaptersWithSource(db, fetchedChapters, manga, source)
|
||||||
|
if (newChapters.first.isNotEmpty()) {
|
||||||
|
if (shouldDownload) {
|
||||||
|
downloadChapters(manga, newChapters.first.sortedBy { it.chapter_number })
|
||||||
|
hasDownloads = true
|
||||||
|
}
|
||||||
|
newUpdates[manga] =
|
||||||
|
newChapters.first.sortedBy { it.chapter_number }.toTypedArray()
|
||||||
|
}
|
||||||
|
if (deleteRemoved && newChapters.second.isNotEmpty()) {
|
||||||
|
val removedChapters = newChapters.second.filter {
|
||||||
|
downloadManager.isChapterDownloaded(it, manga)
|
||||||
|
}
|
||||||
|
if (removedChapters.isNotEmpty()) {
|
||||||
|
downloadManager.deleteChapters(removedChapters, manga, source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newChapters.first.size + newChapters.second.size > 0) listener?.onUpdateManga(
|
||||||
|
manga
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return hasDownloads
|
||||||
|
} catch (e: Exception) {
|
||||||
|
if (e !is CancellationException) {
|
||||||
|
failedUpdates[manga] = e.message
|
||||||
|
Timber.e("Failed updating: ${manga.title}: $e")
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
|
private fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
|
||||||
// We don't want to start downloading while the library is updating, because websites
|
// We don't want to start downloading while the library is updating, because websites
|
||||||
|
@ -448,19 +448,19 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||||||
*/
|
*/
|
||||||
internal fun openChapterPendingActivity(context: Context, manga: Manga, groupId: Int):
|
internal fun openChapterPendingActivity(context: Context, manga: Manga, groupId: Int):
|
||||||
PendingIntent {
|
PendingIntent {
|
||||||
val newIntent =
|
val newIntent =
|
||||||
Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_MANGA)
|
Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_MANGA)
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||||
.putExtra(MangaDetailsController.MANGA_EXTRA, manga.id)
|
.putExtra(MangaDetailsController.MANGA_EXTRA, manga.id)
|
||||||
.putExtra("notificationId", manga.id.hashCode())
|
.putExtra("notificationId", manga.id.hashCode())
|
||||||
.putExtra("groupId", groupId)
|
.putExtra("groupId", groupId)
|
||||||
return PendingIntent.getActivity(
|
return PendingIntent.getActivity(
|
||||||
context,
|
context,
|
||||||
manga.id.hashCode(),
|
manga.id.hashCode(),
|
||||||
newIntent,
|
newIntent,
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns [PendingIntent] that opens the error log file in an external viewer
|
* Returns [PendingIntent] that opens the error log file in an external viewer
|
||||||
@ -522,15 +522,15 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||||||
groupId: Int
|
groupId: Int
|
||||||
):
|
):
|
||||||
PendingIntent {
|
PendingIntent {
|
||||||
val newIntent = Intent(context, NotificationReceiver::class.java).apply {
|
val newIntent = Intent(context, NotificationReceiver::class.java).apply {
|
||||||
action = ACTION_MARK_AS_READ
|
action = ACTION_MARK_AS_READ
|
||||||
putExtra(EXTRA_CHAPTER_URL, chapters.map { it.url }.toTypedArray())
|
putExtra(EXTRA_CHAPTER_URL, chapters.map { it.url }.toTypedArray())
|
||||||
putExtra(EXTRA_MANGA_ID, manga.id)
|
putExtra(EXTRA_MANGA_ID, manga.id)
|
||||||
putExtra(EXTRA_NOTIFICATION_ID, manga.id.hashCode())
|
putExtra(EXTRA_NOTIFICATION_ID, manga.id.hashCode())
|
||||||
putExtra(EXTRA_GROUP_ID, groupId)
|
putExtra(EXTRA_GROUP_ID, groupId)
|
||||||
}
|
|
||||||
return PendingIntent.getBroadcast(context, manga.id.hashCode(), newIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
|
||||||
}
|
}
|
||||||
|
return PendingIntent.getBroadcast(context, manga.id.hashCode(), newIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns [PendingIntent] that starts a service which stops the library update
|
* Returns [PendingIntent] that starts a service which stops the library update
|
||||||
|
@ -6,11 +6,9 @@ import androidx.annotation.StringRes
|
|||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.track.anilist.Anilist
|
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.ui.manga.track.SetTrackReadingDatesDialog
|
|
||||||
import eu.kanade.tachiyomi.util.system.executeOnIO
|
import eu.kanade.tachiyomi.util.system.executeOnIO
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
@ -25,7 +25,6 @@ import okhttp3.RequestBody.Companion.toRequestBody
|
|||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Date
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||||
@ -34,7 +33,6 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
|
|
||||||
suspend fun addLibManga(track: Track): Track {
|
suspend fun addLibManga(track: Track): Track {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
|
|
||||||
val variables = jsonObject(
|
val variables = jsonObject(
|
||||||
"mangaId" to track.media_id,
|
"mangaId" to track.media_id,
|
||||||
"progress" to track.last_chapter_read,
|
"progress" to track.last_chapter_read,
|
||||||
@ -105,7 +103,6 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun findLibManga(track: Track, userid: Int): Track? {
|
suspend fun findLibManga(track: Track, userid: Int): Track? {
|
||||||
|
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val variables = jsonObject(
|
val variables = jsonObject(
|
||||||
"id" to userid,
|
"id" to userid,
|
||||||
@ -141,7 +138,6 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
suspend fun remove(track: Track): Boolean {
|
suspend fun remove(track: Track): Boolean {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
val variables = jsonObject(
|
val variables = jsonObject(
|
||||||
"listId" to track.library_id
|
"listId" to track.library_id
|
||||||
)
|
)
|
||||||
|
@ -114,7 +114,6 @@ class Bangumi(private val context: Context, id: Int) : TrackService(id) {
|
|||||||
|
|
||||||
suspend fun login(code: String): Boolean {
|
suspend fun login(code: String): Boolean {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
val oauth = api.accessToken(code)
|
val oauth = api.accessToken(code)
|
||||||
interceptor.newAuth(oauth)
|
interceptor.newAuth(oauth)
|
||||||
saveCredentials(oauth.user_id.toString(), oauth.access_token)
|
saveCredentials(oauth.user_id.toString(), oauth.access_token)
|
||||||
|
@ -5,14 +5,12 @@ import android.graphics.Color
|
|||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.data.track.updateNewTrackInfo
|
import eu.kanade.tachiyomi.data.track.updateNewTrackInfo
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
@ -89,7 +87,6 @@ class MyAnimeList(private val context: Context, id: Int) : TrackService(id) {
|
|||||||
// Set default fields if it's not found in the list
|
// Set default fields if it's not found in the list
|
||||||
add(track)
|
add(track)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun canRemoveFromService(): Boolean = true
|
override fun canRemoveFromService(): Boolean = true
|
||||||
|
@ -8,17 +8,11 @@ import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
|||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.network.await
|
import eu.kanade.tachiyomi.network.await
|
||||||
import eu.kanade.tachiyomi.network.consumeBody
|
|
||||||
import eu.kanade.tachiyomi.network.consumeXmlBody
|
|
||||||
import eu.kanade.tachiyomi.network.parseAs
|
import eu.kanade.tachiyomi.network.parseAs
|
||||||
import eu.kanade.tachiyomi.util.PkceUtil
|
import eu.kanade.tachiyomi.util.PkceUtil
|
||||||
import eu.kanade.tachiyomi.util.selectInt
|
|
||||||
import eu.kanade.tachiyomi.util.selectText
|
|
||||||
import eu.kanade.tachiyomi.util.system.withIOContext
|
import eu.kanade.tachiyomi.util.system.withIOContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
import kotlinx.serialization.json.boolean
|
import kotlinx.serialization.json.boolean
|
||||||
import kotlinx.serialization.json.contentOrNull
|
import kotlinx.serialization.json.contentOrNull
|
||||||
@ -27,17 +21,9 @@ import kotlinx.serialization.json.jsonArray
|
|||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
|
||||||
import org.json.JSONObject
|
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import org.jsoup.nodes.Document
|
|
||||||
import org.jsoup.nodes.Element
|
|
||||||
import org.jsoup.parser.Parser
|
|
||||||
import retrofit2.http.DELETE
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -49,91 +35,90 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
suspend fun getAccessToken(authCode: String): OAuth {
|
suspend fun getAccessToken(authCode: String): OAuth {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val formBody: RequestBody = FormBody.Builder()
|
val formBody: RequestBody = FormBody.Builder()
|
||||||
.add("client_id", clientId)
|
.add("client_id", clientId)
|
||||||
.add("code", authCode)
|
.add("code", authCode)
|
||||||
.add("code_verifier", codeVerifier)
|
.add("code_verifier", codeVerifier)
|
||||||
.add("grant_type", "authorization_code")
|
.add("grant_type", "authorization_code")
|
||||||
.build()
|
.build()
|
||||||
client.newCall(POST("$baseOAuthUrl/token", body = formBody))
|
client.newCall(POST("$baseOAuthUrl/token", body = formBody))
|
||||||
.await()
|
.await()
|
||||||
.parseAs()
|
.parseAs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getCurrentUser(): String {
|
suspend fun getCurrentUser(): String {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url("$baseApiUrl/users/@me")
|
.url("$baseApiUrl/users/@me")
|
||||||
.get()
|
.get()
|
||||||
.build()
|
.build()
|
||||||
authClient.newCall(request)
|
authClient.newCall(request)
|
||||||
.await()
|
.await()
|
||||||
.parseAs<JsonObject>()
|
.parseAs<JsonObject>()
|
||||||
.let { it["name"]!!.jsonPrimitive.content }
|
.let { it["name"]!!.jsonPrimitive.content }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun search(query: String): List<TrackSearch> {
|
suspend fun search(query: String): List<TrackSearch> {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val url = "$baseApiUrl/manga".toUri().buildUpon()
|
val url = "$baseApiUrl/manga".toUri().buildUpon()
|
||||||
.appendQueryParameter("q", query)
|
.appendQueryParameter("q", query)
|
||||||
.appendQueryParameter("nsfw", "true")
|
.appendQueryParameter("nsfw", "true")
|
||||||
.build()
|
.build()
|
||||||
authClient.newCall(GET(url.toString()))
|
authClient.newCall(GET(url.toString()))
|
||||||
.await()
|
.await()
|
||||||
.parseAs<JsonObject>()
|
.parseAs<JsonObject>()
|
||||||
.let {
|
.let {
|
||||||
it["data"]!!.jsonArray
|
it["data"]!!.jsonArray
|
||||||
.map { data -> data.jsonObject["node"]!!.jsonObject }
|
.map { data -> data.jsonObject["node"]!!.jsonObject }
|
||||||
.map { node ->
|
.map { node ->
|
||||||
val id = node["id"]!!.jsonPrimitive.int
|
val id = node["id"]!!.jsonPrimitive.int
|
||||||
async { getMangaDetails(id) }
|
async { getMangaDetails(id) }
|
||||||
}
|
}
|
||||||
.awaitAll()
|
.awaitAll()
|
||||||
.filter { trackSearch -> trackSearch.publishing_type != "novel" }
|
.filter { trackSearch -> trackSearch.publishing_type != "novel" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
suspend fun getMangaDetails(id: Int): TrackSearch {
|
suspend fun getMangaDetails(id: Int): TrackSearch {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val url = "$baseApiUrl/manga".toUri().buildUpon()
|
val url = "$baseApiUrl/manga".toUri().buildUpon()
|
||||||
.appendPath(id.toString())
|
.appendPath(id.toString())
|
||||||
.appendQueryParameter("fields", "id,title,synopsis,num_chapters,main_picture,status,media_type,start_date")
|
.appendQueryParameter("fields", "id,title,synopsis,num_chapters,main_picture,status,media_type,start_date")
|
||||||
.build()
|
.build()
|
||||||
authClient.newCall(GET(url.toString()))
|
authClient.newCall(GET(url.toString()))
|
||||||
.await()
|
.await()
|
||||||
.parseAs<JsonObject>()
|
.parseAs<JsonObject>()
|
||||||
.let {
|
.let {
|
||||||
val obj = it.jsonObject
|
val obj = it.jsonObject
|
||||||
TrackSearch.create(TrackManager.MYANIMELIST).apply {
|
TrackSearch.create(TrackManager.MYANIMELIST).apply {
|
||||||
media_id = obj["id"]!!.jsonPrimitive.int
|
media_id = obj["id"]!!.jsonPrimitive.int
|
||||||
title = obj["title"]!!.jsonPrimitive.content
|
title = obj["title"]!!.jsonPrimitive.content
|
||||||
summary = obj["synopsis"]?.jsonPrimitive?.content ?: ""
|
summary = obj["synopsis"]?.jsonPrimitive?.content ?: ""
|
||||||
total_chapters = obj["num_chapters"]!!.jsonPrimitive.int
|
total_chapters = obj["num_chapters"]!!.jsonPrimitive.int
|
||||||
cover_url = obj["main_picture"]?.jsonObject?.get("large")?.jsonPrimitive?.content ?: ""
|
cover_url = obj["main_picture"]?.jsonObject?.get("large")?.jsonPrimitive?.content ?: ""
|
||||||
tracking_url = "https://myanimelist.net/manga/$media_id"
|
tracking_url = "https://myanimelist.net/manga/$media_id"
|
||||||
publishing_status = obj["status"]!!.jsonPrimitive.content.replace("_", " ")
|
publishing_status = obj["status"]!!.jsonPrimitive.content.replace("_", " ")
|
||||||
publishing_type = obj["media_type"]!!.jsonPrimitive.content.replace("_", " ")
|
publishing_type = obj["media_type"]!!.jsonPrimitive.content.replace("_", " ")
|
||||||
start_date = try {
|
start_date = try {
|
||||||
val outputDf = SimpleDateFormat("yyyy-MM-dd", Locale.US)
|
val outputDf = SimpleDateFormat("yyyy-MM-dd", Locale.US)
|
||||||
outputDf.format(obj["start_date"]!!)
|
outputDf.format(obj["start_date"]!!)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
""
|
""
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun updateItem(track: Track): Track {
|
suspend fun updateItem(track: Track): Track {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val formBodyBuilder = FormBody.Builder()
|
val formBodyBuilder = FormBody.Builder()
|
||||||
.add("status", track.toMyAnimeListStatus() ?: "reading")
|
.add("status", track.toMyAnimeListStatus() ?: "reading")
|
||||||
.add("is_rereading", (track.status == MyAnimeList.REREADING).toString())
|
.add("is_rereading", (track.status == MyAnimeList.REREADING).toString())
|
||||||
.add("score", track.score.toString())
|
.add("score", track.score.toString())
|
||||||
.add("num_chapters_read", track.last_chapter_read.toString())
|
.add("num_chapters_read", track.last_chapter_read.toString())
|
||||||
convertToIsoDate(track.started_reading_date)?.let {
|
convertToIsoDate(track.started_reading_date)?.let {
|
||||||
formBodyBuilder.add("start_date", it)
|
formBodyBuilder.add("start_date", it)
|
||||||
}
|
}
|
||||||
@ -142,32 +127,31 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
}
|
}
|
||||||
|
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url(mangaUrl(track.media_id).toString())
|
.url(mangaUrl(track.media_id).toString())
|
||||||
.put(formBodyBuilder.build())
|
.put(formBodyBuilder.build())
|
||||||
.build()
|
.build()
|
||||||
authClient.newCall(request)
|
authClient.newCall(request)
|
||||||
.await()
|
.await()
|
||||||
.parseAs<JsonObject>()
|
.parseAs<JsonObject>()
|
||||||
.let { parseMangaItem(it, track) }
|
.let { parseMangaItem(it, track) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
suspend fun findListItem(track: Track): Track? {
|
suspend fun findListItem(track: Track): Track? {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val uri = "$baseApiUrl/manga".toUri().buildUpon()
|
val uri = "$baseApiUrl/manga".toUri().buildUpon()
|
||||||
.appendPath(track.media_id.toString())
|
.appendPath(track.media_id.toString())
|
||||||
.appendQueryParameter("fields", "num_chapters,my_list_status{start_date,finish_date}")
|
.appendQueryParameter("fields", "num_chapters,my_list_status{start_date,finish_date}")
|
||||||
.build()
|
.build()
|
||||||
authClient.newCall(GET(uri.toString()))
|
authClient.newCall(GET(uri.toString()))
|
||||||
.await()
|
.await()
|
||||||
.parseAs<JsonObject>()
|
.parseAs<JsonObject>()
|
||||||
.let { obj ->
|
.let { obj ->
|
||||||
track.total_chapters = obj["num_chapters"]!!.jsonPrimitive.int
|
track.total_chapters = obj["num_chapters"]!!.jsonPrimitive.int
|
||||||
obj.jsonObject["my_list_status"]?.jsonObject?.let {
|
obj.jsonObject["my_list_status"]?.jsonObject?.let {
|
||||||
parseMangaItem(it, track)
|
parseMangaItem(it, track)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,17 +161,17 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
val obj = json.jsonObject
|
val obj = json.jsonObject
|
||||||
|
|
||||||
val matches = obj["data"]!!.jsonArray
|
val matches = obj["data"]!!.jsonArray
|
||||||
.filter {
|
.filter {
|
||||||
it.jsonObject["node"]!!.jsonObject["title"]!!.jsonPrimitive.content.contains(
|
it.jsonObject["node"]!!.jsonObject["title"]!!.jsonPrimitive.content.contains(
|
||||||
query,
|
query,
|
||||||
ignoreCase = true
|
ignoreCase = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.map {
|
.map {
|
||||||
val id = it.jsonObject["node"]!!.jsonObject["id"]!!.jsonPrimitive.int
|
val id = it.jsonObject["node"]!!.jsonObject["id"]!!.jsonPrimitive.int
|
||||||
async { getMangaDetails(id) }
|
async { getMangaDetails(id) }
|
||||||
}
|
}
|
||||||
.awaitAll()
|
.awaitAll()
|
||||||
|
|
||||||
// Check next page if there's more
|
// Check next page if there's more
|
||||||
if (!obj["paging"]!!.jsonObject["next"]?.jsonPrimitive?.contentOrNull.isNullOrBlank()) {
|
if (!obj["paging"]!!.jsonObject["next"]?.jsonPrimitive?.contentOrNull.isNullOrBlank()) {
|
||||||
@ -201,19 +185,19 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
private suspend fun getListPage(offset: Int): JsonObject {
|
private suspend fun getListPage(offset: Int): JsonObject {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val urlBuilder = "$baseApiUrl/users/@me/mangalist".toUri().buildUpon()
|
val urlBuilder = "$baseApiUrl/users/@me/mangalist".toUri().buildUpon()
|
||||||
.appendQueryParameter("fields", "list_status{start_date,finish_date}")
|
.appendQueryParameter("fields", "list_status{start_date,finish_date}")
|
||||||
.appendQueryParameter("limit", listPaginationAmount.toString())
|
.appendQueryParameter("limit", listPaginationAmount.toString())
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
urlBuilder.appendQueryParameter("offset", offset.toString())
|
urlBuilder.appendQueryParameter("offset", offset.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url(urlBuilder.build().toString())
|
.url(urlBuilder.build().toString())
|
||||||
.get()
|
.get()
|
||||||
.build()
|
.build()
|
||||||
authClient.newCall(request)
|
authClient.newCall(request)
|
||||||
.await()
|
.await()
|
||||||
.parseAs()
|
.parseAs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +235,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
|
|
||||||
suspend fun remove(track: Track): Boolean {
|
suspend fun remove(track: Track): Boolean {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
try {
|
try {
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url(mangaUrl(track.media_id).toString())
|
.url(mangaUrl(track.media_id).toString())
|
||||||
.delete()
|
.delete()
|
||||||
@ -277,22 +261,22 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
private var codeVerifier: String = ""
|
private var codeVerifier: String = ""
|
||||||
|
|
||||||
fun authUrl(): Uri = "$baseOAuthUrl/authorize".toUri().buildUpon()
|
fun authUrl(): Uri = "$baseOAuthUrl/authorize".toUri().buildUpon()
|
||||||
.appendQueryParameter("client_id", clientId)
|
.appendQueryParameter("client_id", clientId)
|
||||||
.appendQueryParameter("code_challenge", getPkceChallengeCode())
|
.appendQueryParameter("code_challenge", getPkceChallengeCode())
|
||||||
.appendQueryParameter("response_type", "code")
|
.appendQueryParameter("response_type", "code")
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
fun mangaUrl(id: Int): Uri = "$baseApiUrl/manga".toUri().buildUpon()
|
fun mangaUrl(id: Int): Uri = "$baseApiUrl/manga".toUri().buildUpon()
|
||||||
.appendPath(id.toString())
|
.appendPath(id.toString())
|
||||||
.appendPath("my_list_status")
|
.appendPath("my_list_status")
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
fun refreshTokenRequest(refreshToken: String): Request {
|
fun refreshTokenRequest(refreshToken: String): Request {
|
||||||
val formBody: RequestBody = FormBody.Builder()
|
val formBody: RequestBody = FormBody.Builder()
|
||||||
.add("client_id", clientId)
|
.add("client_id", clientId)
|
||||||
.add("refresh_token", refreshToken)
|
.add("refresh_token", refreshToken)
|
||||||
.add("grant_type", "refresh_token")
|
.add("grant_type", "refresh_token")
|
||||||
.build()
|
.build()
|
||||||
return POST("$baseOAuthUrl/token", body = formBody)
|
return POST("$baseOAuthUrl/token", body = formBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,16 +3,10 @@ package eu.kanade.tachiyomi.data.track.myanimelist
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.Request
|
|
||||||
import okhttp3.RequestBody
|
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import okio.Buffer
|
|
||||||
import org.json.JSONObject
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
class MyAnimeListInterceptor(private val myanimelist: MyAnimeList, private var token: String?) : Interceptor {
|
class MyAnimeListInterceptor(private val myanimelist: MyAnimeList, private var token: String?) : Interceptor {
|
||||||
@ -51,8 +45,8 @@ class MyAnimeListInterceptor(private val myanimelist: MyAnimeList, private var t
|
|||||||
|
|
||||||
// Add the authorization header to the original request.
|
// Add the authorization header to the original request.
|
||||||
val authRequest = originalRequest.newBuilder()
|
val authRequest = originalRequest.newBuilder()
|
||||||
.addHeader("Authorization", "Bearer ${oauth!!.access_token}")
|
.addHeader("Authorization", "Bearer ${oauth!!.access_token}")
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
return chain.proceed(authRequest)
|
return chain.proceed(authRequest)
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,9 @@ class ExtensionManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun removeListener(listener: ExtensionsChangedListener) {
|
fun removeListener(listener: ExtensionsChangedListener) {
|
||||||
if (this.listener == listener)
|
if (this.listener == listener) {
|
||||||
this.listener = null
|
this.listener = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAppIconForSource(source: Source): Drawable? {
|
fun getAppIconForSource(source: Source): Drawable? {
|
||||||
|
@ -62,17 +62,17 @@ internal class ExtensionGithubApi {
|
|||||||
libVersion >= ExtensionLoader.LIB_VERSION_MIN && libVersion <= ExtensionLoader.LIB_VERSION_MAX
|
libVersion >= ExtensionLoader.LIB_VERSION_MIN && libVersion <= ExtensionLoader.LIB_VERSION_MAX
|
||||||
}
|
}
|
||||||
.map { element ->
|
.map { element ->
|
||||||
val name = element.jsonObject["name"]!!.jsonPrimitive.content.substringAfter("Tachiyomi: ")
|
val name = element.jsonObject["name"]!!.jsonPrimitive.content.substringAfter("Tachiyomi: ")
|
||||||
val pkgName = element.jsonObject["pkg"]!!.jsonPrimitive.content
|
val pkgName = element.jsonObject["pkg"]!!.jsonPrimitive.content
|
||||||
val apkName = element.jsonObject["apk"]!!.jsonPrimitive.content
|
val apkName = element.jsonObject["apk"]!!.jsonPrimitive.content
|
||||||
val versionName = element.jsonObject["version"]!!.jsonPrimitive.content
|
val versionName = element.jsonObject["version"]!!.jsonPrimitive.content
|
||||||
val versionCode = element.jsonObject["code"]!!.jsonPrimitive.int
|
val versionCode = element.jsonObject["code"]!!.jsonPrimitive.int
|
||||||
val lang = element.jsonObject["lang"]!!.jsonPrimitive.content
|
val lang = element.jsonObject["lang"]!!.jsonPrimitive.content
|
||||||
val nsfw = element.jsonObject["nsfw"]!!.jsonPrimitive.int == 1
|
val nsfw = element.jsonObject["nsfw"]!!.jsonPrimitive.int == 1
|
||||||
val icon = "${REPO_URL_PREFIX}icon/${apkName.replace(".apk", ".png")}"
|
val icon = "${REPO_URL_PREFIX}icon/${apkName.replace(".apk", ".png")}"
|
||||||
|
|
||||||
Extension.Available(name, pkgName, versionName, versionCode, lang, nsfw, apkName, icon)
|
Extension.Available(name, pkgName, versionName, versionCode, lang, nsfw, apkName, icon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getApkUrl(extension: Extension.Available): String {
|
fun getApkUrl(extension: Extension.Available): String {
|
||||||
|
@ -144,10 +144,11 @@ internal object ExtensionLoader {
|
|||||||
.split(";")
|
.split(";")
|
||||||
.map {
|
.map {
|
||||||
val sourceClass = it.trim()
|
val sourceClass = it.trim()
|
||||||
if (sourceClass.startsWith("."))
|
if (sourceClass.startsWith(".")) {
|
||||||
pkgInfo.packageName + sourceClass
|
pkgInfo.packageName + sourceClass
|
||||||
else
|
} else {
|
||||||
sourceClass
|
sourceClass
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.flatMap {
|
.flatMap {
|
||||||
try {
|
try {
|
||||||
|
@ -16,7 +16,6 @@ fun GET(
|
|||||||
headers: Headers = DEFAULT_HEADERS,
|
headers: Headers = DEFAULT_HEADERS,
|
||||||
cache: CacheControl = DEFAULT_CACHE_CONTROL
|
cache: CacheControl = DEFAULT_CACHE_CONTROL
|
||||||
): Request {
|
): Request {
|
||||||
|
|
||||||
return Request.Builder()
|
return Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.headers(headers)
|
.headers(headers)
|
||||||
@ -30,7 +29,6 @@ fun POST(
|
|||||||
body: RequestBody = DEFAULT_BODY,
|
body: RequestBody = DEFAULT_BODY,
|
||||||
cache: CacheControl = DEFAULT_CACHE_CONTROL
|
cache: CacheControl = DEFAULT_CACHE_CONTROL
|
||||||
): Request {
|
): Request {
|
||||||
|
|
||||||
return Request.Builder()
|
return Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.post(body)
|
.post(body)
|
||||||
|
@ -61,8 +61,9 @@ class SmartSearchEngine(
|
|||||||
} else title
|
} else title
|
||||||
val searchResults = source.fetchSearchManga(1, searchQuery, FilterList()).toSingle().await(Schedulers.io())
|
val searchResults = source.fetchSearchManga(1, searchQuery, FilterList()).toSingle().await(Schedulers.io())
|
||||||
|
|
||||||
if (searchResults.mangas.size == 1)
|
if (searchResults.mangas.size == 1) {
|
||||||
return@supervisorScope listOf(SearchEntry(searchResults.mangas.first(), 0.0))
|
return@supervisorScope listOf(SearchEntry(searchResults.mangas.first(), 0.0))
|
||||||
|
}
|
||||||
|
|
||||||
searchResults.mangas.map {
|
searchResults.mangas.map {
|
||||||
val normalizedDistance = normalizedLevenshtein.similarity(title, it.title)
|
val normalizedDistance = normalizedLevenshtein.similarity(title, it.title)
|
||||||
|
@ -15,14 +15,16 @@ open class Page(
|
|||||||
val number: Int
|
val number: Int
|
||||||
get() = index + 1
|
get() = index + 1
|
||||||
|
|
||||||
@Transient @Volatile var status: Int = 0
|
@Transient @Volatile
|
||||||
|
var status: Int = 0
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
statusSubject?.onNext(value)
|
statusSubject?.onNext(value)
|
||||||
statusCallback?.invoke(this)
|
statusCallback?.invoke(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transient @Volatile var progress: Int = 0
|
@Transient @Volatile
|
||||||
|
var progress: Int = 0
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
statusCallback?.invoke(this)
|
statusCallback?.invoke(this)
|
||||||
|
@ -36,25 +36,31 @@ interface SManga : Serializable {
|
|||||||
get() = (this as? MangaImpl)?.ogGenre ?: genre
|
get() = (this as? MangaImpl)?.ogGenre ?: genre
|
||||||
|
|
||||||
fun copyFrom(other: SManga) {
|
fun copyFrom(other: SManga) {
|
||||||
if (other.author != null)
|
if (other.author != null) {
|
||||||
author = other.originalAuthor
|
author = other.originalAuthor
|
||||||
|
}
|
||||||
|
|
||||||
if (other.artist != null)
|
if (other.artist != null) {
|
||||||
artist = other.originalArtist
|
artist = other.originalArtist
|
||||||
|
}
|
||||||
|
|
||||||
if (other.description != null)
|
if (other.description != null) {
|
||||||
description = other.originalDescription
|
description = other.originalDescription
|
||||||
|
}
|
||||||
|
|
||||||
if (other.genre != null)
|
if (other.genre != null) {
|
||||||
genre = other.originalGenre
|
genre = other.originalGenre
|
||||||
|
}
|
||||||
|
|
||||||
if (other.thumbnail_url != null)
|
if (other.thumbnail_url != null) {
|
||||||
thumbnail_url = other.thumbnail_url
|
thumbnail_url = other.thumbnail_url
|
||||||
|
}
|
||||||
|
|
||||||
status = other.status
|
status = other.status
|
||||||
|
|
||||||
if (!initialized)
|
if (!initialized) {
|
||||||
initialized = other.initialized
|
initialized = other.initialized
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -29,7 +29,8 @@ abstract class BaseActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
if (this !is BiometricActivity && this !is SearchActivity)
|
if (this !is BiometricActivity && this !is SearchActivity) {
|
||||||
SecureActivityDelegate.promptLockIfNeeded(this)
|
SecureActivityDelegate.promptLockIfNeeded(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,8 +84,9 @@ abstract class BaseController(bundle: Bundle? = null) :
|
|||||||
parentController = parentController.parentController
|
parentController = parentController.parentController
|
||||||
}
|
}
|
||||||
|
|
||||||
if (router.backstack.lastOrNull()?.controller() == this)
|
if (router.backstack.lastOrNull()?.controller() == this) {
|
||||||
(activity as? AppCompatActivity)?.supportActionBar?.title = getTitle()
|
(activity as? AppCompatActivity)?.supportActionBar?.title = getTitle()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Controller.instance(): String {
|
private fun Controller.instance(): String {
|
||||||
|
@ -43,12 +43,10 @@ abstract class RxController(bundle: Bundle? = null) : BaseController(bundle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <T> Observable<T>.subscribeUntilDetach(): Subscription {
|
fun <T> Observable<T>.subscribeUntilDetach(): Subscription {
|
||||||
|
|
||||||
return subscribe().also { untilDetachSubscriptions.add(it) }
|
return subscribe().also { untilDetachSubscriptions.add(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> Observable<T>.subscribeUntilDetach(onNext: (T) -> Unit): Subscription {
|
fun <T> Observable<T>.subscribeUntilDetach(onNext: (T) -> Unit): Subscription {
|
||||||
|
|
||||||
return subscribe(onNext).also { untilDetachSubscriptions.add(it) }
|
return subscribe(onNext).also { untilDetachSubscriptions.add(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +54,6 @@ abstract class RxController(bundle: Bundle? = null) : BaseController(bundle) {
|
|||||||
onNext: (T) -> Unit,
|
onNext: (T) -> Unit,
|
||||||
onError: (Throwable) -> Unit
|
onError: (Throwable) -> Unit
|
||||||
): Subscription {
|
): Subscription {
|
||||||
|
|
||||||
return subscribe(onNext, onError).also { untilDetachSubscriptions.add(it) }
|
return subscribe(onNext, onError).also { untilDetachSubscriptions.add(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,17 +62,14 @@ abstract class RxController(bundle: Bundle? = null) : BaseController(bundle) {
|
|||||||
onError: (Throwable) -> Unit,
|
onError: (Throwable) -> Unit,
|
||||||
onCompleted: () -> Unit
|
onCompleted: () -> Unit
|
||||||
): Subscription {
|
): Subscription {
|
||||||
|
|
||||||
return subscribe(onNext, onError, onCompleted).also { untilDetachSubscriptions.add(it) }
|
return subscribe(onNext, onError, onCompleted).also { untilDetachSubscriptions.add(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> Observable<T>.subscribeUntilDestroy(): Subscription {
|
fun <T> Observable<T>.subscribeUntilDestroy(): Subscription {
|
||||||
|
|
||||||
return subscribe().also { untilDestroySubscriptions.add(it) }
|
return subscribe().also { untilDestroySubscriptions.add(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> Observable<T>.subscribeUntilDestroy(onNext: (T) -> Unit): Subscription {
|
fun <T> Observable<T>.subscribeUntilDestroy(onNext: (T) -> Unit): Subscription {
|
||||||
|
|
||||||
return subscribe(onNext).also { untilDestroySubscriptions.add(it) }
|
return subscribe(onNext).also { untilDestroySubscriptions.add(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +77,6 @@ abstract class RxController(bundle: Bundle? = null) : BaseController(bundle) {
|
|||||||
onNext: (T) -> Unit,
|
onNext: (T) -> Unit,
|
||||||
onError: (Throwable) -> Unit
|
onError: (Throwable) -> Unit
|
||||||
): Subscription {
|
): Subscription {
|
||||||
|
|
||||||
return subscribe(onNext, onError).also { untilDestroySubscriptions.add(it) }
|
return subscribe(onNext, onError).also { untilDestroySubscriptions.add(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +85,6 @@ abstract class RxController(bundle: Bundle? = null) : BaseController(bundle) {
|
|||||||
onError: (Throwable) -> Unit,
|
onError: (Throwable) -> Unit,
|
||||||
onCompleted: () -> Unit
|
onCompleted: () -> Unit
|
||||||
): Subscription {
|
): Subscription {
|
||||||
|
|
||||||
return subscribe(onNext, onError, onCompleted).also { untilDestroySubscriptions.add(it) }
|
return subscribe(onNext, onError, onCompleted).also { untilDestroySubscriptions.add(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,8 +122,9 @@ class CategoryController(bundle: Bundle? = null) :
|
|||||||
|
|
||||||
override fun onCategoryRename(position: Int, newName: String): Boolean {
|
override fun onCategoryRename(position: Int, newName: String): Boolean {
|
||||||
val category = adapter?.getItem(position)?.category ?: return false
|
val category = adapter?.getItem(position)?.category ?: return false
|
||||||
if (category.order == CREATE_CATEGORY_ORDER)
|
if (category.order == CREATE_CATEGORY_ORDER) {
|
||||||
return (presenter.createCategory(newName))
|
return (presenter.createCategory(newName))
|
||||||
|
}
|
||||||
return (presenter.renameCategory(category, newName))
|
return (presenter.renameCategory(category, newName))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,6 +186,7 @@ class CategoryController(bundle: Bundle? = null) :
|
|||||||
override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean {
|
override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean {
|
||||||
return toPosition > 0
|
return toPosition > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from the presenter when a category with the given name already exists.
|
* Called from the presenter when a category with the given name already exists.
|
||||||
*/
|
*/
|
||||||
|
@ -121,8 +121,9 @@ class CategoryHolder(view: View, val adapter: CategoryAdapter) : BaseFlexibleVie
|
|||||||
) {
|
) {
|
||||||
isEditing(false)
|
isEditing(false)
|
||||||
edit_text.inputType = InputType.TYPE_NULL
|
edit_text.inputType = InputType.TYPE_NULL
|
||||||
if (!createCategory)
|
if (!createCategory) {
|
||||||
title.text = edit_text.text.toString()
|
title.text = edit_text.text.toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
itemView.performClick()
|
itemView.performClick()
|
||||||
|
@ -105,10 +105,11 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
|
|||||||
preferences.downloadNewCategories(),
|
preferences.downloadNewCategories(),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
if (downloadNew && preferences.downloadNewCategories().get().isEmpty())
|
if (downloadNew && preferences.downloadNewCategories().get().isEmpty()) {
|
||||||
view.download_new.gone()
|
view.download_new.gone()
|
||||||
else if (!downloadNew)
|
} else if (!downloadNew) {
|
||||||
view.download_new.visible()
|
view.download_new.visible()
|
||||||
|
}
|
||||||
view.download_new.isChecked =
|
view.download_new.isChecked =
|
||||||
preferences.downloadNew().get() && view.download_new.isChecked
|
preferences.downloadNew().get() && view.download_new.isChecked
|
||||||
setCheckbox(
|
setCheckbox(
|
||||||
@ -132,9 +133,9 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setCheckbox(
|
private fun setCheckbox(
|
||||||
box: CompoundButton,
|
box: CompoundButton,
|
||||||
categories: Preference<Set<String>>,
|
categories: Preference<Set<String>>,
|
||||||
shouldShow: Boolean
|
shouldShow: Boolean
|
||||||
) {
|
) {
|
||||||
val updateCategories = categories.get()
|
val updateCategories = categories.get()
|
||||||
box.visibleIf(updateCategories.isNotEmpty() && shouldShow)
|
box.visibleIf(updateCategories.isNotEmpty() && shouldShow)
|
||||||
|
@ -202,8 +202,9 @@ class DownloadBottomSheet @JvmOverloads constructor(
|
|||||||
val adapter = adapter ?: return false
|
val adapter = adapter ?: return false
|
||||||
val items = adapter.currentItems.sortedBy { it.download.chapter.date_upload }
|
val items = adapter.currentItems.sortedBy { it.download.chapter.date_upload }
|
||||||
.toMutableList()
|
.toMutableList()
|
||||||
if (item.itemId == R.id.newest)
|
if (item.itemId == R.id.newest) {
|
||||||
items.reverse()
|
items.reverse()
|
||||||
|
}
|
||||||
adapter.updateDataSet(items)
|
adapter.updateDataSet(items)
|
||||||
val downloads = items.mapNotNull { it.download }
|
val downloads = items.mapNotNull { it.download }
|
||||||
presenter.reorder(downloads)
|
presenter.reorder(downloads)
|
||||||
@ -266,10 +267,11 @@ class DownloadBottomSheet @JvmOverloads constructor(
|
|||||||
val items = adapter?.currentItems?.toMutableList() ?: return
|
val items = adapter?.currentItems?.toMutableList() ?: return
|
||||||
val item = items[position]
|
val item = items[position]
|
||||||
items.remove(item)
|
items.remove(item)
|
||||||
if (menuItem.itemId == R.id.move_to_top)
|
if (menuItem.itemId == R.id.move_to_top) {
|
||||||
items.add(0, item)
|
items.add(0, item)
|
||||||
else
|
} else {
|
||||||
items.add(item)
|
items.add(item)
|
||||||
|
}
|
||||||
adapter?.updateDataSet(items)
|
adapter?.updateDataSet(items)
|
||||||
val downloads = items.mapNotNull { it.download }
|
val downloads = items.mapNotNull { it.download }
|
||||||
presenter.reorder(downloads)
|
presenter.reorder(downloads)
|
||||||
|
@ -59,8 +59,9 @@ class DownloadButton @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
isAnimating = false
|
isAnimating = false
|
||||||
}
|
}
|
||||||
download_icon.setImageDrawable(
|
download_icon.setImageDrawable(
|
||||||
if (state == Download.CHECKED)
|
if (state == Download.CHECKED) {
|
||||||
checkDrawable else downloadDrawable
|
checkDrawable
|
||||||
|
} else downloadDrawable
|
||||||
)
|
)
|
||||||
when (state) {
|
when (state) {
|
||||||
Download.CHECKED -> {
|
Download.CHECKED -> {
|
||||||
|
@ -15,7 +15,6 @@ import eu.kanade.tachiyomi.source.SourceManager
|
|||||||
import eu.kanade.tachiyomi.ui.migration.MangaItem
|
import eu.kanade.tachiyomi.ui.migration.MangaItem
|
||||||
import eu.kanade.tachiyomi.ui.migration.SelectionHeader
|
import eu.kanade.tachiyomi.ui.migration.SelectionHeader
|
||||||
import eu.kanade.tachiyomi.ui.migration.SourceItem
|
import eu.kanade.tachiyomi.ui.migration.SourceItem
|
||||||
import eu.kanade.tachiyomi.util.lang.combineLatest
|
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import eu.kanade.tachiyomi.util.system.executeOnIO
|
import eu.kanade.tachiyomi.util.system.executeOnIO
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -26,8 +25,6 @@ import kotlinx.coroutines.awaitAll
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
|
||||||
import rx.schedulers.Schedulers
|
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -76,14 +73,15 @@ class ExtensionBottomPresenter(
|
|||||||
val migrationJob = async {
|
val migrationJob = async {
|
||||||
val favs = db.getFavoriteMangas().executeOnIO()
|
val favs = db.getFavoriteMangas().executeOnIO()
|
||||||
sourceItems = findSourcesWithManga(favs)
|
sourceItems = findSourcesWithManga(favs)
|
||||||
mangaItems = HashMap(sourceItems.associate {
|
mangaItems = HashMap(
|
||||||
it.source.id to this@ExtensionBottomPresenter.libraryToMigrationItem(favs, it.source.id)
|
sourceItems.associate {
|
||||||
})
|
it.source.id to this@ExtensionBottomPresenter.libraryToMigrationItem(favs, it.source.id)
|
||||||
|
}
|
||||||
|
)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (selectedSource != null) {
|
if (selectedSource != null) {
|
||||||
bottomSheet.setMigrationManga(mangaItems[selectedSource])
|
bottomSheet.setMigrationManga(mangaItems[selectedSource])
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
bottomSheet.setMigrationSources(sourceItems)
|
bottomSheet.setMigrationSources(sourceItems)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,14 +123,15 @@ class ExtensionBottomPresenter(
|
|||||||
scope.launch {
|
scope.launch {
|
||||||
val favs = db.getFavoriteMangas().executeOnIO()
|
val favs = db.getFavoriteMangas().executeOnIO()
|
||||||
sourceItems = findSourcesWithManga(favs)
|
sourceItems = findSourcesWithManga(favs)
|
||||||
mangaItems = HashMap(sourceItems.associate {
|
mangaItems = HashMap(
|
||||||
it.source.id to this@ExtensionBottomPresenter.libraryToMigrationItem(favs, it.source.id)
|
sourceItems.associate {
|
||||||
})
|
it.source.id to this@ExtensionBottomPresenter.libraryToMigrationItem(favs, it.source.id)
|
||||||
|
}
|
||||||
|
)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (selectedSource != null) {
|
if (selectedSource != null) {
|
||||||
bottomSheet.setMigrationManga(mangaItems[selectedSource])
|
bottomSheet.setMigrationManga(mangaItems[selectedSource])
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
bottomSheet.setMigrationSources(sourceItems)
|
bottomSheet.setMigrationSources(sourceItems)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,10 +308,12 @@ class ExtensionBottomSheet @JvmOverloads constructor(context: Context, attrs: At
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getPageTitle(position: Int): CharSequence {
|
override fun getPageTitle(position: Int): CharSequence {
|
||||||
return context.getString(when (position) {
|
return context.getString(
|
||||||
0 -> R.string.extensions
|
when (position) {
|
||||||
else -> R.string.migration
|
0 -> R.string.extensions
|
||||||
})
|
else -> R.string.migration
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,6 @@ data class ExtensionGroupItem(val name: String, val size: Int) : AbstractHeaderI
|
|||||||
position: Int,
|
position: Int,
|
||||||
payloads: MutableList<Any?>?
|
payloads: MutableList<Any?>?
|
||||||
) {
|
) {
|
||||||
|
|
||||||
holder.bind(this)
|
holder.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,6 @@ data class ExtensionItem(
|
|||||||
position: Int,
|
position: Int,
|
||||||
payloads: MutableList<Any?>?
|
payloads: MutableList<Any?>?
|
||||||
) {
|
) {
|
||||||
|
|
||||||
if (payloads == null || payloads.isEmpty()) {
|
if (payloads == null || payloads.isEmpty()) {
|
||||||
holder.bind(this)
|
holder.bind(this)
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.extension
|
|||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import androidx.preference.SwitchPreference
|
import androidx.preference.SwitchPreference
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
|
||||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||||
import eu.kanade.tachiyomi.ui.setting.SettingsController
|
import eu.kanade.tachiyomi.ui.setting.SettingsController
|
||||||
import eu.kanade.tachiyomi.ui.setting.onChange
|
import eu.kanade.tachiyomi.ui.setting.onChange
|
||||||
|
@ -125,7 +125,8 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
|
|||||||
screen.setShouldUseGeneratedIds(true)
|
screen.setShouldUseGeneratedIds(true)
|
||||||
val extHeaderAdapter = ExtensionDetailsHeaderAdapter(presenter)
|
val extHeaderAdapter = ExtensionDetailsHeaderAdapter(presenter)
|
||||||
extHeaderAdapter.setHasStableIds(true)
|
extHeaderAdapter.setHasStableIds(true)
|
||||||
extension_prefs_recycler.adapter = ConcatAdapter(concatAdapterConfig,
|
extension_prefs_recycler.adapter = ConcatAdapter(
|
||||||
|
concatAdapterConfig,
|
||||||
extHeaderAdapter,
|
extHeaderAdapter,
|
||||||
PreferenceGroupAdapter(screen)
|
PreferenceGroupAdapter(screen)
|
||||||
)
|
)
|
||||||
@ -151,7 +152,6 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
|
|||||||
lastOpenPreferencePosition = savedInstanceState.get(LASTOPENPREFERENCE_KEY) as? Int
|
lastOpenPreferencePosition = savedInstanceState.get(LASTOPENPREFERENCE_KEY) as? Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
inflater.inflate(R.menu.extension_details, menu)
|
inflater.inflate(R.menu.extension_details, menu)
|
||||||
|
|
||||||
@ -208,8 +208,7 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
|
|||||||
toggleSource(source, checked)
|
toggleSource(source, checked)
|
||||||
prefs.forEach { it.isVisible = checked }
|
prefs.forEach { it.isVisible = checked }
|
||||||
true
|
true
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
coordinator.snack(context.getString(R.string._must_be_enabled_first, title), Snackbar.LENGTH_LONG) {
|
coordinator.snack(context.getString(R.string._must_be_enabled_first, title), Snackbar.LENGTH_LONG) {
|
||||||
setAction(R.string.enable) {
|
setAction(R.string.enable) {
|
||||||
preferences.enabledLanguages() += source.lang
|
preferences.enabledLanguages() += source.lang
|
||||||
@ -308,7 +307,6 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
|
|||||||
return id.toString() !in preferences.hiddenSources().get() && isLangEnabled()
|
return id.toString() !in preferences.hiddenSources().get() && isLangEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun Source.isLangEnabled(langs: Set<String>? = null): Boolean {
|
private fun Source.isLangEnabled(langs: Set<String>? = null): Boolean {
|
||||||
return (lang in langs ?: preferences.enabledLanguages().get())
|
return (lang in langs ?: preferences.enabledLanguages().get())
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ class ExtensionDetailsHeaderAdapter(private val presenter: ExtensionDetailsPrese
|
|||||||
view.extension_pkg.text = extension.pkgName
|
view.extension_pkg.text = extension.pkgName
|
||||||
|
|
||||||
view.extension_uninstall_button.setOnClickListener {
|
view.extension_uninstall_button.setOnClickListener {
|
||||||
presenter.uninstallExtension()
|
presenter.uninstallExtension()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extension.isObsolete) {
|
if (extension.isObsolete) {
|
||||||
|
@ -41,7 +41,6 @@ class AddToLibraryCategoriesDialog<T>(bundle: Bundle? = null) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||||
|
|
||||||
return MaterialDialog(activity!!).title(R.string.add_to_library).message(R.string.add_to_categories)
|
return MaterialDialog(activity!!).title(R.string.add_to_library).message(R.string.add_to_categories)
|
||||||
.listItemsMultiChoice(
|
.listItemsMultiChoice(
|
||||||
items = categories.map { it.name },
|
items = categories.map { it.name },
|
||||||
|
@ -29,6 +29,7 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
|||||||
init {
|
init {
|
||||||
setDisplayHeadersAtStartUp(true)
|
setDisplayHeadersAtStartUp(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of manga in this category.
|
* The list of manga in this category.
|
||||||
*/
|
*/
|
||||||
|
@ -619,13 +619,12 @@ class LibraryController(
|
|||||||
(listOfYs.minOrNull() ?: filter_bottom_sheet.y) +
|
(listOfYs.minOrNull() ?: filter_bottom_sheet.y) +
|
||||||
hopperOffset
|
hopperOffset
|
||||||
if (view.height - insetBottom < category_hopper_frame.y) {
|
if (view.height - insetBottom < category_hopper_frame.y) {
|
||||||
jumper_category_text.translationY = -(category_hopper_frame.y - (view.height - insetBottom))
|
jumper_category_text.translationY = -(category_hopper_frame.y - (view.height - insetBottom))
|
||||||
} else {
|
} else {
|
||||||
jumper_category_text.translationY = 0f
|
jumper_category_text.translationY = 0f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun resetHopperY() {
|
fun resetHopperY() {
|
||||||
hopperOffset = 0f
|
hopperOffset = 0f
|
||||||
}
|
}
|
||||||
@ -821,10 +820,11 @@ class LibraryController(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
adapter.setItems(mangaMap)
|
adapter.setItems(mangaMap)
|
||||||
if (recycler.itemAnimator == null)
|
if (recycler.itemAnimator == null) {
|
||||||
recycler.post {
|
recycler.post {
|
||||||
recycler.itemAnimator = DefaultItemAnimator()
|
recycler.itemAnimator = DefaultItemAnimator()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
singleCategory = presenter.categories.size <= 1
|
singleCategory = presenter.categories.size <= 1
|
||||||
showDropdown()
|
showDropdown()
|
||||||
progress.gone()
|
progress.gone()
|
||||||
|
@ -70,8 +70,9 @@ class LibraryGridHolder(
|
|||||||
if (cover_thumbnail.height == 0) {
|
if (cover_thumbnail.height == 0) {
|
||||||
val oldPos = adapterPosition
|
val oldPos = adapterPosition
|
||||||
adapter.recyclerView.post {
|
adapter.recyclerView.post {
|
||||||
if (oldPos == adapterPosition)
|
if (oldPos == adapterPosition) {
|
||||||
setCover(item.manga)
|
setCover(item.manga)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else setCover(item.manga)
|
} else setCover(item.manga)
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,9 @@ abstract class LibraryHolder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setReadingButton(item: LibraryItem) {
|
fun setReadingButton(item: LibraryItem) {
|
||||||
play_layout?.visibility = if (item.manga.unread > 0 && item.unreadType > 0 && !item.hideReadingButton)
|
play_layout?.visibility = if (item.manga.unread > 0 && item.unreadType > 0 && !item.hideReadingButton) {
|
||||||
View.VISIBLE else View.GONE
|
View.VISIBLE
|
||||||
|
} else View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,10 +46,11 @@ class LibraryItem(
|
|||||||
get() = preferences.hideStartReadingButton().getOrDefault()
|
get() = preferences.hideStartReadingButton().getOrDefault()
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return if (libraryLayout == 0 || manga.isBlank())
|
return if (libraryLayout == 0 || manga.isBlank()) {
|
||||||
R.layout.manga_list_item
|
R.layout.manga_list_item
|
||||||
else
|
} else {
|
||||||
R.layout.manga_grid_item
|
R.layout.manga_grid_item
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder {
|
||||||
@ -141,11 +142,13 @@ class LibraryItem(
|
|||||||
* @return true if the manga should be included, false otherwise.
|
* @return true if the manga should be included, false otherwise.
|
||||||
*/
|
*/
|
||||||
override fun filter(constraint: String): Boolean {
|
override fun filter(constraint: String): Boolean {
|
||||||
if (manga.isBlank() && manga.title.isBlank())
|
if (manga.isBlank() && manga.title.isBlank()) {
|
||||||
return constraint.isEmpty()
|
return constraint.isEmpty()
|
||||||
|
}
|
||||||
val sourceManager by injectLazy<SourceManager>()
|
val sourceManager by injectLazy<SourceManager>()
|
||||||
val sourceName = if (manga.source == 0L) "Local" else
|
val sourceName = if (manga.source == 0L) "Local" else {
|
||||||
sourceManager.getOrStub(manga.source).name
|
sourceManager.getOrStub(manga.source).name
|
||||||
|
}
|
||||||
return manga.title.contains(constraint, true) ||
|
return manga.title.contains(constraint, true) ||
|
||||||
(manga.author?.contains(constraint, true) ?: false) ||
|
(manga.author?.contains(constraint, true) ?: false) ||
|
||||||
(manga.artist?.contains(constraint, true) ?: false) ||
|
(manga.artist?.contains(constraint, true) ?: false) ||
|
||||||
@ -159,14 +162,15 @@ class LibraryItem(
|
|||||||
@SuppressLint("DefaultLocale")
|
@SuppressLint("DefaultLocale")
|
||||||
private fun containsGenre(tag: String, genres: List<String>?): Boolean {
|
private fun containsGenre(tag: String, genres: List<String>?): Boolean {
|
||||||
if (tag.trim().isEmpty()) return true
|
if (tag.trim().isEmpty()) return true
|
||||||
return if (tag.startsWith("-"))
|
return if (tag.startsWith("-")) {
|
||||||
genres?.find {
|
genres?.find {
|
||||||
it.trim().toLowerCase() == tag.substringAfter("-").toLowerCase()
|
it.trim().toLowerCase() == tag.substringAfter("-").toLowerCase()
|
||||||
} == null
|
} == null
|
||||||
else
|
} else {
|
||||||
genres?.find {
|
genres?.find {
|
||||||
it.trim().toLowerCase() == tag.toLowerCase()
|
it.trim().toLowerCase() == tag.toLowerCase()
|
||||||
} != null
|
} != null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
|
@ -36,7 +36,6 @@ class LibraryListHolder(
|
|||||||
* @param item the manga item to bind.
|
* @param item the manga item to bind.
|
||||||
*/
|
*/
|
||||||
override fun onSetValues(item: LibraryItem) {
|
override fun onSetValues(item: LibraryItem) {
|
||||||
|
|
||||||
title.visible()
|
title.visible()
|
||||||
constraint_layout.minHeight = 56.dpToPx
|
constraint_layout.minHeight = 56.dpToPx
|
||||||
if (item.manga.isBlank()) {
|
if (item.manga.isBlank()) {
|
||||||
@ -47,8 +46,9 @@ class LibraryListHolder(
|
|||||||
if (item.manga.status == -1) {
|
if (item.manga.status == -1) {
|
||||||
title.text = null
|
title.text = null
|
||||||
title.gone()
|
title.gone()
|
||||||
} else
|
} else {
|
||||||
title.text = itemView.context.getString(R.string.category_is_empty)
|
title.text = itemView.context.getString(R.string.category_is_empty)
|
||||||
|
}
|
||||||
title.textAlignment = View.TEXT_ALIGNMENT_CENTER
|
title.textAlignment = View.TEXT_ALIGNMENT_CENTER
|
||||||
card.gone()
|
card.gone()
|
||||||
badge_view.gone()
|
badge_view.gone()
|
||||||
|
@ -729,8 +729,9 @@ class LibraryPresenter(
|
|||||||
db.resetMangaInfo(manga).executeOnIO()
|
db.resetMangaInfo(manga).executeOnIO()
|
||||||
coverCache.deleteFromCache(manga)
|
coverCache.deleteFromCache(manga)
|
||||||
val source = sourceManager.get(manga.source) as? HttpSource
|
val source = sourceManager.get(manga.source) as? HttpSource
|
||||||
if (source != null)
|
if (source != null) {
|
||||||
downloadManager.deleteManga(manga, source)
|
downloadManager.deleteManga(manga, source)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -825,9 +826,10 @@ class LibraryPresenter(
|
|||||||
val mc = ArrayList<MangaCategory>()
|
val mc = ArrayList<MangaCategory>()
|
||||||
val categories =
|
val categories =
|
||||||
if (catId == 0) emptyList()
|
if (catId == 0) emptyList()
|
||||||
else
|
else {
|
||||||
db.getCategoriesForManga(manga).executeOnIO()
|
db.getCategoriesForManga(manga).executeOnIO()
|
||||||
.filter { it.id != oldCatId } + listOf(category)
|
.filter { it.id != oldCatId } + listOf(category)
|
||||||
|
}
|
||||||
|
|
||||||
for (cat in categories) {
|
for (cat in categories) {
|
||||||
mc.add(MangaCategory.create(manga, cat))
|
mc.add(MangaCategory.create(manga, cat))
|
||||||
@ -858,10 +860,11 @@ class LibraryPresenter(
|
|||||||
val categoriesHidden = preferences.collapsedCategories().getOrDefault().mapNotNull {
|
val categoriesHidden = preferences.collapsedCategories().getOrDefault().mapNotNull {
|
||||||
it.toIntOrNull()
|
it.toIntOrNull()
|
||||||
}.toMutableSet()
|
}.toMutableSet()
|
||||||
if (categoryId in categoriesHidden)
|
if (categoryId in categoriesHidden) {
|
||||||
categoriesHidden.remove(categoryId)
|
categoriesHidden.remove(categoryId)
|
||||||
else
|
} else {
|
||||||
categoriesHidden.add(categoryId)
|
categoriesHidden.add(categoryId)
|
||||||
|
}
|
||||||
preferences.collapsedCategories().set(categoriesHidden.map { it.toString() }.toMutableSet())
|
preferences.collapsedCategories().set(categoriesHidden.map { it.toString() }.toMutableSet())
|
||||||
getLibrary()
|
getLibrary()
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,9 @@ class CategoryRecyclerView @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
fastAdapter.onClickListener = { _, _, item, _ ->
|
fastAdapter.onClickListener = { _, _, item, _ ->
|
||||||
if (item.category.id != -1)
|
if (item.category.id != -1) {
|
||||||
onCategoryClicked(item.category.order)
|
onCategoryClicked(item.category.order)
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
|||||||
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
|
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
|
||||||
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
|
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
|
||||||
|
|
||||||
open class TabbedLibraryDisplaySheet(controller: LibraryController):
|
open class TabbedLibraryDisplaySheet(controller: LibraryController) :
|
||||||
TabbedBottomSheetDialog(controller.activity!!) {
|
TabbedBottomSheetDialog(controller.activity!!) {
|
||||||
|
|
||||||
private val displayView: LibraryDisplayView = inflate(controller.activity!!, R.layout.library_display_layout, null) as LibraryDisplayView
|
private val displayView: LibraryDisplayView = inflate(controller.activity!!, R.layout.library_display_layout, null) as LibraryDisplayView
|
||||||
@ -26,10 +26,12 @@ open class TabbedLibraryDisplaySheet(controller: LibraryController):
|
|||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||||
menu.tooltipText = context.getString(R.string.more_library_settings)
|
menu.tooltipText = context.getString(R.string.more_library_settings)
|
||||||
}
|
}
|
||||||
menu.setImageDrawable(ContextCompat.getDrawable(
|
menu.setImageDrawable(
|
||||||
context,
|
ContextCompat.getDrawable(
|
||||||
R.drawable.ic_settings_24dp
|
context,
|
||||||
))
|
R.drawable.ic_settings_24dp
|
||||||
|
)
|
||||||
|
)
|
||||||
menu.setOnClickListener {
|
menu.setOnClickListener {
|
||||||
controller.router.pushController(SettingsLibraryController().withFadeTransaction())
|
controller.router.pushController(SettingsLibraryController().withFadeTransaction())
|
||||||
dismiss()
|
dismiss()
|
||||||
|
@ -90,8 +90,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
list.add(unread)
|
list.add(unread)
|
||||||
list.add(downloaded)
|
list.add(downloaded)
|
||||||
list.add(completed)
|
list.add(completed)
|
||||||
if (hasTracking)
|
if (hasTracking) {
|
||||||
tracked?.let { list.add(it) }
|
tracked?.let { list.add(it) }
|
||||||
|
}
|
||||||
list
|
list
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,8 +153,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
}
|
}
|
||||||
|
|
||||||
val activeFilters = hasActiveFiltersFromPref()
|
val activeFilters = hasActiveFiltersFromPref()
|
||||||
if (activeFilters && sheetBehavior.isHidden() && sheetBehavior?.skipCollapsed == false)
|
if (activeFilters && sheetBehavior.isHidden() && sheetBehavior?.skipCollapsed == false) {
|
||||||
sheetBehavior?.collapse()
|
sheetBehavior?.collapse()
|
||||||
|
}
|
||||||
|
|
||||||
post {
|
post {
|
||||||
updateRootPadding(
|
updateRootPadding(
|
||||||
@ -218,10 +220,11 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
?: if (sheetBehavior.isExpanded()) 1f else 0f
|
?: if (sheetBehavior.isExpanded()) 1f else 0f
|
||||||
val percent = (trueProgress * 100).roundToInt()
|
val percent = (trueProgress * 100).roundToInt()
|
||||||
val value = (percent * (maxHeight - minHeight) / 100) + minHeight
|
val value = (percent * (maxHeight - minHeight) / 100) + minHeight
|
||||||
if (trueProgress >= 0)
|
if (trueProgress >= 0) {
|
||||||
libraryRecyler?.updatePaddingRelative(bottom = value + 10.dpToPx + bottomBarHeight)
|
libraryRecyler?.updatePaddingRelative(bottom = value + 10.dpToPx + bottomBarHeight)
|
||||||
else
|
} else {
|
||||||
libraryRecyler?.updatePaddingRelative(bottom = (minHeight * (1 + trueProgress)).toInt() + bottomBarHeight)
|
libraryRecyler?.updatePaddingRelative(bottom = (minHeight * (1 + trueProgress)).toInt() + bottomBarHeight)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasActiveFilters() = filterItems.any { it.isActivated }
|
fun hasActiveFilters() = filterItems.any { it.isActivated }
|
||||||
@ -235,7 +238,6 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createTags() {
|
private fun createTags() {
|
||||||
|
|
||||||
downloaded = inflate(R.layout.filter_buttons) as FilterTagGroup
|
downloaded = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||||
downloaded.setup(this, R.string.downloaded, R.string.not_downloaded)
|
downloaded.setup(this, R.string.downloaded, R.string.not_downloaded)
|
||||||
|
|
||||||
@ -372,8 +374,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
|
|
||||||
fun manageFilterPopup() {
|
fun manageFilterPopup() {
|
||||||
val recycler = RecyclerView(context)
|
val recycler = RecyclerView(context)
|
||||||
if (filterOrder.count() != 6)
|
if (filterOrder.count() != 6) {
|
||||||
filterOrder = "urdcmt"
|
filterOrder = "urdcmt"
|
||||||
|
}
|
||||||
val adapter = FlexibleAdapter(
|
val adapter = FlexibleAdapter(
|
||||||
filterOrder.toCharArray().map(::ManageFilterItem),
|
filterOrder.toCharArray().map(::ManageFilterItem),
|
||||||
this,
|
this,
|
||||||
@ -493,8 +496,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
|
|
||||||
private fun reSortViews() {
|
private fun reSortViews() {
|
||||||
filter_layout.removeAllViews()
|
filter_layout.removeAllViews()
|
||||||
if (filterItems.any { it.isActivated })
|
if (filterItems.any { it.isActivated }) {
|
||||||
filter_layout.addView(clearButton)
|
filter_layout.addView(clearButton)
|
||||||
|
}
|
||||||
filterItems.filter { it.isActivated }.forEach {
|
filterItems.filter { it.isActivated }.forEach {
|
||||||
filter_layout.addView(it)
|
filter_layout.addView(it)
|
||||||
}
|
}
|
||||||
|
@ -84,8 +84,9 @@ class FilterTagGroup@JvmOverloads constructor(context: Context, attrs: Attribute
|
|||||||
private fun toggleButton(index: Int, callBack: Boolean = true) {
|
private fun toggleButton(index: Int, callBack: Boolean = true) {
|
||||||
if (index < 0 || itemCount == 0 ||
|
if (index < 0 || itemCount == 0 ||
|
||||||
(isActivated && index != buttons.indexOfFirst { it.isActivated })
|
(isActivated && index != buttons.indexOfFirst { it.isActivated })
|
||||||
)
|
) {
|
||||||
return
|
return
|
||||||
|
}
|
||||||
if (callBack) {
|
if (callBack) {
|
||||||
val transition = androidx.transition.AutoTransition()
|
val transition = androidx.transition.AutoTransition()
|
||||||
transition.duration = 150
|
transition.duration = 150
|
||||||
|
@ -268,7 +268,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
container: ViewGroup,
|
container: ViewGroup,
|
||||||
handler: ControllerChangeHandler
|
handler: ControllerChangeHandler
|
||||||
) {
|
) {
|
||||||
|
|
||||||
syncActivityViewWithController(to, from, isPush)
|
syncActivityViewWithController(to, from, isPush)
|
||||||
appbar.y = 0f
|
appbar.y = 0f
|
||||||
bottom_nav.translationY = 0f
|
bottom_nav.translationY = 0f
|
||||||
@ -318,9 +317,9 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
window.navigationBarColor = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) {
|
window.navigationBarColor = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) {
|
||||||
// basically if in landscape on a phone
|
// basically if in landscape on a phone
|
||||||
// For lollipop, draw opaque nav bar
|
// For lollipop, draw opaque nav bar
|
||||||
if (insets.hasSideNavBar())
|
if (insets.hasSideNavBar()) {
|
||||||
Color.BLACK
|
Color.BLACK
|
||||||
else Color.argb(179, 0, 0, 0)
|
} else Color.argb(179, 0, 0, 0)
|
||||||
}
|
}
|
||||||
// if the android q+ device has gesture nav, transparent nav bar
|
// if the android q+ device has gesture nav, transparent nav bar
|
||||||
// this is here in case some crazy with a notch uses landscape
|
// this is here in case some crazy with a notch uses landscape
|
||||||
@ -515,10 +514,10 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
else !router.handleBack()
|
else !router.handleBack()
|
||||||
) {
|
) {
|
||||||
if (preferences.backReturnsToStart().get() && this !is SearchActivity &&
|
if (preferences.backReturnsToStart().get() && this !is SearchActivity &&
|
||||||
startingTab() != bottom_nav?.selectedItemId) {
|
startingTab() != bottom_nav?.selectedItemId
|
||||||
|
) {
|
||||||
goToStartingTab()
|
goToStartingTab()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (!preferences.backReturnsToStart().get() && this !is SearchActivity) {
|
if (!preferences.backReturnsToStart().get() && this !is SearchActivity) {
|
||||||
setStartingTab()
|
setStartingTab()
|
||||||
}
|
}
|
||||||
@ -529,13 +528,17 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setStartingTab() {
|
private fun setStartingTab() {
|
||||||
if (bottom_nav?.selectedItemId != R.id.nav_browse
|
if (bottom_nav?.selectedItemId != R.id.nav_browse &&
|
||||||
&& bottom_nav?.selectedItemId != null
|
bottom_nav?.selectedItemId != null &&
|
||||||
&& preferences.startingTab().get() >= 0)
|
preferences.startingTab().get() >= 0
|
||||||
preferences.startingTab().set(when (bottom_nav?.selectedItemId) {
|
) {
|
||||||
R.id.nav_library -> 0
|
preferences.startingTab().set(
|
||||||
else -> 1
|
when (bottom_nav?.selectedItemId) {
|
||||||
})
|
R.id.nav_library -> 0
|
||||||
|
else -> 1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@IdRes
|
@IdRes
|
||||||
|
@ -69,8 +69,9 @@ class EditMangaDialog : DialogController {
|
|||||||
val isLocal = manga.source == LocalSource.ID
|
val isLocal = manga.source == LocalSource.ID
|
||||||
|
|
||||||
if (isLocal) {
|
if (isLocal) {
|
||||||
if (manga.title != manga.url)
|
if (manga.title != manga.url) {
|
||||||
view.title.append(manga.title)
|
view.title.append(manga.title)
|
||||||
|
}
|
||||||
view.title.hint = "${resources?.getString(R.string.title)}: ${manga.url}"
|
view.title.hint = "${resources?.getString(R.string.title)}: ${manga.url}"
|
||||||
view.manga_author.append(manga.author ?: "")
|
view.manga_author.append(manga.author ?: "")
|
||||||
view.manga_artist.append(manga.artist ?: "")
|
view.manga_artist.append(manga.artist ?: "")
|
||||||
|
@ -434,8 +434,9 @@ class MangaDetailsController :
|
|||||||
setActionBar(true)
|
setActionBar(true)
|
||||||
setStatusBarAndToolbar()
|
setStatusBarAndToolbar()
|
||||||
} else if (type == ControllerChangeType.PUSH_EXIT || type == ControllerChangeType.POP_EXIT) {
|
} else if (type == ControllerChangeType.PUSH_EXIT || type == ControllerChangeType.POP_EXIT) {
|
||||||
if (router.backstack.lastOrNull()?.controller() is DialogController)
|
if (router.backstack.lastOrNull()?.controller() is DialogController) {
|
||||||
return
|
return
|
||||||
|
}
|
||||||
if (type == ControllerChangeType.POP_EXIT) {
|
if (type == ControllerChangeType.POP_EXIT) {
|
||||||
setActionBar(false)
|
setActionBar(false)
|
||||||
presenter.cancelScope()
|
presenter.cancelScope()
|
||||||
@ -1042,10 +1043,11 @@ class MangaDetailsController :
|
|||||||
if (chapter.status != Download.NOT_DOWNLOADED && chapter.status != Download.ERROR) {
|
if (chapter.status != Download.NOT_DOWNLOADED && chapter.status != Download.ERROR) {
|
||||||
presenter.deleteChapter(chapter)
|
presenter.deleteChapter(chapter)
|
||||||
} else {
|
} else {
|
||||||
if (chapter.status == Download.ERROR)
|
if (chapter.status == Download.ERROR) {
|
||||||
DownloadService.start(view.context)
|
DownloadService.start(view.context)
|
||||||
else
|
} else {
|
||||||
downloadChapters(listOf(chapter))
|
downloadChapters(listOf(chapter))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1279,8 +1281,9 @@ class MangaDetailsController :
|
|||||||
|
|
||||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
|
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
|
||||||
mode?.title = view?.context?.getString(
|
mode?.title = view?.context?.getString(
|
||||||
if (startingDLChapterPos == null)
|
if (startingDLChapterPos == null) {
|
||||||
R.string.select_starting_chapter else R.string.select_ending_chapter
|
R.string.select_starting_chapter
|
||||||
|
} else R.string.select_ending_chapter
|
||||||
)
|
)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import android.app.Application
|
|||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import coil.Coil
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
@ -88,7 +87,6 @@ class MangaDetailsPresenter(
|
|||||||
var headerItem = MangaHeaderItem(manga, controller.fromCatalogue)
|
var headerItem = MangaHeaderItem(manga, controller.fromCatalogue)
|
||||||
|
|
||||||
fun onCreate() {
|
fun onCreate() {
|
||||||
|
|
||||||
isLockedFromSearch = SecureActivityDelegate.shouldBeLocked()
|
isLockedFromSearch = SecureActivityDelegate.shouldBeLocked()
|
||||||
headerItem.isLocked = isLockedFromSearch
|
headerItem.isLocked = isLockedFromSearch
|
||||||
downloadManager.addListener(this)
|
downloadManager.addListener(this)
|
||||||
@ -218,8 +216,9 @@ class MangaDetailsPresenter(
|
|||||||
* @return an observable of the list of chapters filtered and sorted.
|
* @return an observable of the list of chapters filtered and sorted.
|
||||||
*/
|
*/
|
||||||
private fun applyChapterFilters(chapterList: List<ChapterItem>): List<ChapterItem> {
|
private fun applyChapterFilters(chapterList: List<ChapterItem>): List<ChapterItem> {
|
||||||
if (isLockedFromSearch)
|
if (isLockedFromSearch) {
|
||||||
return chapterList
|
return chapterList
|
||||||
|
}
|
||||||
|
|
||||||
val chapters = chapterFilter.filterChapters(chapterList, manga)
|
val chapters = chapterFilter.filterChapters(chapterList, manga)
|
||||||
|
|
||||||
@ -357,8 +356,8 @@ class MangaDetailsPresenter(
|
|||||||
if (newChapters.first.isNotEmpty()) {
|
if (newChapters.first.isNotEmpty()) {
|
||||||
if (manga.shouldDownloadNewChapters(db, preferences)) {
|
if (manga.shouldDownloadNewChapters(db, preferences)) {
|
||||||
downloadChapters(
|
downloadChapters(
|
||||||
newChapters.first.sortedBy { it.chapter_number }
|
newChapters.first.sortedBy { it.chapter_number }
|
||||||
.map { it.toModel() }
|
.map { it.toModel() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -867,8 +866,9 @@ class MangaDetailsPresenter(
|
|||||||
fun setStatus(item: TrackItem, index: Int) {
|
fun setStatus(item: TrackItem, index: Int) {
|
||||||
val track = item.track!!
|
val track = item.track!!
|
||||||
track.status = item.service.getStatusList()[index]
|
track.status = item.service.getStatusList()[index]
|
||||||
if (item.service.isCompletedStatus(index) && track.total_chapters > 0)
|
if (item.service.isCompletedStatus(index) && track.total_chapters > 0) {
|
||||||
track.last_chapter_read = track.total_chapters
|
track.last_chapter_read = track.total_chapters
|
||||||
|
}
|
||||||
updateRemote(track, item.service)
|
updateRemote(track, item.service)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@ class MangaHeaderHolder(
|
|||||||
}
|
}
|
||||||
if (event.actionMasked == MotionEvent.ACTION_UP) {
|
if (event.actionMasked == MotionEvent.ACTION_UP) {
|
||||||
hadSelection = manga_summary.hasSelection()
|
hadSelection = manga_summary.hasSelection()
|
||||||
(adapter.delegate as MangaDetailsController).swipe_refresh.isEnabled =
|
(adapter.delegate as MangaDetailsController).swipe_refresh.isEnabled =
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -320,9 +320,9 @@ class MangaHeaderHolder(
|
|||||||
fun collapse() {
|
fun collapse() {
|
||||||
sub_item_group.gone()
|
sub_item_group.gone()
|
||||||
start_reading_button.gone()
|
start_reading_button.gone()
|
||||||
if (more_button.visibility == View.VISIBLE || more_button.visibility == View.INVISIBLE)
|
if (more_button.visibility == View.VISIBLE || more_button.visibility == View.INVISIBLE) {
|
||||||
more_button_group.invisible()
|
more_button_group.invisible()
|
||||||
else {
|
} else {
|
||||||
less_button.gone()
|
less_button.gone()
|
||||||
manga_genres_tags.gone()
|
manga_genres_tags.gone()
|
||||||
}
|
}
|
||||||
|
@ -40,10 +40,11 @@ class ChaptersSortBottomSheet(controller: MangaDetailsController) : BottomSheetD
|
|||||||
sheetBehavior.addBottomSheetCallback(
|
sheetBehavior.addBottomSheetCallback(
|
||||||
object : BottomSheetBehavior.BottomSheetCallback() {
|
object : BottomSheetBehavior.BottomSheetCallback() {
|
||||||
override fun onSlide(bottomSheet: View, progress: Float) {
|
override fun onSlide(bottomSheet: View, progress: Float) {
|
||||||
if (progress.isNaN())
|
if (progress.isNaN()) {
|
||||||
pill.alpha = 0f
|
pill.alpha = 0f
|
||||||
else
|
} else {
|
||||||
pill.alpha = (1 - max(0f, progress)) * 0.25f
|
pill.alpha = (1 - max(0f, progress)) * 0.25f
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStateChanged(p0: View, state: Int) {
|
override fun onStateChanged(p0: View, state: Int) {
|
||||||
@ -92,14 +93,16 @@ class ChaptersSortBottomSheet(controller: MangaDetailsController) : BottomSheetD
|
|||||||
|
|
||||||
var defPref = presenter.globalSort()
|
var defPref = presenter.globalSort()
|
||||||
sort_group.check(
|
sort_group.check(
|
||||||
if (presenter.manga.sortDescending(defPref)) R.id.sort_newest else
|
if (presenter.manga.sortDescending(defPref)) R.id.sort_newest else {
|
||||||
R.id.sort_oldest
|
R.id.sort_oldest
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
hide_titles.isChecked = presenter.manga.displayMode != Manga.DISPLAY_NAME
|
hide_titles.isChecked = presenter.manga.displayMode != Manga.DISPLAY_NAME
|
||||||
sort_method_group.check(
|
sort_method_group.check(
|
||||||
if (presenter.manga.sorting == Manga.SORTING_SOURCE) R.id.sort_by_source else
|
if (presenter.manga.sorting == Manga.SORTING_SOURCE) R.id.sort_by_source else {
|
||||||
R.id.sort_by_number
|
R.id.sort_by_number
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
set_as_default_sort.visInvisIf(
|
set_as_default_sort.visInvisIf(
|
||||||
|
@ -70,12 +70,14 @@ class SetTrackReadingDatesDialog<T> : DialogController
|
|||||||
listener.setReadingDate(item, dateToUpdate, 0L)
|
listener.setReadingDate(item, dateToUpdate, 0L)
|
||||||
}.apply {
|
}.apply {
|
||||||
getSuggestedDate()?.let {
|
getSuggestedDate()?.let {
|
||||||
message(text = it,
|
message(
|
||||||
applySettings = {
|
text = it,
|
||||||
messageTextView.setOnClickListener {
|
applySettings = {
|
||||||
this@apply.setDate(suggestedDate ?: 0L)
|
messageTextView.setOnClickListener {
|
||||||
|
this@apply.setDate(suggestedDate ?: 0L)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,9 +95,11 @@ class SetTrackReadingDatesDialog<T> : DialogController
|
|||||||
val suggestedCalendar = Calendar.getInstance()
|
val suggestedCalendar = Calendar.getInstance()
|
||||||
suggestedCalendar.timeInMillis = suggestedDate
|
suggestedCalendar.timeInMillis = suggestedDate
|
||||||
return if (date > suggestedDate &&
|
return if (date > suggestedDate &&
|
||||||
(suggestedCalendar.year != calendar.year ||
|
(
|
||||||
suggestedCalendar.month != calendar.month ||
|
suggestedCalendar.year != calendar.year ||
|
||||||
suggestedCalendar.dayOfMonth != calendar.dayOfMonth)
|
suggestedCalendar.month != calendar.month ||
|
||||||
|
suggestedCalendar.dayOfMonth != calendar.dayOfMonth
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
activity?.getString(
|
activity?.getString(
|
||||||
R.string.suggested_date_,
|
R.string.suggested_date_,
|
||||||
|
@ -72,9 +72,9 @@ class TrackHolder(view: View, adapter: TrackAdapter) : BaseViewHolder(view) {
|
|||||||
date_group.visibleIf(item.service.supportsReadingDates)
|
date_group.visibleIf(item.service.supportsReadingDates)
|
||||||
if (item.service.supportsReadingDates) {
|
if (item.service.supportsReadingDates) {
|
||||||
track_start_date.text =
|
track_start_date.text =
|
||||||
if (track.started_reading_date != 0L) dateFormat.format(track.started_reading_date) else "-"
|
if (track.started_reading_date != 0L) dateFormat.format(track.started_reading_date) else "-"
|
||||||
track_finish_date.text =
|
track_finish_date.text =
|
||||||
if (track.finished_reading_date != 0L) dateFormat.format(track.finished_reading_date) else "-"
|
if (track.finished_reading_date != 0L) dateFormat.format(track.finished_reading_date) else "-"
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.manga.track
|
package eu.kanade.tachiyomi.ui.manga.track
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -190,11 +188,13 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) :
|
|||||||
if (item.track == null) return
|
if (item.track == null) return
|
||||||
|
|
||||||
val suggestedDate = presenter.getSuggestedDate(SetTrackReadingDatesDialog.ReadingDate.Start)
|
val suggestedDate = presenter.getSuggestedDate(SetTrackReadingDatesDialog.ReadingDate.Start)
|
||||||
SetTrackReadingDatesDialog(controller,
|
SetTrackReadingDatesDialog(
|
||||||
|
controller,
|
||||||
this,
|
this,
|
||||||
SetTrackReadingDatesDialog.ReadingDate.Start,
|
SetTrackReadingDatesDialog.ReadingDate.Start,
|
||||||
item,
|
item,
|
||||||
suggestedDate)
|
suggestedDate
|
||||||
|
)
|
||||||
.showDialog(controller.router)
|
.showDialog(controller.router)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,11 +203,13 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) :
|
|||||||
if (item.track == null) return
|
if (item.track == null) return
|
||||||
|
|
||||||
val suggestedDate = presenter.getSuggestedDate(SetTrackReadingDatesDialog.ReadingDate.Finish)
|
val suggestedDate = presenter.getSuggestedDate(SetTrackReadingDatesDialog.ReadingDate.Finish)
|
||||||
SetTrackReadingDatesDialog(controller,
|
SetTrackReadingDatesDialog(
|
||||||
|
controller,
|
||||||
this,
|
this,
|
||||||
SetTrackReadingDatesDialog.ReadingDate.Finish,
|
SetTrackReadingDatesDialog.ReadingDate.Finish,
|
||||||
item,
|
item,
|
||||||
suggestedDate)
|
suggestedDate
|
||||||
|
)
|
||||||
.showDialog(controller.router)
|
.showDialog(controller.router)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,5 +259,4 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) :
|
|||||||
private companion object {
|
private companion object {
|
||||||
const val TAG_SEARCH_CONTROLLER = "track_search_controller"
|
const val TAG_SEARCH_CONTROLLER = "track_search_controller"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ class MangaItem(val manga: Manga) : AbstractFlexibleItem<MangaHolder>() {
|
|||||||
position: Int,
|
position: Int,
|
||||||
payloads: MutableList<Any?>?
|
payloads: MutableList<Any?>?
|
||||||
) {
|
) {
|
||||||
|
|
||||||
holder.bind(this)
|
holder.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +93,6 @@ class MigrationPresenter(
|
|||||||
manga: Manga,
|
manga: Manga,
|
||||||
replace: Boolean
|
replace: Boolean
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val flags = preferences.migrateFlags().getOrDefault()
|
val flags = preferences.migrateFlags().getOrDefault()
|
||||||
val migrateChapters = MigrationFlags.hasChapters(flags)
|
val migrateChapters = MigrationFlags.hasChapters(flags)
|
||||||
val migrateCategories = MigrationFlags.hasCategories(flags)
|
val migrateCategories = MigrationFlags.hasCategories(flags)
|
||||||
|
@ -42,8 +42,9 @@ class SearchController(
|
|||||||
override fun getTitle(): String? {
|
override fun getTitle(): String? {
|
||||||
if (totalProgress > 1) {
|
if (totalProgress > 1) {
|
||||||
return "($progress/$totalProgress) ${super.getTitle()}"
|
return "($progress/$totalProgress) ${super.getTitle()}"
|
||||||
} else
|
} else {
|
||||||
return super.getTitle()
|
return super.getTitle()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createPresenter(): GlobalSearchPresenter {
|
override fun createPresenter(): GlobalSearchPresenter {
|
||||||
|
@ -40,7 +40,6 @@ data class SourceItem(val source: Source, val header: SelectionHeader? = null) :
|
|||||||
position: Int,
|
position: Int,
|
||||||
payloads: MutableList<Any?>?
|
payloads: MutableList<Any?>?
|
||||||
) {
|
) {
|
||||||
|
|
||||||
holder.bind(this)
|
holder.bind(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.migration.manga.design
|
|||||||
import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG
|
import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
|
||||||
import eu.kanade.tachiyomi.source.icon
|
import eu.kanade.tachiyomi.source.icon
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
||||||
|
@ -15,7 +15,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
|
|||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||||
|
@ -54,7 +54,6 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.sync.Semaphore
|
import kotlinx.coroutines.sync.Semaphore
|
||||||
import kotlinx.coroutines.sync.withPermit
|
import kotlinx.coroutines.sync.withPermit
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import rx.schedulers.Schedulers
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
@ -99,7 +98,6 @@ class MigrationListController(bundle: Bundle? = null) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View) {
|
override fun onViewCreated(view: View) {
|
||||||
|
|
||||||
super.onViewCreated(view)
|
super.onViewCreated(view)
|
||||||
liftAppbarWith(recycler)
|
liftAppbarWith(recycler)
|
||||||
setTitle()
|
setTitle()
|
||||||
@ -324,7 +322,6 @@ class MigrationListController(bundle: Bundle? = null) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onMenuItemClick(position: Int, item: MenuItem) {
|
override fun onMenuItemClick(position: Int, item: MenuItem) {
|
||||||
|
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_search_manually -> {
|
R.id.action_search_manually -> {
|
||||||
launchUI {
|
launchUI {
|
||||||
@ -377,7 +374,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
|||||||
try {
|
try {
|
||||||
val newManga =
|
val newManga =
|
||||||
sourceManager.getOrStub(result.source).getMangaDetails(result.toMangaInfo())
|
sourceManager.getOrStub(result.source).getMangaDetails(result.toMangaInfo())
|
||||||
.toSManga()
|
.toSManga()
|
||||||
result.copyFrom(newManga)
|
result.copyFrom(newManga)
|
||||||
|
|
||||||
db.insertManga(result).executeAsBlocking()
|
db.insertManga(result).executeAsBlocking()
|
||||||
|
@ -33,7 +33,6 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
|
|
||||||
import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity
|
import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity
|
||||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||||
import eu.kanade.tachiyomi.ui.main.SearchActivity
|
import eu.kanade.tachiyomi.ui.main.SearchActivity
|
||||||
@ -283,8 +282,10 @@ class ReaderActivity :
|
|||||||
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
|
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
|
||||||
val detailsItem = menu?.findItem(R.id.action_manga_details)
|
val detailsItem = menu?.findItem(R.id.action_manga_details)
|
||||||
if (presenter.manga?.mangaType(this) != null) {
|
if (presenter.manga?.mangaType(this) != null) {
|
||||||
detailsItem?.title = getString(R.string._details,
|
detailsItem?.title = getString(
|
||||||
presenter.manga?.mangaType(this)?.capitalize(Locale.ROOT) ?: "")
|
R.string._details,
|
||||||
|
presenter.manga?.mangaType(this)?.capitalize(Locale.ROOT) ?: ""
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
detailsItem?.title = getString(R.string.details)
|
detailsItem?.title = getString(R.string.details)
|
||||||
}
|
}
|
||||||
@ -798,7 +799,6 @@ class ReaderActivity :
|
|||||||
*/
|
*/
|
||||||
private fun setNotchCutoutMode() {
|
private fun setNotchCutoutMode() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
|
|
||||||
val currentOrientation = resources.configuration.orientation
|
val currentOrientation = resources.configuration.orientation
|
||||||
|
|
||||||
val params = window.attributes
|
val params = window.attributes
|
||||||
@ -941,10 +941,11 @@ class ReaderActivity :
|
|||||||
* Sets the 32-bit color mode according to [enabled].
|
* Sets the 32-bit color mode according to [enabled].
|
||||||
*/
|
*/
|
||||||
private fun setTrueColor(enabled: Boolean) {
|
private fun setTrueColor(enabled: Boolean) {
|
||||||
if (enabled)
|
if (enabled) {
|
||||||
SubsamplingScaleImageView.setPreferredBitmapConfig(Bitmap.Config.ARGB_8888)
|
SubsamplingScaleImageView.setPreferredBitmapConfig(Bitmap.Config.ARGB_8888)
|
||||||
else
|
} else {
|
||||||
SubsamplingScaleImageView.setPreferredBitmapConfig(Bitmap.Config.RGB_565)
|
SubsamplingScaleImageView.setPreferredBitmapConfig(Bitmap.Config.RGB_565)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +38,6 @@ class SaveImageNotifier(private val context: Context) {
|
|||||||
* @param file image file containing downloaded page image.
|
* @param file image file containing downloaded page image.
|
||||||
*/
|
*/
|
||||||
fun onComplete(file: File) {
|
fun onComplete(file: File) {
|
||||||
|
|
||||||
val request = LoadRequest.Builder(context).memoryCachePolicy(CachePolicy.DISABLED).diskCachePolicy(CachePolicy.DISABLED)
|
val request = LoadRequest.Builder(context).memoryCachePolicy(CachePolicy.DISABLED).diskCachePolicy(CachePolicy.DISABLED)
|
||||||
.data(file)
|
.data(file)
|
||||||
.size(720, 1280)
|
.size(720, 1280)
|
||||||
@ -64,8 +63,9 @@ class SaveImageNotifier(private val context: Context) {
|
|||||||
setAutoCancel(true)
|
setAutoCancel(true)
|
||||||
color = ContextCompat.getColor(context, R.color.colorAccent)
|
color = ContextCompat.getColor(context, R.color.colorAccent)
|
||||||
// Clear old actions if they exist
|
// Clear old actions if they exist
|
||||||
if (mActions.isNotEmpty())
|
if (mActions.isNotEmpty()) {
|
||||||
mActions.clear()
|
mActions.clear()
|
||||||
|
}
|
||||||
|
|
||||||
setContentIntent(NotificationHandler.openImagePendingActivity(context, file))
|
setContentIntent(NotificationHandler.openImagePendingActivity(context, file))
|
||||||
// Share action
|
// Share action
|
||||||
|
@ -192,10 +192,11 @@ class HttpPageLoader(
|
|||||||
* @param page the page whose source image has to be downloaded.
|
* @param page the page whose source image has to be downloaded.
|
||||||
*/
|
*/
|
||||||
private fun HttpSource.fetchImageFromCacheThenNet(page: ReaderPage): Observable<ReaderPage> {
|
private fun HttpSource.fetchImageFromCacheThenNet(page: ReaderPage): Observable<ReaderPage> {
|
||||||
return if (page.imageUrl.isNullOrEmpty())
|
return if (page.imageUrl.isNullOrEmpty()) {
|
||||||
getImageUrl(page).flatMap { getCachedImage(it) }
|
getImageUrl(page).flatMap { getCachedImage(it) }
|
||||||
else
|
} else {
|
||||||
getCachedImage(page)
|
getCachedImage(page)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun HttpSource.getImageUrl(page: ReaderPage): Observable<ReaderPage> {
|
private fun HttpSource.getImageUrl(page: ReaderPage): Observable<ReaderPage> {
|
||||||
|
@ -5,9 +5,7 @@ import android.util.AttributeSet
|
|||||||
import android.widget.SeekBar
|
import android.widget.SeekBar
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
|
|
||||||
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
|
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
|
||||||
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
|
|
||||||
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
|
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
|
||||||
import kotlinx.android.synthetic.main.reader_color_filter.*
|
import kotlinx.android.synthetic.main.reader_color_filter.*
|
||||||
import kotlinx.android.synthetic.main.reader_color_filter.view.*
|
import kotlinx.android.synthetic.main.reader_color_filter.view.*
|
||||||
@ -115,7 +113,6 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set enabled status of seekBars belonging to color filter
|
* Set enabled status of seekBars belonging to color filter
|
||||||
* @param enabled determines if seekBar gets enabled
|
* @param enabled determines if seekBar gets enabled
|
||||||
@ -202,7 +199,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
|
|||||||
* Sets the color filter overlay of the screen. Determined by HEX of integer
|
* Sets the color filter overlay of the screen. Determined by HEX of integer
|
||||||
* @param color hex of color.
|
* @param color hex of color.
|
||||||
*/
|
*/
|
||||||
private fun setColorFilterValue(@ColorInt color: Int) {
|
private fun setColorFilterValue(@ColorInt color: Int) {
|
||||||
setValues(color)
|
setValues(color)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,7 @@ import android.content.Context
|
|||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
import eu.kanade.tachiyomi.util.bindToPreference
|
import eu.kanade.tachiyomi.util.bindToPreference
|
||||||
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
|
|
||||||
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
|
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
|
||||||
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
|
|
||||||
import kotlinx.android.synthetic.main.reader_general_layout.view.*
|
import kotlinx.android.synthetic.main.reader_general_layout.view.*
|
||||||
|
|
||||||
class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
|
@ -12,16 +12,14 @@ import com.tfcporciuncula.flow.Preference
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import kotlinx.android.synthetic.main.reader_preference.view.*
|
import kotlinx.android.synthetic.main.reader_preference.view.*
|
||||||
|
|
||||||
|
|
||||||
class ReaderSpinnerView @JvmOverloads constructor(context: Context, attrs: AttributeSet?) :
|
class ReaderSpinnerView @JvmOverloads constructor(context: Context, attrs: AttributeSet?) :
|
||||||
FrameLayout(context, attrs) {
|
FrameLayout(context, attrs) {
|
||||||
|
|
||||||
|
|
||||||
private var entries = emptyList<String>()
|
private var entries = emptyList<String>()
|
||||||
private var selectedPosition = 0
|
private var selectedPosition = 0
|
||||||
private var pref: Preference<Int>? = null
|
private var pref: Preference<Int>? = null
|
||||||
private var prefOffset = 0
|
private var prefOffset = 0
|
||||||
private var popup:PopupMenu? = null
|
private var popup: PopupMenu? = null
|
||||||
|
|
||||||
var onItemSelectedListener: ((Int) -> Unit)? = null
|
var onItemSelectedListener: ((Int) -> Unit)? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
@ -159,7 +157,7 @@ class ReaderSpinnerView @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
|
|
||||||
fun popup(): PopupMenu {
|
fun popup(): PopupMenu {
|
||||||
val popup = PopupMenu(context, this, Gravity.END)
|
val popup = PopupMenu(context, this, Gravity.END)
|
||||||
entries.forEachIndexed { index, entry ->
|
entries.forEachIndexed { index, entry ->
|
||||||
popup.menu.add(0, index, 0, entry)
|
popup.menu.add(0, index, 0, entry)
|
||||||
}
|
}
|
||||||
popup.menu[selectedPosition].isCheckable = true
|
popup.menu[selectedPosition].isCheckable = true
|
||||||
|
@ -1,22 +1,19 @@
|
|||||||
package eu.kanade.tachiyomi.ui.reader.settings
|
package eu.kanade.tachiyomi.ui.reader.settings
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.widget.NestedScrollView
|
|
||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.library.display.LibraryBadgesView
|
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
import eu.kanade.tachiyomi.util.view.gone
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
import eu.kanade.tachiyomi.util.view.visInvisIf
|
import eu.kanade.tachiyomi.util.view.visInvisIf
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
import eu.kanade.tachiyomi.util.view.visibleIf
|
|
||||||
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
|
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
|
||||||
import kotlinx.android.synthetic.main.reader_activity.*
|
import kotlinx.android.synthetic.main.reader_activity.*
|
||||||
import kotlinx.android.synthetic.main.reader_color_filter.view.*
|
import kotlinx.android.synthetic.main.reader_color_filter.view.*
|
||||||
import kotlinx.android.synthetic.main.recycler_with_scroller.view.*
|
import kotlinx.android.synthetic.main.recycler_with_scroller.view.*
|
||||||
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
|
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
|
||||||
|
|
||||||
class TabbedReaderSettingsSheet(val readerActivity: ReaderActivity): TabbedBottomSheetDialog(
|
class TabbedReaderSettingsSheet(val readerActivity: ReaderActivity) : TabbedBottomSheetDialog(
|
||||||
readerActivity
|
readerActivity
|
||||||
) {
|
) {
|
||||||
private val generalView: ReaderGeneralView = View.inflate(
|
private val generalView: ReaderGeneralView = View.inflate(
|
||||||
|
@ -27,7 +27,6 @@ abstract class ViewerConfig(preferences: PreferencesHelper) {
|
|||||||
var volumeKeysInverted = false
|
var volumeKeysInverted = false
|
||||||
var alwaysShowChapterTransition = true
|
var alwaysShowChapterTransition = true
|
||||||
|
|
||||||
|
|
||||||
var navigationOverlayForNewUser = false
|
var navigationOverlayForNewUser = false
|
||||||
var navigationMode = 0
|
var navigationMode = 0
|
||||||
protected set
|
protected set
|
||||||
|
@ -17,8 +17,7 @@ abstract class ViewerNavigation {
|
|||||||
fun directionalRegion(LTR: Boolean): NavigationRegion {
|
fun directionalRegion(LTR: Boolean): NavigationRegion {
|
||||||
return if (this === LEFT || this === RIGHT) {
|
return if (this === LEFT || this === RIGHT) {
|
||||||
if (if (LTR) this === LEFT else this === RIGHT) NEXT else PREV
|
if (if (LTR) this === LEFT else this === RIGHT) NEXT else PREV
|
||||||
}
|
} else this
|
||||||
else this
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,9 +45,12 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe
|
|||||||
.register({ navigationMode = it }, { updateNavigation(navigationMode) })
|
.register({ navigationMode = it }, { updateNavigation(navigationMode) })
|
||||||
|
|
||||||
preferences.pagerNavInverted()
|
preferences.pagerNavInverted()
|
||||||
.register({ tappingInverted = it }, {
|
.register(
|
||||||
navigator.invertMode = it
|
{ tappingInverted = it },
|
||||||
})
|
{
|
||||||
|
navigator.invertMode = it
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
preferences.pagerNavInverted().asFlow()
|
preferences.pagerNavInverted().asFlow()
|
||||||
.drop(1)
|
.drop(1)
|
||||||
|
@ -340,7 +340,6 @@ class PagerPageHolder(
|
|||||||
@SuppressLint("PrivateResource")
|
@SuppressLint("PrivateResource")
|
||||||
private fun createProgressBar(): ReaderProgressBar {
|
private fun createProgressBar(): ReaderProgressBar {
|
||||||
return ReaderProgressBar(context, null).apply {
|
return ReaderProgressBar(context, null).apply {
|
||||||
|
|
||||||
val size = 48.dpToPx
|
val size = 48.dpToPx
|
||||||
layoutParams = LayoutParams(size, size).apply {
|
layoutParams = LayoutParams(size, size).apply {
|
||||||
gravity = Gravity.CENTER
|
gravity = Gravity.CENTER
|
||||||
|
@ -24,6 +24,7 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
|
|||||||
private set
|
private set
|
||||||
|
|
||||||
var currentChapter: ReaderChapter? = null
|
var currentChapter: ReaderChapter? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates this adapter with the given [chapters]. It handles setting a few pages of the
|
* Updates this adapter with the given [chapters]. It handles setting a few pages of the
|
||||||
* next/previous chapter to allow seamless transitions and inverting the pages if the viewer
|
* next/previous chapter to allow seamless transitions and inverting the pages if the viewer
|
||||||
|
@ -22,6 +22,7 @@ class WebtoonAdapter(val viewer: WebtoonViewer) : RecyclerView.Adapter<RecyclerV
|
|||||||
private set
|
private set
|
||||||
|
|
||||||
var currentChapter: ReaderChapter? = null
|
var currentChapter: ReaderChapter? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates this adapter with the given [chapters]. It handles setting a few pages of the
|
* Updates this adapter with the given [chapters]. It handles setting a few pages of the
|
||||||
* next/previous chapter to allow seamless transitions.
|
* next/previous chapter to allow seamless transitions.
|
||||||
|
@ -37,9 +37,12 @@ class WebtoonConfig(preferences: PreferencesHelper = Injekt.get()) : ViewerConfi
|
|||||||
.register({ navigationMode = it }, { updateNavigation(it) })
|
.register({ navigationMode = it }, { updateNavigation(it) })
|
||||||
|
|
||||||
preferences.webtoonNavInverted()
|
preferences.webtoonNavInverted()
|
||||||
.register({ tappingInverted = it }, {
|
.register(
|
||||||
navigator.invertMode = it
|
{ tappingInverted = it },
|
||||||
})
|
{
|
||||||
|
navigator.invertMode = it
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
preferences.webtoonNavInverted().asFlow()
|
preferences.webtoonNavInverted().asFlow()
|
||||||
.drop(1)
|
.drop(1)
|
||||||
|
@ -42,12 +42,13 @@ class WebtoonLayoutManager(activity: ReaderActivity) : LinearLayoutManager(activ
|
|||||||
val fromIndex = childCount - 1
|
val fromIndex = childCount - 1
|
||||||
val toIndex = -1
|
val toIndex = -1
|
||||||
|
|
||||||
val child = if (mOrientation == HORIZONTAL)
|
val child = if (mOrientation == HORIZONTAL) {
|
||||||
mHorizontalBoundCheck
|
mHorizontalBoundCheck
|
||||||
.findOneViewWithinBoundFlags(fromIndex, toIndex, preferredBoundsFlag, 0)
|
.findOneViewWithinBoundFlags(fromIndex, toIndex, preferredBoundsFlag, 0)
|
||||||
else
|
} else {
|
||||||
mVerticalBoundCheck
|
mVerticalBoundCheck
|
||||||
.findOneViewWithinBoundFlags(fromIndex, toIndex, preferredBoundsFlag, 0)
|
.findOneViewWithinBoundFlags(fromIndex, toIndex, preferredBoundsFlag, 0)
|
||||||
|
}
|
||||||
|
|
||||||
return if (child == null) NO_POSITION else getPosition(child)
|
return if (child == null) NO_POSITION else getPosition(child)
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ class WebtoonViewer(val activity: ReaderActivity, val hasMargins: Boolean = fals
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
recycler.tapListener = f@{ event ->
|
recycler.tapListener = f@{ event ->
|
||||||
if (!config.tappingEnabled) {
|
if (!config.tappingEnabled) {
|
||||||
activity.toggleMenu()
|
activity.toggleMenu()
|
||||||
return@f
|
return@f
|
||||||
|
@ -44,6 +44,7 @@ class RecentlyReadController(bundle: Bundle? = null) :
|
|||||||
init {
|
init {
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter containing the recent manga.
|
* Adapter containing the recent manga.
|
||||||
*/
|
*/
|
||||||
@ -85,8 +86,9 @@ class RecentlyReadController(bundle: Bundle? = null) :
|
|||||||
resetProgressItem()
|
resetProgressItem()
|
||||||
scrollViewWith(recycler, padBottom = true)
|
scrollViewWith(recycler, padBottom = true)
|
||||||
|
|
||||||
if (recentItems != null)
|
if (recentItems != null) {
|
||||||
adapter?.updateDataSet(recentItems!!.toList())
|
adapter?.updateDataSet(recentItems!!.toList())
|
||||||
|
}
|
||||||
|
|
||||||
launchUI {
|
launchUI {
|
||||||
val manga = presenter.refresh(query)
|
val manga = presenter.refresh(query)
|
||||||
@ -106,6 +108,7 @@ class RecentlyReadController(bundle: Bundle? = null) :
|
|||||||
observeLater = false
|
observeLater = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate adapter with chapters
|
* Populate adapter with chapters
|
||||||
*
|
*
|
||||||
@ -115,8 +118,9 @@ class RecentlyReadController(bundle: Bundle? = null) :
|
|||||||
val adapter = adapter ?: return
|
val adapter = adapter ?: return
|
||||||
adapter.updateDataSet(mangaHistory)
|
adapter.updateDataSet(mangaHistory)
|
||||||
adapter.onLoadMoreComplete(null)
|
adapter.onLoadMoreComplete(null)
|
||||||
if (recentItems == null)
|
if (recentItems == null) {
|
||||||
resetProgressItem()
|
resetProgressItem()
|
||||||
|
}
|
||||||
recentItems = mangaHistory.toMutableList()
|
recentItems = mangaHistory.toMutableList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ class RecentlyReadItem(val mch: MangaChapterHistory) : AbstractFlexibleItem<Rece
|
|||||||
position: Int,
|
position: Int,
|
||||||
payloads: MutableList<Any?>?
|
payloads: MutableList<Any?>?
|
||||||
) {
|
) {
|
||||||
|
|
||||||
holder.bind(mch)
|
holder.bind(mch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@ import eu.kanade.tachiyomi.util.system.dpToPx
|
|||||||
import eu.kanade.tachiyomi.util.system.spToPx
|
import eu.kanade.tachiyomi.util.system.spToPx
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.expand
|
import eu.kanade.tachiyomi.util.view.expand
|
||||||
import eu.kanade.tachiyomi.util.view.isCollapsed
|
|
||||||
import eu.kanade.tachiyomi.util.view.isExpanded
|
import eu.kanade.tachiyomi.util.view.isExpanded
|
||||||
import eu.kanade.tachiyomi.util.view.requestPermissionsSafe
|
import eu.kanade.tachiyomi.util.view.requestPermissionsSafe
|
||||||
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
||||||
@ -95,9 +94,9 @@ class RecentsController(bundle: Bundle? = null) :
|
|||||||
var headerHeight = 0
|
var headerHeight = 0
|
||||||
|
|
||||||
override fun getTitle(): String? {
|
override fun getTitle(): String? {
|
||||||
return if (showingDownloads)
|
return if (showingDownloads) {
|
||||||
resources?.getString(R.string.download_queue)
|
resources?.getString(R.string.download_queue)
|
||||||
else resources?.getString(R.string.recents)
|
} else resources?.getString(R.string.recents)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
|
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
|
||||||
@ -243,8 +242,9 @@ class RecentsController(bundle: Bundle? = null) :
|
|||||||
val pad = bottomBar.translationY - bottomBar.height
|
val pad = bottomBar.translationY - bottomBar.height
|
||||||
val padding = max(
|
val padding = max(
|
||||||
(-pad).toInt(),
|
(-pad).toInt(),
|
||||||
if (dl_bottom_sheet.sheetBehavior.isExpanded()) 0 else
|
if (dl_bottom_sheet.sheetBehavior.isExpanded()) 0 else {
|
||||||
view?.rootWindowInsets?.systemWindowInsetBottom ?: 0
|
view?.rootWindowInsets?.systemWindowInsetBottom ?: 0
|
||||||
|
}
|
||||||
)
|
)
|
||||||
shadow2.translationY = pad
|
shadow2.translationY = pad
|
||||||
dl_bottom_sheet.sheetBehavior?.peekHeight = 48.spToPx + padding
|
dl_bottom_sheet.sheetBehavior?.peekHeight = 48.spToPx + padding
|
||||||
@ -303,8 +303,9 @@ class RecentsController(bundle: Bundle? = null) :
|
|||||||
swipe_refresh.isRefreshing = LibraryUpdateService.isRunning()
|
swipe_refresh.isRefreshing = LibraryUpdateService.isRunning()
|
||||||
adapter.updateItems(recents)
|
adapter.updateItems(recents)
|
||||||
adapter.removeAllScrollableHeaders()
|
adapter.removeAllScrollableHeaders()
|
||||||
if (presenter.viewType > 0)
|
if (presenter.viewType > 0) {
|
||||||
adapter.addScrollableHeader(presenter.generalHeader)
|
adapter.addScrollableHeader(presenter.generalHeader)
|
||||||
|
}
|
||||||
if (lastChapterId != null) {
|
if (lastChapterId != null) {
|
||||||
refreshItem(lastChapterId ?: 0L)
|
refreshItem(lastChapterId ?: 0L)
|
||||||
lastChapterId = null
|
lastChapterId = null
|
||||||
@ -380,8 +381,9 @@ class RecentsController(bundle: Bundle? = null) :
|
|||||||
val manga = item.mch.manga
|
val manga = item.mch.manga
|
||||||
val history = item.mch.history
|
val history = item.mch.history
|
||||||
val chapter = item.mch.chapter
|
val chapter = item.mch.chapter
|
||||||
if (history.id != null)
|
if (history.id != null) {
|
||||||
RemoveHistoryDialog(this, manga, history, chapter).showDialog(router)
|
RemoveHistoryDialog(this, manga, history, chapter).showDialog(router)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun removeHistory(manga: Manga, history: History, all: Boolean) {
|
override fun removeHistory(manga: Manga, history: History, all: Boolean) {
|
||||||
@ -476,7 +478,7 @@ class RecentsController(bundle: Bundle? = null) :
|
|||||||
setBottomPadding()
|
setBottomPadding()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onChangeEnded(handler: ControllerChangeHandler, type: ControllerChangeType ) {
|
override fun onChangeEnded(handler: ControllerChangeHandler, type: ControllerChangeType) {
|
||||||
super.onChangeEnded(handler, type)
|
super.onChangeEnded(handler, type)
|
||||||
if (type == ControllerChangeType.POP_ENTER) setBottomPadding()
|
if (type == ControllerChangeType.POP_ENTER) setBottomPadding()
|
||||||
}
|
}
|
||||||
@ -484,8 +486,9 @@ class RecentsController(bundle: Bundle? = null) :
|
|||||||
fun hasQueue() = presenter.downloadManager.hasQueue()
|
fun hasQueue() = presenter.downloadManager.hasQueue()
|
||||||
|
|
||||||
override fun showSheet() {
|
override fun showSheet() {
|
||||||
if (dl_bottom_sheet.sheetBehavior?.isHideable == false || hasQueue())
|
if (dl_bottom_sheet.sheetBehavior?.isHideable == false || hasQueue()) {
|
||||||
dl_bottom_sheet.sheetBehavior?.expand()
|
dl_bottom_sheet.sheetBehavior?.expand()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toggleSheet() {
|
override fun toggleSheet() {
|
||||||
@ -498,13 +501,15 @@ class RecentsController(bundle: Bundle? = null) :
|
|||||||
override fun expandSearch() {
|
override fun expandSearch() {
|
||||||
if (showingDownloads) {
|
if (showingDownloads) {
|
||||||
dl_bottom_sheet.dismiss()
|
dl_bottom_sheet.dismiss()
|
||||||
} else
|
} else {
|
||||||
activity?.toolbar?.menu?.findItem(R.id.action_search)?.expandActionView()
|
activity?.toolbar?.menu?.findItem(R.id.action_search)?.expandActionView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
if (showingDownloads)
|
if (showingDownloads) {
|
||||||
return dl_bottom_sheet.onOptionsItemSelected(item)
|
return dl_bottom_sheet.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_group_all, R.id.action_ungroup_all, R.id.action_only_history,
|
R.id.action_group_all, R.id.action_ungroup_all, R.id.action_only_history,
|
||||||
R.id.action_only_updates -> {
|
R.id.action_only_updates -> {
|
||||||
@ -516,8 +521,9 @@ class RecentsController(bundle: Bundle? = null) :
|
|||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (item.itemId == R.id.action_only_history)
|
if (item.itemId == R.id.action_only_history) {
|
||||||
activity?.toast(R.string.press_and_hold_to_reset_history, Toast.LENGTH_LONG)
|
activity?.toast(R.string.press_and_hold_to_reset_history, Toast.LENGTH_LONG)
|
||||||
|
}
|
||||||
activity?.invalidateOptionsMenu()
|
activity?.invalidateOptionsMenu()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,9 @@ class RecentsPresenter(
|
|||||||
downloadManager.addListener(this)
|
downloadManager.addListener(this)
|
||||||
LibraryUpdateService.setListener(this)
|
LibraryUpdateService.setListener(this)
|
||||||
if (lastRecents != null) {
|
if (lastRecents != null) {
|
||||||
if (recentItems.isEmpty())
|
if (recentItems.isEmpty()) {
|
||||||
recentItems = lastRecents ?: emptyList()
|
recentItems = lastRecents ?: emptyList()
|
||||||
|
}
|
||||||
lastRecents = null
|
lastRecents = null
|
||||||
}
|
}
|
||||||
getRecents()
|
getRecents()
|
||||||
@ -95,14 +96,15 @@ class RecentsPresenter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val cReading = if (viewType != 3)
|
val cReading = if (viewType != 3) {
|
||||||
if (query.isEmpty() && viewType != 2)
|
if (query.isEmpty() && viewType != 2) {
|
||||||
db.getRecentsWithUnread(cal.time, query, isUngrouped).executeOnIO()
|
db.getRecentsWithUnread(cal.time, query, isUngrouped).executeOnIO()
|
||||||
else db.getRecentMangaLimit(
|
} else db.getRecentMangaLimit(
|
||||||
cal.time,
|
cal.time,
|
||||||
if (viewType == 2) 200 else 8,
|
if (viewType == 2) 200 else 8,
|
||||||
query
|
query
|
||||||
).executeOnIO() else emptyList()
|
).executeOnIO()
|
||||||
|
} else emptyList()
|
||||||
val rUpdates = when {
|
val rUpdates = when {
|
||||||
viewType == 3 -> db.getRecentChapters(calWeek.time).executeOnIO().map {
|
viewType == 3 -> db.getRecentChapters(calWeek.time).executeOnIO().map {
|
||||||
MangaChapterHistory(it.manga, it.chapter, HistoryImpl())
|
MangaChapterHistory(it.manga, it.chapter, HistoryImpl())
|
||||||
@ -113,8 +115,9 @@ class RecentsPresenter(
|
|||||||
rUpdates.forEach {
|
rUpdates.forEach {
|
||||||
it.history.last_read = it.chapter.date_fetch
|
it.history.last_read = it.chapter.date_fetch
|
||||||
}
|
}
|
||||||
val nAdditions = if (viewType < 2)
|
val nAdditions = if (viewType < 2) {
|
||||||
db.getRecentlyAdded(calDay.time, query, isUngrouped).executeOnIO() else emptyList()
|
db.getRecentlyAdded(calDay.time, query, isUngrouped).executeOnIO()
|
||||||
|
} else emptyList()
|
||||||
nAdditions.forEach {
|
nAdditions.forEach {
|
||||||
it.history.last_read = it.manga.date_added
|
it.history.last_read = it.manga.date_added
|
||||||
}
|
}
|
||||||
@ -144,10 +147,11 @@ class RecentsPresenter(
|
|||||||
Comparator<Pair<MangaChapterHistory, Chapter>> { f1, f2 ->
|
Comparator<Pair<MangaChapterHistory, Chapter>> { f1, f2 ->
|
||||||
if (abs(f1.second.date_fetch - f2.second.date_fetch) <=
|
if (abs(f1.second.date_fetch - f2.second.date_fetch) <=
|
||||||
TimeUnit.HOURS.toMillis(12)
|
TimeUnit.HOURS.toMillis(12)
|
||||||
)
|
) {
|
||||||
f2.second.date_upload.compareTo(f1.second.date_upload)
|
f2.second.date_upload.compareTo(f1.second.date_upload)
|
||||||
else
|
} else {
|
||||||
f2.second.date_fetch.compareTo(f1.second.date_fetch)
|
f2.second.date_fetch.compareTo(f1.second.date_fetch)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.take(4).map {
|
.take(4).map {
|
||||||
|
@ -10,7 +10,6 @@ import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
|
|||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
|
||||||
import eu.kanade.tachiyomi.data.updater.UpdateChecker
|
import eu.kanade.tachiyomi.data.updater.UpdateChecker
|
||||||
import eu.kanade.tachiyomi.data.updater.UpdateResult
|
import eu.kanade.tachiyomi.data.updater.UpdateResult
|
||||||
import eu.kanade.tachiyomi.data.updater.UpdaterService
|
import eu.kanade.tachiyomi.data.updater.UpdaterService
|
||||||
|
@ -46,8 +46,8 @@ inline fun PreferenceGroup.editTextPreference(block: (@DSL EditTextPreference).(
|
|||||||
|
|
||||||
inline fun PreferenceGroup.dropDownPreference(block: (@DSL DropDownPreference).() -> Unit):
|
inline fun PreferenceGroup.dropDownPreference(block: (@DSL DropDownPreference).() -> Unit):
|
||||||
DropDownPreference {
|
DropDownPreference {
|
||||||
return initThenAdd(DropDownPreference(context), block).also(::initDialog)
|
return initThenAdd(DropDownPreference(context), block).also(::initDialog)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun PreferenceGroup.listPreference(
|
inline fun PreferenceGroup.listPreference(
|
||||||
activity: Activity?,
|
activity: Activity?,
|
||||||
@ -55,8 +55,8 @@ inline fun PreferenceGroup.listPreference(
|
|||||||
-> Unit
|
-> Unit
|
||||||
):
|
):
|
||||||
ListMatPreference {
|
ListMatPreference {
|
||||||
return initThenAdd(ListMatPreference(activity, context), block)
|
return initThenAdd(ListMatPreference(activity, context), block)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun PreferenceGroup.intListPreference(
|
inline fun PreferenceGroup.intListPreference(
|
||||||
activity: Activity?,
|
activity: Activity?,
|
||||||
@ -66,8 +66,8 @@ inline fun PreferenceGroup.intListPreference(
|
|||||||
).() -> Unit
|
).() -> Unit
|
||||||
):
|
):
|
||||||
IntListMatPreference {
|
IntListMatPreference {
|
||||||
return initThenAdd(IntListMatPreference(activity, context), block)
|
return initThenAdd(IntListMatPreference(activity, context), block)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun PreferenceGroup.multiSelectListPreferenceMat(
|
inline fun PreferenceGroup.multiSelectListPreferenceMat(
|
||||||
activity: Activity?,
|
activity: Activity?,
|
||||||
|
@ -186,9 +186,7 @@ class SettingsAdvancedController : SettingsController() {
|
|||||||
|
|
||||||
class CleanupDownloadsDialogController() : DialogController() {
|
class CleanupDownloadsDialogController() : DialogController() {
|
||||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||||
|
|
||||||
return MaterialDialog(activity!!).show {
|
return MaterialDialog(activity!!).show {
|
||||||
|
|
||||||
title(R.string.clean_up_downloaded_chapters)
|
title(R.string.clean_up_downloaded_chapters)
|
||||||
.listItemsMultiChoice(R.array.clean_up_downloads, disabledIndices = intArrayOf(0), initialSelection = intArrayOf(0, 1, 2)) { dialog, selections, items ->
|
.listItemsMultiChoice(R.array.clean_up_downloads, disabledIndices = intArrayOf(0), initialSelection = intArrayOf(0, 1, 2)) { dialog, selections, items ->
|
||||||
val deleteRead = selections.contains(1)
|
val deleteRead = selections.contains(1)
|
||||||
|
@ -151,7 +151,7 @@ class SettingsBackupController : SettingsController() {
|
|||||||
defaultValue = true
|
defaultValue = true
|
||||||
|
|
||||||
preferences.backupInterval().asImmediateFlow { isVisible = it > 0 }
|
preferences.backupInterval().asImmediateFlow { isVisible = it > 0 }
|
||||||
.launchIn(viewScope)
|
.launchIn(viewScope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
|
|||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||||
import eu.kanade.tachiyomi.ui.migration.MigrationController
|
import eu.kanade.tachiyomi.ui.migration.MigrationController
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
|
||||||
import eu.kanade.tachiyomi.util.view.snack
|
import eu.kanade.tachiyomi.util.view.snack
|
||||||
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
@ -20,7 +20,6 @@ import com.bluelinelabs.conductor.ControllerChangeType
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
|
||||||
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
||||||
import kotlinx.coroutines.MainScope
|
import kotlinx.coroutines.MainScope
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
@ -97,15 +97,16 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
preferences.downloadNew().asImmediateFlow { isVisible = it }
|
preferences.downloadNew().asImmediateFlow { isVisible = it }
|
||||||
|
|
||||||
preferences.downloadNewCategories().asImmediateFlow { list ->
|
preferences.downloadNewCategories().asImmediateFlow { list ->
|
||||||
val selectedCategories = list
|
val selectedCategories = list
|
||||||
.mapNotNull { id -> dbCategories.find { it.id == id.toInt() } }
|
.mapNotNull { id -> dbCategories.find { it.id == id.toInt() } }
|
||||||
.sortedBy { it.order }
|
.sortedBy { it.order }
|
||||||
|
|
||||||
customSummary = if (selectedCategories.isEmpty())
|
customSummary = if (selectedCategories.isEmpty()) {
|
||||||
resources?.getString(R.string.all)
|
resources?.getString(R.string.all)
|
||||||
else
|
} else {
|
||||||
selectedCategories.joinToString { it.name }
|
selectedCategories.joinToString { it.name }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
preferenceCategory {
|
preferenceCategory {
|
||||||
intListPreference(activity) {
|
intListPreference(activity) {
|
||||||
|
@ -137,7 +137,7 @@ class SettingsLibraryController : SettingsController() {
|
|||||||
|
|
||||||
preferences.libraryUpdateCategories().asImmediateFlow { list ->
|
preferences.libraryUpdateCategories().asImmediateFlow { list ->
|
||||||
val selectedCategories =
|
val selectedCategories =
|
||||||
list.mapNotNull { id -> dbCategories.find { it.id == id.toInt() } }
|
list.mapNotNull { id -> dbCategories.find { it.id == id.toInt() } }
|
||||||
.sortedBy { it.order }
|
.sortedBy { it.order }
|
||||||
|
|
||||||
customSummary =
|
customSummary =
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user