From 86ed72179663d44d21bdfc4f8f22c6dd5021fc3e Mon Sep 17 00:00:00 2001 From: aayush262 Date: Sat, 2 Mar 2024 23:01:58 +0530 Subject: [PATCH] feat(profile page): Stats, Banner animation --- .../dantotsu/media/comments/CommentItem.kt | 18 +- .../ani/dantotsu/profile/ProfileActivity.kt | 51 +- .../ani/dantotsu/profile/ProfileFragment.kt | 14 +- .../ani/dantotsu/profile/StatsFragment.kt | 4 +- app/src/main/res/layout/activity_profile.xml | 22 +- app/src/main/res/layout/fragment_profile.xml | 448 +++++++++++++----- 6 files changed, 410 insertions(+), 147 deletions(-) diff --git a/app/src/main/java/ani/dantotsu/media/comments/CommentItem.kt b/app/src/main/java/ani/dantotsu/media/comments/CommentItem.kt index 90419d877a4..b5d2f883bd6 100644 --- a/app/src/main/java/ani/dantotsu/media/comments/CommentItem.kt +++ b/app/src/main/java/ani/dantotsu/media/comments/CommentItem.kt @@ -12,6 +12,7 @@ import ani.dantotsu.connections.comments.CommentsAPI import ani.dantotsu.copyToClipboard import ani.dantotsu.databinding.ItemCommentsBinding import ani.dantotsu.loadImage +import ani.dantotsu.others.ImageViewDialog import ani.dantotsu.profile.ProfileActivity import ani.dantotsu.snackString import com.xwray.groupie.GroupieAdapter @@ -101,7 +102,13 @@ class CommentItem(val comment: Comment, .putExtra("userId", comment.userId.toInt()) .putExtra("username","[${levelColor.second}]"), null ) - + } + viewBinding.commentUserAvatar.setOnClickListener { + ContextCompat.startActivity( + commentsFragment.activity, Intent(commentsFragment.activity, ProfileActivity::class.java) + .putExtra("userId", comment.userId.toInt()) + .putExtra("username","[${levelColor.second}]"), null + ) } viewBinding.commentText.setOnLongClickListener { copyToClipboard(comment.content) @@ -193,10 +200,15 @@ class CommentItem(val comment: Comment, } } viewBinding.commentTotalVotes.text = (comment.upvotes - comment.downvotes).toString() - viewBinding.commentUserAvatar + viewBinding.commentUserAvatar.setOnLongClickListener { + ImageViewDialog.newInstance( + commentsFragment.activity, + "${comment.username}'s [Cover]", + comment.profilePictureUrl + ) + } comment.profilePictureUrl?.let { viewBinding.commentUserAvatar.loadImage(it) } viewBinding.commentUserName.text = comment.username - viewBinding.commentUserLevel.text = "[${levelColor.second}]" viewBinding.commentUserLevel.setTextColor(levelColor.first) viewBinding.commentUserTime.text = formatTimestamp(comment.timestamp) diff --git a/app/src/main/java/ani/dantotsu/profile/ProfileActivity.kt b/app/src/main/java/ani/dantotsu/profile/ProfileActivity.kt index 5c77d40fa6d..036a3d06afe 100644 --- a/app/src/main/java/ani/dantotsu/profile/ProfileActivity.kt +++ b/app/src/main/java/ani/dantotsu/profile/ProfileActivity.kt @@ -4,8 +4,10 @@ import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat +import androidx.core.view.updateLayoutParams import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.lifecycle.Lifecycle @@ -20,8 +22,12 @@ import ani.dantotsu.loadImage import ani.dantotsu.media.Media import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.media.user.ListActivity +import ani.dantotsu.navBarHeight import ani.dantotsu.others.ImageViewDialog +import ani.dantotsu.settings.saving.PrefManager +import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.snackString +import ani.dantotsu.statusBarHeight import ani.dantotsu.themes.ThemeManager import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -32,7 +38,7 @@ import nl.joery.animatedbottombar.AnimatedBottomBar class ProfileActivity : AppCompatActivity(){ private lateinit var binding: ActivityProfileBinding private var selected: Int = 0 - private lateinit var tabLayout: AnimatedBottomBar + private lateinit var navBar: AnimatedBottomBar @SuppressLint("SetTextI18n") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -40,15 +46,14 @@ class ProfileActivity : AppCompatActivity(){ initActivity(this) binding = ActivityProfileBinding.inflate(layoutInflater) setContentView(binding.root) - tabLayout = binding.typeTab - val profileTab = tabLayout.createTab(R.drawable.ic_round_person_24, "Profile") - val statsTab = tabLayout.createTab(R.drawable.ic_stats_24, "Stats") - tabLayout.addTab(profileTab) - tabLayout.addTab(statsTab) - tabLayout.visibility = View.GONE + navBar = binding.profileNavBar + navBar.updateLayoutParams { bottomMargin = navBarHeight } + val profileTab = navBar.createTab(R.drawable.ic_round_person_24, "Profile") + val statsTab = navBar.createTab(R.drawable.ic_stats_24, "Stats") + navBar.addTab(profileTab) + navBar.addTab(statsTab) + navBar.visibility = View.GONE binding.mediaViewPager.isUserInputEnabled = false - - lifecycleScope.launch(Dispatchers.IO) { val userid = intent.getIntExtra("userId", 0) val respond = Anilist.query.getUserProfile(userid) @@ -60,9 +65,9 @@ class ProfileActivity : AppCompatActivity(){ } withContext(Dispatchers.Main) { binding.mediaViewPager.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle, user, this@ProfileActivity) - tabLayout.visibility = View.VISIBLE - tabLayout.selectTabAt(selected) - tabLayout.setOnTabSelectListener(object : AnimatedBottomBar.OnTabSelectListener { + navBar.visibility = View.VISIBLE + navBar.selectTabAt(selected) + navBar.setOnTabSelectListener(object : AnimatedBottomBar.OnTabSelectListener { override fun onTabSelected( lastIndex: Int, lastTab: AnimatedBottomBar.Tab?, @@ -76,13 +81,29 @@ class ProfileActivity : AppCompatActivity(){ val userLevel = intent.getStringExtra("username")?: "" binding.profileProgressBar.visibility = View.GONE + binding.profileTopContainer.visibility = View.VISIBLE binding.profileBannerImage.loadImage(user.bannerImage) + binding.profileBannerImage.setOnLongClickListener { + ImageViewDialog.newInstance( + this@ProfileActivity, + "${user.name}'s [Banner]", + user.bannerImage + ) + } binding.profileUserAvatar.loadImage(user.avatar?.medium) + binding.profileUserAvatar.setOnLongClickListener { + ImageViewDialog.newInstance( + this@ProfileActivity, + "${user.name}'s [Avatar]", + user.avatar?.medium + ) + } binding.profileUserName.text = "${user.name} $userLevel" binding.profileUserEpisodesWatched.text = user.statistics.anime.episodesWatched.toString() binding.profileUserChaptersRead.text = user.statistics.manga.chaptersRead.toString() - + if (!(PrefManager.getVal(PrefName.BannerAnimations) as Boolean)) binding.profileBannerImage.pause() binding.profileBannerImage.loadImage(user.bannerImage) + binding.profileBannerImage.updateLayoutParams { height += statusBarHeight } binding.profileBannerImage.setOnLongClickListener { ImageViewDialog.newInstance( this@ProfileActivity, @@ -104,8 +125,8 @@ class ProfileActivity : AppCompatActivity(){ } override fun onResume() { - if (this::tabLayout.isInitialized) { - tabLayout.selectTabAt(selected) + if (this::navBar.isInitialized) { + navBar.selectTabAt(selected) } super.onResume() } diff --git a/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt b/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt index 504bce577b9..2fa98c9c09f 100644 --- a/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt +++ b/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt @@ -27,7 +27,9 @@ class ProfileFragment(private val user: Query.UserProfile, private val activity: override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val markwon = buildMarkwon(activity, false) - markwon.setMarkdown(binding.profileUserInfo, user.about?:"") + markwon.setMarkdown(binding.profileUserBio, user.about?:"") + binding.userInfoContainer.visibility = if (user.about != null) View.VISIBLE else View.GONE + binding.profileAnimeList.setOnClickListener { ContextCompat.startActivity( activity, Intent(activity, ListActivity::class.java) @@ -46,5 +48,15 @@ class ProfileFragment(private val user: Query.UserProfile, private val activity: } binding.profileAnimeListImage.loadImage("https://bit.ly/31bsIHq") binding.profileMangaListImage.loadImage("https://bit.ly/2ZGfcuG") + binding.statsEpisodesWatched.text = user.statistics.anime.episodesWatched.toString() + binding.statsDaysWatched.text = (user.statistics.anime.minutesWatched / (24 * 60)).toString() + binding.statsTotalAnime.text = user.statistics.anime.count.toString() + binding.statsAnimeMeanScore.text = user.statistics.anime.meanScore.toString() + binding.statsChaptersRead.text = user.statistics.manga.chaptersRead.toString() + binding.statsVolumeRead.text = (user.statistics.manga.volumesRead).toString() + binding.statsTotalManga.text = user.statistics.manga.count.toString() + binding.statsMangaMeanScore.text = user.statistics.manga.meanScore.toString() + + } } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt b/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt index 153f60cf021..2ce90ae2b78 100644 --- a/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt +++ b/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt @@ -129,12 +129,12 @@ class StatsFragment(private val user: Query.UserProfile, private val activity: P val fotmatTypes: List = if (anime) { stats?.data?.user?.statistics?.anime?.formats?.map { it.format } ?: emptyList() } else { - stats?.data?.user?.statistics?.manga?.formats?.map { it.format } ?: emptyList() + stats?.data?.user?.statistics?.manga?.countries?.map { it.country } ?: emptyList() } val formatCount: List = if (anime) { stats?.data?.user?.statistics?.anime?.formats?.map { it.count } ?: emptyList() } else { - stats?.data?.user?.statistics?.manga?.formats?.map { it.count } ?: emptyList() + stats?.data?.user?.statistics?.manga?.countries?.map { it.count } ?: emptyList() } if (fotmatTypes.isEmpty() || formatCount.isEmpty()) return null diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index 36aa8560fce..7bd0b006ae2 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -28,14 +28,22 @@ android:id="@+id/profileTopContainer" android:layout_width="match_parent" android:layout_height="wrap_content" + android:visibility="gone" + tools:visibility="visible" android:orientation="vertical"> - - + + + app:cardCornerRadius="64dp"> @@ -141,7 +149,7 @@ - - - + android:orientation="vertical"> + + - - - + android:layout_height="wrap_content" + android:clipToPadding="false" + android:paddingStart="24dp" + android:paddingEnd="24dp"> - + android:layout_height="72dp" + android:layout_margin="8dp" + app:boxStrokeColor="@color/text_input_layout_stroke_color" + app:cardCornerRadius="16dp" + app:layout_constrainedWidth="true" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/profileMangaList" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintWidth_max="256dp" + tools:visibility="visible"> - + - + + + android:orientation="vertical"> + + + + + + + + + + + + - - + android:orientation="vertical"> + + + + + + + + + + + + + + + + + + - - - + + + android:layout_height="24dp" + android:orientation="horizontal"> - + + + + + + + android:layout_height="24dp" + android:orientation="horizontal"> - + + + + + + + + + android:textAlignment="textEnd" /> + - - + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file