From eb5e2623a0443fe8b8f0c7ce1f36b6594fdb59af Mon Sep 17 00:00:00 2001 From: rebelonion <87634197+rebelonion@users.noreply.github.com> Date: Sun, 10 Mar 2024 05:00:23 -0500 Subject: [PATCH] feat: combine profile queries --- .../connections/anilist/AnilistQueries.kt | 101 +++++++++--------- .../connections/anilist/AnilistViewModel.kt | 43 ++++++-- .../dantotsu/connections/anilist/api/Data.kt | 14 +++ .../ani/dantotsu/profile/StatsFragment.kt | 38 ++++--- .../dantotsu/profile/activity/FeedFragment.kt | 85 ++++++++------- 5 files changed, 165 insertions(+), 116 deletions(-) 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 bbc2bb07..b8d6ad19 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt @@ -52,7 +52,7 @@ class AnilistQueries { Anilist.episodesWatched = user.statistics?.anime?.episodesWatched Anilist.chapterRead = user.statistics?.manga?.chaptersRead Anilist.adult = user.options?.displayAdultContent ?: false - Anilist.unreadNotificationCount = user.unreadNotificationCount?:0 + Anilist.unreadNotificationCount = user.unreadNotificationCount ?: 0 return true } @@ -281,7 +281,8 @@ class AnilistQueries { } else { if (currContext()?.let { isOnline(it) } == true) { snackString(currContext()?.getString(R.string.error_getting_data)) - } else { } + } else { + } } } val mal = async { @@ -335,7 +336,11 @@ class AnilistQueries { returnArray.addAll(map.values) return returnArray } - val list = PrefManager.getNullableCustomVal("continueAnimeList", listOf(), List::class.java) as List + val list = PrefManager.getNullableCustomVal( + "continueAnimeList", + listOf(), + List::class.java + ) as List if (list.isNotEmpty()) { list.reversed().forEach { if (map.containsKey(it)) returnArray.add(map[it]!!) @@ -351,7 +356,7 @@ class AnilistQueries { return """ MediaListCollection(userId: ${Anilist.userid}, type: $type, status: $status , sort: UPDATED_TIME ) { lists { entries { progress private score(format:POINT_100) status media { id idMal type isAdult status chapters episodes nextAiringEpisode {episode} meanScore isFavourite format bannerImage coverImage{large} title { english romaji userPreferred } } } } } """ } - suspend fun favMedia(anime: Boolean, id: Int? = Anilist.userid ): ArrayList { + suspend fun favMedia(anime: Boolean, id: Int? = Anilist.userid): ArrayList { var hasNextPage = true var page = 0 @@ -375,7 +380,7 @@ class AnilistQueries { return responseArray } - private fun favMediaQuery(anime: Boolean, page: Int, id: Int?= Anilist.userid ): String { + private fun favMediaQuery(anime: Boolean, page: Int, id: Int? = Anilist.userid): String { return """User(id:${id}){id favourites{${if (anime) "anime" else "manga"}(page:$page){pageInfo{hasNextPage}edges{favouriteOrder node{id idMal isAdult mediaListEntry{ progress private score(format:POINT_100) status } chapters isFavourite format episodes nextAiringEpisode{episode}meanScore isFavourite format startDate{year month day} title{english romaji userPreferred}type status(version:2)bannerImage coverImage{large}}}}}}""" } @@ -487,7 +492,11 @@ class AnilistQueries { returnMap["current$type"] = returnArray return } - val list = PrefManager.getNullableCustomVal("continueAnimeList", listOf(), List::class.java) as List + val list = PrefManager.getNullableCustomVal( + "continueAnimeList", + listOf(), + List::class.java + ) as List if (list.isNotEmpty()) { list.reversed().forEach { if (subMap.containsKey(it)) returnArray.add(subMap[it]!!) @@ -512,7 +521,11 @@ class AnilistQueries { subMap[m.id] = m } } - val list = PrefManager.getNullableCustomVal("continueAnimeList", listOf(), List::class.java) as List + val list = PrefManager.getNullableCustomVal( + "continueAnimeList", + listOf(), + List::class.java + ) as List if (list.isNotEmpty()) { list.reversed().forEach { if (subMap.containsKey(it)) returnArray.add(subMap[it]!!) @@ -1291,64 +1304,44 @@ Page(page:$page,perPage:50) { ) } - suspend fun userFavMedia(anime: Boolean, id: Int): ArrayList { - var hasNextPage = true - var page = 0 - - suspend fun getNextPage(page: Int): List { - val response = executeQuery("""{${userFavMediaQuery(anime, page, id)}}""") - val favourites = response?.data?.user?.favourites - val apiMediaList = if (anime) favourites?.anime else favourites?.manga - hasNextPage = apiMediaList?.pageInfo?.hasNextPage ?: false - return apiMediaList?.edges?.mapNotNull { - it.node?.let { i -> - Media(i).apply { isFav = true } - } - } ?: return listOf() - } - - val responseArray = arrayListOf() - while (hasNextPage) { - page++ - responseArray.addAll(getNextPage(page)) - } - return responseArray - } - private fun userFavMediaQuery(anime: Boolean, page: Int, id: Int): String { return """User(id:${id}){id favourites{${if (anime) "anime" else "manga"}(page:$page){pageInfo{hasNextPage}edges{favouriteOrder node{id idMal isAdult mediaListEntry{ progress private score(format:POINT_100) status } chapters isFavourite format episodes nextAiringEpisode{episode}meanScore isFavourite format startDate{year month day} title{english romaji userPreferred}type status(version:2)bannerImage coverImage{large}}}}}}""" } - suspend fun userFollowing(id: Int): Query.Following?{ - return executeQuery("""{Page {following(userId:${id},sort:[USERNAME]){id name avatar{large medium}bannerImage}}}""", force = true) + suspend fun userFollowing(id: Int): Query.Following? { + return executeQuery( + """{Page {following(userId:${id},sort:[USERNAME]){id name avatar{large medium}bannerImage}}}""", + force = true + ) } - suspend fun userFollowers(id: Int): Query.Follower?{ - return executeQuery("""{Page {followers(userId:${id},sort:[USERNAME]){id name avatar{large medium}bannerImage}}}""", force = true) + suspend fun userFollowers(id: Int): Query.Follower? { + return executeQuery( + """{Page {followers(userId:${id},sort:[USERNAME]){id name avatar{large medium}bannerImage}}}""", + force = true + ) } - private suspend fun userBannerImage(type: String,id: Int?): String? { - val response = - executeQuery("""{ MediaListCollection(userId: ${id}, type: $type, chunk:1,perChunk:25, sort: [SCORE_DESC,UPDATED_TIME_DESC]) { lists { entries{ media { id bannerImage } } } } } """) - val random = response?.data?.mediaListCollection?.lists?.mapNotNull { - it.entries?.mapNotNull { entry -> - val imageUrl = entry.media?.bannerImage - if (imageUrl != null && imageUrl != "null") imageUrl - else null - } - }?.flatten()?.randomOrNull() ?: return null - return random + suspend fun initProfilePage(id: Int): Query.ProfilePageMedia? { + return executeQuery( + """{ + favoriteAnime:${userFavMediaQuery(true, 1, id)} + favoriteManga:${userFavMediaQuery(false, 1, id)} + animeMediaList:${bannerImageQuery("ANIME", id)} + mangaMediaList:${bannerImageQuery("MANGA", id)} + }""".trimIndent(), force = true + ) } - suspend fun getUserBannerImages(id: Int? = Anilist.userid): ArrayList { - val default = arrayListOf(null, null) - default[0] = userBannerImage("ANIME", id) - default[1] = userBannerImage("MANGA",id) - return default + private fun bannerImageQuery(type: String, id: Int?): String { + return """MediaListCollection(userId: ${id}, type: $type, chunk:1,perChunk:25, sort: [SCORE_DESC,UPDATED_TIME_DESC]) { lists { entries{ media { id bannerImage } } } }""" } suspend fun getNotifications(id: Int, page: Int = 1): NotificationResponse? { - val res = executeQuery("""{User(id:$id){unreadNotificationCount}Page(page:$page,perPage:$ITEMS_PER_PAGE){notifications(resetNotificationCount:true){__typename...on AiringNotification{id,type,animeId,episode,contexts,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}},}...on FollowingNotification{id,userId,type,context,createdAt,user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityMessageNotification{id,userId,type,activityId,context,createdAt,message{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityMentionNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplyNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplySubscribedNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityLikeNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplyLikeNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentMentionNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentReplyNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentSubscribedNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentLikeNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadLikeNotification{id,userId,type,threadId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on RelatedMediaAdditionNotification{id,type,context,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaDataChangeNotification{id,type,mediaId,context,reason,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaMergeNotification{id,type,mediaId,deletedMediaTitles,context,reason,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaDeletionNotification{id,type,deletedMediaTitle,context,reason,createdAt,}}}}""", force = true) + val res = executeQuery( + """{User(id:$id){unreadNotificationCount}Page(page:$page,perPage:$ITEMS_PER_PAGE){notifications(resetNotificationCount:true){__typename...on AiringNotification{id,type,animeId,episode,contexts,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}},}...on FollowingNotification{id,userId,type,context,createdAt,user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityMessageNotification{id,userId,type,activityId,context,createdAt,message{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityMentionNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplyNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplySubscribedNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityLikeNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplyLikeNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentMentionNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentReplyNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentSubscribedNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentLikeNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadLikeNotification{id,userId,type,threadId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on RelatedMediaAdditionNotification{id,type,context,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaDataChangeNotification{id,type,mediaId,context,reason,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaMergeNotification{id,type,mediaId,deletedMediaTitles,context,reason,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaDeletionNotification{id,type,deletedMediaTitle,context,reason,createdAt,}}}}""", + force = true + ) if (res != null) { Anilist.unreadNotificationCount = 0 } @@ -1359,7 +1352,9 @@ Page(page:$page,perPage:50) { val filter = if (userId != null) "userId:$userId," else if (global) "isFollowing:false," else "isFollowing:true," - val res = executeQuery("""{Page(page:$page,perPage:$ITEMS_PER_PAGE){activities(${filter}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{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 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}}}}}}""") + val res = executeQuery( + """{Page(page:$page,perPage:$ITEMS_PER_PAGE){activities(${filter}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{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 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 res } 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 f9535263..07d93b9c 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt @@ -7,10 +7,8 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import ani.dantotsu.BuildConfig import ani.dantotsu.R -import ani.dantotsu.connections.comments.CommentsAPI import ani.dantotsu.connections.discord.Discord import ani.dantotsu.connections.mal.MAL -import ani.dantotsu.media.Character import ani.dantotsu.media.Media import ani.dantotsu.others.AppUpdater import ani.dantotsu.settings.saving.PrefManager @@ -335,24 +333,57 @@ class GenresViewModel : ViewModel() { } } -class ProfileViewModel : ViewModel(){ +class ProfileViewModel : ViewModel() { private val mangaFav: MutableLiveData> = MutableLiveData>(null) + fun getMangaFav(): LiveData> = mangaFav private val animeFav: MutableLiveData> = MutableLiveData>(null) + fun getAnimeFav(): LiveData> = animeFav private val listImages: MutableLiveData> = MutableLiveData>(arrayListOf()) + fun getListImages(): LiveData> = listImages suspend fun setData(id: Int) { - mangaFav.postValue(Anilist.query.userFavMedia(false, id)) - animeFav.postValue(Anilist.query.userFavMedia(true, id)) - listImages.postValue(Anilist.query.getUserBannerImages(id)) + val res = Anilist.query.initProfilePage(id) + val mangaList = res?.data?.favoriteManga?.favourites?.manga?.edges?.mapNotNull { + it.node?.let { i -> + Media(i).apply { isFav = true } + } + } + mangaFav.postValue(ArrayList(mangaList ?: arrayListOf())) + val animeList = res?.data?.favoriteAnime?.favourites?.anime?.edges?.mapNotNull { + it.node?.let { i -> + Media(i).apply { isFav = true } + } + } + animeFav.postValue(ArrayList(animeList ?: arrayListOf())) + + val bannerImages = arrayListOf(null, null) + val animeRandom = res?.data?.animeMediaList?.lists?.mapNotNull { + it.entries?.mapNotNull { entry -> + val imageUrl = entry.media?.bannerImage + if (imageUrl != null && imageUrl != "null") imageUrl + else null + } + }?.flatten()?.randomOrNull() + bannerImages[0] = animeRandom + val mangaRandom = res?.data?.mangaMediaList?.lists?.mapNotNull { + it.entries?.mapNotNull { entry -> + val imageUrl = entry.media?.bannerImage + if (imageUrl != null && imageUrl != "null") imageUrl + else null + } + }?.flatten()?.randomOrNull() + bannerImages[1] = mangaRandom + listImages.postValue(bannerImages) + } fun refresh() { 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 fc074559..bf4310a7 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 @@ -139,6 +139,20 @@ class Query { ) } + @Serializable + data class ProfilePageMedia( + @SerialName("data") + val data: Data? + ) { + @Serializable + data class Data( + @SerialName("favoriteAnime") val favoriteAnime: ani.dantotsu.connections.anilist.api.User?, + @SerialName("favoriteManga") val favoriteManga: ani.dantotsu.connections.anilist.api.User?, + @SerialName("animeMediaList") val animeMediaList: ani.dantotsu.connections.anilist.api.MediaListCollection?, + @SerialName("mangaMediaList") val mangaMediaList: ani.dantotsu.connections.anilist.api.MediaListCollection? + ) + } + @Serializable data class ToggleFollow( @SerialName("data") diff --git a/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt b/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt index 3b878846..1fdeef98 100644 --- a/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt +++ b/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt @@ -34,6 +34,7 @@ class StatsFragment : private var statType: StatType = StatType.COUNT private lateinit var user: Query.UserProfile private lateinit var activity: ProfileActivity + private var loadedFirstTime = false override fun onCreateView( inflater: LayoutInflater, @@ -101,29 +102,32 @@ class StatsFragment : } binding.filterContainer.visibility = View.GONE - activity.lifecycleScope.launch { - stats.clear() - stats.add(Anilist.query.getUserStatistics(user.id)?.data?.user) - withContext(Dispatchers.Main) { - binding.filterContainer.visibility = View.VISIBLE - binding.sourceType.setOnItemClickListener { _, _, i, _ -> - type = MediaType.entries.toTypedArray()[i] - loadStats(type == MediaType.ANIME) - } - binding.sourceFilter.setOnItemClickListener { _, _, i, _ -> - statType = StatType.entries.toTypedArray()[i] - loadStats(type == MediaType.ANIME) - } - loadStats(type == MediaType.ANIME) - binding.statisticProgressBar.visibility = View.GONE - } - } } override fun onResume() { super.onResume() if (this::binding.isInitialized) { binding.root.requestLayout() + if (!loadedFirstTime) { + activity.lifecycleScope.launch { + stats.clear() + stats.add(Anilist.query.getUserStatistics(user.id)?.data?.user) + withContext(Dispatchers.Main) { + binding.filterContainer.visibility = View.VISIBLE + binding.sourceType.setOnItemClickListener { _, _, i, _ -> + type = MediaType.entries.toTypedArray()[i] + loadStats(type == MediaType.ANIME) + } + binding.sourceFilter.setOnItemClickListener { _, _, i, _ -> + statType = StatType.entries.toTypedArray()[i] + loadStats(type == MediaType.ANIME) + } + loadStats(type == MediaType.ANIME) + binding.statisticProgressBar.visibility = View.GONE + } + } + loadedFirstTime = true + } } loadStats(type == MediaType.ANIME) } diff --git a/app/src/main/java/ani/dantotsu/profile/activity/FeedFragment.kt b/app/src/main/java/ani/dantotsu/profile/activity/FeedFragment.kt index 720514c9..353748d7 100644 --- a/app/src/main/java/ani/dantotsu/profile/activity/FeedFragment.kt +++ b/app/src/main/java/ani/dantotsu/profile/activity/FeedFragment.kt @@ -28,6 +28,9 @@ class FeedFragment : Fragment() { private var activityList: List = emptyList() private lateinit var activity: androidx.activity.ComponentActivity private var page: Int = 1 + private var loadedFirstTime = false + private var userId: Int? = null + private var global: Boolean = false override fun onCreateView( inflater: LayoutInflater, @@ -38,7 +41,6 @@ class FeedFragment : Fragment() { return binding.root } - @SuppressLint("ClickableViewAccessibility") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) activity = requireActivity() @@ -46,52 +48,55 @@ class FeedFragment : Fragment() { binding.listRecyclerView.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false) binding.listProgressBar.visibility = ViewGroup.VISIBLE - var userId: Int? = arguments?.getInt("userId", -1) + userId = arguments?.getInt("userId", -1) if (userId == -1) userId = null - val global = arguments?.getBoolean("global", false) ?: false - - activity.lifecycleScope.launch(Dispatchers.IO) { - val res = Anilist.query.getFeed(userId, global) - withContext(Dispatchers.Main) { - res?.data?.page?.activities?.let { activities -> - activityList = activities - adapter.update(activityList.map { ActivityItem(it) { _, _ -> } }) - } - binding.listProgressBar.visibility = ViewGroup.GONE - val scrollView = binding.listRecyclerView - - binding.listRecyclerView.setOnTouchListener { _, event -> - if (event?.action == MotionEvent.ACTION_UP) { - if (adapter.itemCount % AnilistQueries.ITEMS_PER_PAGE != 0 && !global) { - snackString("No more activities") - } else if (!scrollView.canScrollVertically(1) && !binding.feedRefresh.isVisible - && binding.listRecyclerView.adapter!!.itemCount != 0 && - (binding.listRecyclerView.layoutManager as LinearLayoutManager).findLastVisibleItemPosition() == (binding.listRecyclerView.adapter!!.itemCount - 1) - ) { - page++ - binding.feedRefresh.visibility = ViewGroup.VISIBLE - activity.lifecycleScope.launch(Dispatchers.IO) { - val res = Anilist.query.getFeed(userId, global, page) - withContext(Dispatchers.Main) { - res?.data?.page?.activities?.let { activities -> - activityList += activities - adapter.addAll(activities.map { ActivityItem(it) { _, _ -> } }) - } - binding.feedRefresh.visibility = ViewGroup.GONE - } - } - } - } - false - } - } - } + global = arguments?.getBoolean("global", false) ?: false } + @SuppressLint("ClickableViewAccessibility") override fun onResume() { super.onResume() if (this::binding.isInitialized) { binding.root.requestLayout() + if (!loadedFirstTime) { + activity.lifecycleScope.launch(Dispatchers.IO) { + val res = Anilist.query.getFeed(userId, global) + withContext(Dispatchers.Main) { + res?.data?.page?.activities?.let { activities -> + activityList = activities + adapter.update(activityList.map { ActivityItem(it) { _, _ -> } }) + } + binding.listProgressBar.visibility = ViewGroup.GONE + val scrollView = binding.listRecyclerView + + binding.listRecyclerView.setOnTouchListener { _, event -> + if (event?.action == MotionEvent.ACTION_UP) { + if (adapter.itemCount % AnilistQueries.ITEMS_PER_PAGE != 0 && !global) { + snackString("No more activities") + } else if (!scrollView.canScrollVertically(1) && !binding.feedRefresh.isVisible + && binding.listRecyclerView.adapter!!.itemCount != 0 && + (binding.listRecyclerView.layoutManager as LinearLayoutManager).findLastVisibleItemPosition() == (binding.listRecyclerView.adapter!!.itemCount - 1) + ) { + page++ + binding.feedRefresh.visibility = ViewGroup.VISIBLE + activity.lifecycleScope.launch(Dispatchers.IO) { + val res = Anilist.query.getFeed(userId, global, page) + withContext(Dispatchers.Main) { + res?.data?.page?.activities?.let { activities -> + activityList += activities + adapter.addAll(activities.map { ActivityItem(it) { _, _ -> } }) + } + binding.feedRefresh.visibility = ViewGroup.GONE + } + } + } + } + false + } + } + } + loadedFirstTime = true + } } }