diff --git a/app/src/main/java/ani/dantotsu/App.kt b/app/src/main/java/ani/dantotsu/App.kt index 7a9e39ac..70a0ee45 100644 --- a/app/src/main/java/ani/dantotsu/App.kt +++ b/app/src/main/java/ani/dantotsu/App.kt @@ -28,7 +28,9 @@ import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import logcat.AndroidLogcatLogger @@ -57,6 +59,7 @@ class App : MultiDexApplication() { val mFTActivityLifecycleCallbacks = FTActivityLifecycleCallbacks() + @OptIn(DelicateCoroutinesApi::class) override fun onCreate() { super.onCreate() @@ -98,43 +101,35 @@ class App : MultiDexApplication() { LogcatLogger.install(AndroidLogcatLogger(LogPriority.VERBOSE)) } - animeExtensionManager = Injekt.get() - mangaExtensionManager = Injekt.get() - novelExtensionManager = Injekt.get() - torrentAddonManager = Injekt.get() - downloadAddonManager = Injekt.get() - - val animeScope = CoroutineScope(Dispatchers.Default) - animeScope.launch { + CoroutineScope(Dispatchers.IO).launch { + animeExtensionManager = Injekt.get() animeExtensionManager.findAvailableExtensions() Logger.log("Anime Extensions: ${animeExtensionManager.installedExtensionsFlow.first()}") AnimeSources.init(animeExtensionManager.installedExtensionsFlow) } - val mangaScope = CoroutineScope(Dispatchers.Default) - mangaScope.launch { + CoroutineScope(Dispatchers.IO).launch { + mangaExtensionManager = Injekt.get() mangaExtensionManager.findAvailableExtensions() Logger.log("Manga Extensions: ${mangaExtensionManager.installedExtensionsFlow.first()}") MangaSources.init(mangaExtensionManager.installedExtensionsFlow) } - val novelScope = CoroutineScope(Dispatchers.Default) - novelScope.launch { + CoroutineScope(Dispatchers.IO).launch { + novelExtensionManager = Injekt.get() novelExtensionManager.findAvailableExtensions() Logger.log("Novel Extensions: ${novelExtensionManager.installedExtensionsFlow.first()}") NovelSources.init(novelExtensionManager.installedExtensionsFlow) } - val addonScope = CoroutineScope(Dispatchers.Default) - addonScope.launch { + GlobalScope.launch { + torrentAddonManager = Injekt.get() + downloadAddonManager = Injekt.get() torrentAddonManager.init() downloadAddonManager.init() - } - val commentsScope = CoroutineScope(Dispatchers.Default) - commentsScope.launch { CommentsAPI.fetchAuthToken() - } - val useAlarmManager = PrefManager.getVal(PrefName.UseAlarmManager) - val scheduler = TaskScheduler.create(this, useAlarmManager) - scheduler.scheduleAllTasks(this) + val useAlarmManager = PrefManager.getVal(PrefName.UseAlarmManager) + val scheduler = TaskScheduler.create(this@App, useAlarmManager) + scheduler.scheduleAllTasks(this@App) + } } private fun setupNotificationChannels() { diff --git a/app/src/main/java/ani/dantotsu/addons/AddonDownloader.kt b/app/src/main/java/ani/dantotsu/addons/AddonDownloader.kt index 76f077c1..4ab1876f 100644 --- a/app/src/main/java/ani/dantotsu/addons/AddonDownloader.kt +++ b/app/src/main/java/ani/dantotsu/addons/AddonDownloader.kt @@ -35,7 +35,7 @@ class AddonDownloader { val md = r.body ?: "" val version = v.ifEmpty { throw Exception("Weird Version : ${r.tagName}") } - Logger.log("Git Version : $version") + Logger.log("Git Version for $repo: $version") Pair(md, version) } catch (e: Exception) { Logger.log("Error checking for update") diff --git a/app/src/main/java/ani/dantotsu/addons/download/DownloadAddonManager.kt b/app/src/main/java/ani/dantotsu/addons/download/DownloadAddonManager.kt index 6c704f83..7815c0ca 100644 --- a/app/src/main/java/ani/dantotsu/addons/download/DownloadAddonManager.kt +++ b/app/src/main/java/ani/dantotsu/addons/download/DownloadAddonManager.kt @@ -24,7 +24,7 @@ class DownloadAddonManager( override var name: String = "Download Addon" override var type = AddonType.DOWNLOAD - private val _isInitialized = MutableLiveData().apply { value = false } + private val _isInitialized = MutableLiveData().apply { postValue(false) } val isInitialized: LiveData = _isInitialized private var error: String? = null diff --git a/app/src/main/java/ani/dantotsu/addons/torrent/TorrentAddonManager.kt b/app/src/main/java/ani/dantotsu/addons/torrent/TorrentAddonManager.kt index 1dc7bfe5..cd713bae 100644 --- a/app/src/main/java/ani/dantotsu/addons/torrent/TorrentAddonManager.kt +++ b/app/src/main/java/ani/dantotsu/addons/torrent/TorrentAddonManager.kt @@ -25,7 +25,7 @@ class TorrentAddonManager( override var type: AddonType = AddonType.TORRENT var torrentHash: String? = null - private val _isInitialized = MutableLiveData().apply { value = false } + private val _isInitialized = MutableLiveData().apply { postValue(false) } val isInitialized: LiveData = _isInitialized private var error: String? = null diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/Anilist.kt b/app/src/main/java/ani/dantotsu/connections/anilist/Anilist.kt index 9810b8c5..320d715b 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/Anilist.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/Anilist.kt @@ -202,7 +202,6 @@ object Anilist { if (!json.text.startsWith("{")) { throw Exception(currContext()?.getString(R.string.anilist_down)) } - if (show) Logger.log("Anilist Response: ${json.text}") json.parsed() } else null } catch (e: Exception) { diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt index d9f07b73..f7917b23 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt @@ -25,7 +25,6 @@ import ani.dantotsu.profile.User import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.snackString -import ani.dantotsu.util.Logger import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.runBlocking @@ -413,7 +412,7 @@ class AnilistQueries { return """ MediaListCollection(userId: ${Anilist.userid}, type: $type, status: PLANNING${if (type == "ANIME") ", sort: MEDIA_POPULARITY_DESC" else ""} ) { lists { entries { media { id mediaListEntry { progress private score(format:POINT_100) status } idMal type isAdult popularity status(version: 2) chapters episodes nextAiringEpisode {episode} meanScore isFavourite format bannerImage coverImage{large} title { english romaji userPreferred } } } } }""" } - suspend fun initHomePage(): Map> { + suspend fun initHomePage(): Map> { val toShow: List = PrefManager.getVal(PrefName.HomeLayout) // anime continue, anime fav, anime planned, manga continue, manga fav, manga planned, recommendations var query = """{""" @@ -448,11 +447,11 @@ class AnilistQueries { "ANIME" ) }, recommendationPlannedQueryManga: ${recommendationPlannedQuery("MANGA")}""" + if (toShow.getOrNull(7) == true) query += "Page1:${status(1)}Page2:${status(2)}" query += """}""".trimEnd(',') val response = executeQuery(query, show = true) - Logger.log(response.toString()) - val returnMap = mutableMapOf>() + val returnMap = mutableMapOf>() fun current(type: String) { val subMap = mutableMapOf() val returnArray = arrayListOf() @@ -595,6 +594,45 @@ class AnilistQueries { list.sortByDescending { it.meanScore } returnMap["recommendations"] = list } + if (toShow.getOrNull(7) == true) { + val list = mutableListOf() + val threeDaysAgo = Calendar.getInstance().apply { + add(Calendar.DAY_OF_MONTH, -3) + }.timeInMillis + if (response?.data?.page1 != null && response.data.page2 != null) { + val activities = listOf( + response.data.page1.activities, + response.data.page2.activities + ).flatten() + .filter { it.typename != "MessageActivity" } + .sortedByDescending { it.createdAt } + .filter { it.createdAt * 1000L > threeDaysAgo } + val anilistActivities = mutableListOf() + val groupedActivities = activities.groupBy { it.userId } + + groupedActivities.forEach { (_, userActivities) -> + val user = userActivities.firstOrNull()?.user + if (user != null) { + val userToAdd = User( + user.id, + user.name ?: "", + user.avatar?.medium, + user.bannerImage, + activity = userActivities.sortedBy { it.createdAt }.toList() + ) + if (user.id == Anilist.userid) { + anilistActivities.add(0, userToAdd) + } else { + list.add(userToAdd) + } + } + } + + + list.addAll(0, anilistActivities) + returnMap["status"] = ArrayList(list) + } + } return returnMap } @@ -1546,48 +1584,9 @@ Page(page:$page,perPage:50) { ) } private fun status(page: Int = 1): String { - return """Page(page:$page,perPage:50){activities(isFollowing: true,sort:ID_DESC){__typename ... on TextActivity{id userId type replyCount text(asHtml:true)siteUrl isLocked isSubscribed likeCount isLiked isPinned createdAt user{id name bannerImage avatar{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}... on ListActivity{id userId type replyCount status progress siteUrl isLocked isSubscribed likeCount isLiked isPinned createdAt user{id name bannerImage avatar{medium large}}media{id title{english romaji native userPreferred}bannerImage coverImage{extraLarge medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}... on MessageActivity{id recipientId messengerId type replyCount likeCount message(asHtml:true)isLocked isSubscribed isLiked isPrivate siteUrl createdAt recipient{id name bannerImage avatar{medium large}}messenger{id name bannerImage avatar{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}}}""" + return """Page(page:$page,perPage:50){activities(isFollowing: true,sort:ID_DESC){__typename ... on TextActivity{id userId type replyCount text(asHtml:true)siteUrl isLocked isSubscribed likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}... on ListActivity{id userId type replyCount status progress siteUrl isLocked isSubscribed likeCount isLiked isPinned createdAt user{id name bannerImage avatar{medium large}}media{id title{english romaji native userPreferred}bannerImage coverImage{extraLarge medium large}}likes{id name bannerImage avatar{medium large}}}... on MessageActivity{id type createdAt}}}""" } - suspend fun getStatus( - ): MutableList { - fun query() = """{ - Page1:${status(1)} - Page2:${status(2)} - }""".trimIndent() - val list = mutableListOf() - val threeDaysAgo = Calendar.getInstance().apply { - add(Calendar.DAY_OF_MONTH, -3) - }.timeInMillis - executeQuery(query(), force = true)?.data?.let { data -> - val activities = listOf(data.page1.activities, data.page2.activities).flatten() - .sortedByDescending { it.createdAt } - .filter { it.createdAt * 1000L > threeDaysAgo } - val anilistActivities = mutableListOf() - val groupedActivities = activities.groupBy { it.userId } - groupedActivities.forEach { (_, userActivities) -> - val user = userActivities.firstOrNull()?.user - if (user != null) { - val userToAdd = User( - user.id, - user.name ?: "", - user.avatar?.medium, - user.bannerImage, - activity = userActivities.sortedBy { it.createdAt }.toList() - ) - if (user.id == Anilist.userid) { - anilistActivities.add(0, userToAdd) - } else { - list.add(userToAdd) - } - } - } - - - list.addAll(0, anilistActivities) - } - return list - } suspend fun getUpcomingAnime(id: String): List { val res = executeQuery( """{MediaListCollection(userId:$id,type:ANIME){lists{name entries{media{id,isFavourite,title{userPreferred,romaji}coverImage{medium}nextAiringEpisode{timeUntilAiring}}}}}}""", diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt index 92a5bd09..65f26c81 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt @@ -23,16 +23,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch suspend fun getUserId(context: Context, block: () -> Unit) { - CoroutineScope(Dispatchers.IO).launch { - val token = PrefManager.getVal(PrefName.DiscordToken, null as String?) - val userid = PrefManager.getVal(PrefName.DiscordId, null as String?) - if (userid == null && token != null) { - /*if (!Discord.getUserData()) - snackString(context.getString(R.string.error_loading_discord_user_data))*/ - //TODO: Discord.getUserData() - } - } - val anilist = if (Anilist.userid == null && Anilist.token != null) { if (Anilist.query.getUserData()) { tryWithSuspend { @@ -91,26 +81,23 @@ class AnilistHomeViewModel : ViewModel() { fun getRecommendation(): LiveData> = recommendation + @Suppress("UNCHECKED_CAST") suspend fun initHomePage() { val res = Anilist.query.initHomePage() - Logger.log("AnilistHomeViewModel : res=$res") - res["currentAnime"]?.let { animeContinue.postValue(it) } - res["favoriteAnime"]?.let { animeFav.postValue(it) } - res["plannedAnime"]?.let { animePlanned.postValue(it) } - res["currentManga"]?.let { mangaContinue.postValue(it) } - res["favoriteManga"]?.let { mangaFav.postValue(it) } - res["plannedManga"]?.let { mangaPlanned.postValue(it) } - res["recommendations"]?.let { recommendation.postValue(it) } + res["currentAnime"]?.let { animeContinue.postValue(it as ArrayList?) } + res["favoriteAnime"]?.let { animeFav.postValue(it as ArrayList?) } + res["plannedAnime"]?.let { animePlanned.postValue(it as ArrayList?) } + res["currentManga"]?.let { mangaContinue.postValue(it as ArrayList?) } + res["favoriteManga"]?.let { mangaFav.postValue(it as ArrayList?) } + res["plannedManga"]?.let { mangaPlanned.postValue(it as ArrayList?) } + res["recommendations"]?.let { recommendation.postValue(it as ArrayList?) } + res["status"]?.let { userStatus.postValue(it as ArrayList?) } } private val userStatus: MutableLiveData> = MutableLiveData>(null) fun getUserStatus(): LiveData> = userStatus - suspend fun initUserStatus() { - Anilist.query.getStatus().let { userStatus.postValue(ArrayList(it)) } - } - suspend fun loadMain(context: FragmentActivity) { Anilist.getSavedToken() MAL.getSavedToken() diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/api/Data.kt b/app/src/main/java/ani/dantotsu/connections/anilist/api/Data.kt index d45fdc79..bb6ee792 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/api/Data.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/api/Data.kt @@ -138,6 +138,8 @@ class Query { @SerialName("recommendationQuery") val recommendationQuery: ani.dantotsu.connections.anilist.api.Page?, @SerialName("recommendationPlannedQueryAnime") val recommendationPlannedQueryAnime: ani.dantotsu.connections.anilist.api.MediaListCollection?, @SerialName("recommendationPlannedQueryManga") val recommendationPlannedQueryManga: ani.dantotsu.connections.anilist.api.MediaListCollection?, + @SerialName("Page1") val page1: ActivityPage?, + @SerialName("Page2") val page2: ActivityPage? ) } diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/api/Feed.kt b/app/src/main/java/ani/dantotsu/connections/anilist/api/Feed.kt index 9d4a44d4..51802883 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/api/Feed.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/api/Feed.kt @@ -46,7 +46,7 @@ data class Activity( @SerialName("type") val type: String, @SerialName("replyCount") - val replyCount: Int, + val replyCount: Int = 0, @SerialName("status") val status: String?, @SerialName("progress") @@ -58,9 +58,9 @@ data class Activity( @SerialName("siteUrl") val siteUrl: String?, @SerialName("isLocked") - val isLocked: Boolean, + val isLocked: Boolean?, @SerialName("isSubscribed") - val isSubscribed: Boolean, + val isSubscribed: Boolean?, @SerialName("likeCount") var likeCount: Int?, @SerialName("isLiked") diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/api/Media.kt b/app/src/main/java/ani/dantotsu/connections/anilist/api/Media.kt index 471b130d..b7a5134b 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/api/Media.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/api/Media.kt @@ -205,15 +205,17 @@ enum class MediaStatus { FINISHED, RELEASING, NOT_YET_RELEASED, CANCELLED, HIATUS; override fun toString(): String { - return when (super.toString()) { - "FINISHED" -> currContext()!!.getString(R.string.status_finished) - "RELEASING" -> currContext()!!.getString(R.string.status_releasing) - "NOT_YET_RELEASED" -> currContext()!!.getString(R.string.status_not_yet_released) - "CANCELLED" -> currContext()!!.getString(R.string.status_cancelled) - "HIATUS" -> currContext()!!.getString(R.string.status_hiatus) - else -> "" + currContext()?.let { + return when (super.toString()) { + "FINISHED" -> it.getString(R.string.status_finished) + "RELEASING" -> it.getString(R.string.status_releasing) + "NOT_YET_RELEASED" -> it.getString(R.string.status_not_yet_released) + "CANCELLED" -> it.getString(R.string.status_cancelled) + "HIATUS" -> it.getString(R.string.status_hiatus) + else -> "" + } } - + return super.toString().replace("_", " ") } } @@ -445,17 +447,20 @@ enum class MediaRelation { ADAPTATION, PREQUEL, SEQUEL, PARENT, SIDE_STORY, CHARACTER, SUMMARY, ALTERNATIVE, SPIN_OFF, OTHER, SOURCE, COMPILATION, CONTAINS; override fun toString(): String { - return when (super.toString()) { - "ADAPTATION" -> currContext()!!.getString(R.string.type_adaptation) - "PARENT" -> currContext()!!.getString(R.string.type_parent) - "CHARACTER" -> currContext()!!.getString(R.string.type_character) - "SUMMARY" -> currContext()!!.getString(R.string.type_summary) - "ALTERNATIVE" -> currContext()!!.getString(R.string.type_alternative) - "OTHER" -> currContext()!!.getString(R.string.type_other) - "SOURCE" -> currContext()!!.getString(R.string.type_source) - "CONTAINS" -> currContext()!!.getString(R.string.type_contains) - else -> super.toString().replace("_", " ") + currContext()?.let { + return when (super.toString()) { + "ADAPTATION" -> it.getString(R.string.type_adaptation) + "PARENT" -> it.getString(R.string.type_parent) + "CHARACTER" -> it.getString(R.string.type_character) + "SUMMARY" -> it.getString(R.string.type_summary) + "ALTERNATIVE" -> it.getString(R.string.type_alternative) + "OTHER" -> it.getString(R.string.type_other) + "SOURCE" -> it.getString(R.string.type_source) + "CONTAINS" -> it.getString(R.string.type_contains) + else -> super.toString().replace("_", " ") + } } + return super.toString().replace("_", " ") } } diff --git a/app/src/main/java/ani/dantotsu/download/anime/OfflineAnimeFragment.kt b/app/src/main/java/ani/dantotsu/download/anime/OfflineAnimeFragment.kt index b1729e7e..e9877c02 100644 --- a/app/src/main/java/ani/dantotsu/download/anime/OfflineAnimeFragment.kt +++ b/app/src/main/java/ani/dantotsu/download/anime/OfflineAnimeFragment.kt @@ -291,8 +291,8 @@ class OfflineAnimeFragment : Fragment(), OfflineAnimeSearchListener { val animeTitles = downloadManager.animeDownloadedTypes.map { it.titleName.findValidName() }.distinct() val newAnimeDownloads = mutableListOf() for (title in animeTitles) { - val tDownloads = downloadManager.animeDownloadedTypes.filter { it.titleName == title } - val download = tDownloads.first() + val tDownloads = downloadManager.animeDownloadedTypes.filter { it.titleName.findValidName() == title } + val download = tDownloads.firstOrNull() ?: continue val offlineAnimeModel = loadOfflineAnimeModel(download) newAnimeDownloads += offlineAnimeModel } diff --git a/app/src/main/java/ani/dantotsu/download/manga/OfflineMangaFragment.kt b/app/src/main/java/ani/dantotsu/download/manga/OfflineMangaFragment.kt index ab964ee9..36e90e60 100644 --- a/app/src/main/java/ani/dantotsu/download/manga/OfflineMangaFragment.kt +++ b/app/src/main/java/ani/dantotsu/download/manga/OfflineMangaFragment.kt @@ -282,8 +282,8 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener { val mangaTitles = downloadManager.mangaDownloadedTypes.map { it.titleName.findValidName() }.distinct() val newMangaDownloads = mutableListOf() for (title in mangaTitles) { - val tDownloads = downloadManager.mangaDownloadedTypes.filter { it.titleName == title } - val download = tDownloads.first() + val tDownloads = downloadManager.mangaDownloadedTypes.filter { it.titleName.findValidName() == title } + val download = tDownloads.firstOrNull() ?: continue val offlineMangaModel = loadOfflineMangaModel(download) newMangaDownloads += offlineMangaModel } @@ -291,8 +291,8 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener { val novelTitles = downloadManager.novelDownloadedTypes.map { it.titleName }.distinct() val newNovelDownloads = mutableListOf() for (title in novelTitles) { - val tDownloads = downloadManager.novelDownloadedTypes.filter { it.titleName == title } - val download = tDownloads.first() + val tDownloads = downloadManager.novelDownloadedTypes.filter { it.titleName.findValidName() == title } + val download = tDownloads.firstOrNull() ?: continue val offlineMangaModel = loadOfflineMangaModel(download) newNovelDownloads += offlineMangaModel } diff --git a/app/src/main/java/ani/dantotsu/home/HomeFragment.kt b/app/src/main/java/ani/dantotsu/home/HomeFragment.kt index 56857254..499c7cdb 100644 --- a/app/src/main/java/ani/dantotsu/home/HomeFragment.kt +++ b/app/src/main/java/ani/dantotsu/home/HomeFragment.kt @@ -46,6 +46,7 @@ import ani.dantotsu.settings.saving.PrefManager.asLiveBool import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.snackString import ani.dantotsu.statusBarHeight +import ani.dantotsu.util.Logger import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -75,7 +76,9 @@ class HomeFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val scope = lifecycleScope + Logger.log("HomeFragment") fun load() { + Logger.log("Loading HomeFragment") if (activity != null && _binding != null) lifecycleScope.launch(Dispatchers.Main) { binding.homeUserName.text = Anilist.username binding.homeUserEpisodesWatched.text = Anilist.episodesWatched.toString() @@ -315,7 +318,7 @@ class HomeFragment : Fragment() { binding.homeRecommendedEmpty, binding.homeRecommended ) - binding.homeUserStatusContainer.visibility =View.VISIBLE + binding.homeUserStatusContainer.visibility = View.VISIBLE binding.homeUserStatusProgressBar.visibility = View.VISIBLE binding.homeUserStatusRecyclerView.visibility = View.GONE model.getUserStatus().observe(viewLifecycleOwner) { @@ -391,13 +394,12 @@ class HomeFragment : Fragment() { } model.loaded = true model.setListImages() + Logger.log("HomeFragment: Refreshing") var empty = true val homeLayoutShow: List = PrefManager.getVal(PrefName.HomeLayout) - runBlocking { - if (homeLayoutShow.getOrNull(7) == true) model.initUserStatus() - model.initHomePage() - } + model.initHomePage() + (array.indices).forEach { i -> if (homeLayoutShow.elementAt(i)) { empty = false diff --git a/app/src/main/java/ani/dantotsu/media/MediaInfoFragment.kt b/app/src/main/java/ani/dantotsu/media/MediaInfoFragment.kt index d4373bba..9315863a 100644 --- a/app/src/main/java/ani/dantotsu/media/MediaInfoFragment.kt +++ b/app/src/main/java/ani/dantotsu/media/MediaInfoFragment.kt @@ -573,7 +573,7 @@ class MediaInfoFragment : Fragment() { parent.addView(root) } } - val users = media.users!! + val users: ArrayList = media.users ?: arrayListOf() if (Anilist.token != null && media.userStatus != null) { users.add(0, User( diff --git a/app/src/main/java/ani/dantotsu/notifications/subscription/SubscriptionHelper.kt b/app/src/main/java/ani/dantotsu/notifications/subscription/SubscriptionHelper.kt index 9905cb86..79f84381 100644 --- a/app/src/main/java/ani/dantotsu/notifications/subscription/SubscriptionHelper.kt +++ b/app/src/main/java/ani/dantotsu/notifications/subscription/SubscriptionHelper.kt @@ -23,7 +23,7 @@ class SubscriptionHelper { mediaId: Int ): Selected { val data = - PrefManager.getNullableCustomVal("${mediaId}-select", null, Selected::class.java) + PrefManager.getNullableCustomVal("Selected-${mediaId}", null, Selected::class.java) ?: Selected().let { it.sourceIndex = 0 it.preferDub = PrefManager.getVal(PrefName.SettingsPreferDub) @@ -33,13 +33,16 @@ class SubscriptionHelper { } private fun saveSelected(mediaId: Int, data: Selected) { - PrefManager.setCustomVal("${mediaId}-select", data) + PrefManager.setCustomVal("Selected-${mediaId}", data) } fun getAnimeParser(id: Int): AnimeParser { val sources = AnimeSources Logger.log("getAnimeParser size: ${sources.list.size}") val selected = loadSelected(id) + if (selected.sourceIndex >= sources.list.size) { + selected.sourceIndex = 0 + } val parser = sources[selected.sourceIndex] parser.selectDub = selected.preferDub return parser @@ -76,7 +79,11 @@ class SubscriptionHelper { fun getMangaParser(id: Int): MangaParser { val sources = MangaSources + Logger.log("getMangaParser size: ${sources.list.size}") val selected = loadSelected(id) + if (selected.sourceIndex >= sources.list.size) { + selected.sourceIndex = 0 + } return sources[selected.sourceIndex] } diff --git a/app/src/main/java/ani/dantotsu/util/Logger.kt b/app/src/main/java/ani/dantotsu/util/Logger.kt index 3714aa01..ec6b627f 100644 --- a/app/src/main/java/ani/dantotsu/util/Logger.kt +++ b/app/src/main/java/ani/dantotsu/util/Logger.kt @@ -117,6 +117,17 @@ object Logger { } } + fun uncaughtException(t: Thread, e: Throwable) { + loggerExecutor.execute { + if (file == null) e.printStackTrace() else { + file?.appendText("---------------------------Uncaught Exception---------------------------\n") + file?.appendText("thread: ${t.name}\n") + file?.appendText("date/time: ${Date()} | ${e.message}\n") + file?.appendText("trace: ${e.stackTraceToString()}\n") + } + } + } + fun shareLog(context: Context) { if (file == null) { snackString("No log file found") @@ -151,7 +162,7 @@ class FinalExceptionHandler : Thread.UncaughtExceptionHandler { Thread.getDefaultUncaughtExceptionHandler() override fun uncaughtException(t: Thread, e: Throwable) { - Logger.log(e) + Logger.uncaughtException(t, e) Injekt.get().logException(e) defaultUEH?.uncaughtException(t, e) }