feat: following / followers page

This commit is contained in:
rebelonion 2024-03-05 19:33:42 -06:00
parent 8da0092561
commit 31afbd547e
17 changed files with 546 additions and 215 deletions

View file

@ -1278,12 +1278,19 @@ Page(page:$page,perPage:50) {
}
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<Query.Following>("""{Following:Page {following(userId:${id},sort:[USERNAME]){id name avatar{large medium}bannerImage}}}""", force = true)
return executeQuery<Query.Following>("""{Page {following(userId:${id},sort:[USERNAME]){id name avatar{large medium}bannerImage}}}""", force = true)
}
suspend fun userFollowers(id: Int): Query.Follower?{
return executeQuery<Query.Follower>("""{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<Query.MediaListCollection>("""{ MediaListCollection(userId: ${id}, type: $type, chunk:1,perChunk:25, sort: [SCORE_DESC,UPDATED_TIME_DESC]) { lists { entries{ media { id bannerImage } } } } } """)

View file

@ -143,73 +143,97 @@ class Query {
data class ToggleFollow(
@SerialName("data")
val data: Data?
) {
) : java.io.Serializable {
@Serializable
data class Data(
@SerialName("ToggleFollow")
val toggleFollow: FollowData
)
) : java.io.Serializable
}
@Serializable
data class GenreCollection(
@SerialName("data")
val data: Data
) {
) : java.io.Serializable {
@Serializable
data class Data(
@SerialName("GenreCollection")
val genreCollection: List<String>?
)
) : java.io.Serializable
}
@Serializable
data class MediaTagCollection(
@SerialName("data")
val data: Data
) {
) : java.io.Serializable {
@Serializable
data class Data(
@SerialName("MediaTagCollection")
val mediaTagCollection: List<MediaTag>?
)
) : java.io.Serializable
}
@Serializable
data class User(
@SerialName("data")
val data: Data
) {
) : java.io.Serializable {
@Serializable
data class Data(
@SerialName("User")
val user: ani.dantotsu.connections.anilist.api.User?
)
) : java.io.Serializable
}
@Serializable
data class UserProfileResponse(
@SerialName("data")
val data: Data
) {
) : java.io.Serializable {
@Serializable
data class Data(
@SerialName("user")
val user: UserProfile?
)
) : java.io.Serializable
}
@Serializable
data class Following(
@SerialName("data")
val data: Data
) {
) : java.io.Serializable {
@Serializable
data class Data(
@SerialName("following")
val following: ani.dantotsu.connections.anilist.api.User?
)
@SerialName("Page")
val page: FollowingPage?
) : java.io.Serializable
}
@Serializable
data class Follower(
@SerialName("data")
val data: Data
) : java.io.Serializable {
@Serializable
data class Data(
@SerialName("Page")
val page: FollowerPage?
) : java.io.Serializable
}
@Serializable
data class FollowerPage(
@SerialName("followers")
val followers: List<ani.dantotsu.connections.anilist.api.User>?
) : java.io.Serializable
@Serializable
data class FollowingPage(
@SerialName("following")
val following: List<ani.dantotsu.connections.anilist.api.User>?
) : java.io.Serializable
@Serializable
data class UserProfile(
@SerialName("id")
@ -342,7 +366,7 @@ class Query {
val mediaListOptions: MediaListOptions,
@SerialName("statistics")
val statistics: StatisticsTypes
)
) : java.io.Serializable
@Serializable
data class StatisticsTypes(
@ -350,7 +374,7 @@ class Query {
val anime: Statistics,
@SerialName("manga")
val manga: Statistics
)
) : java.io.Serializable
@Serializable
data class Statistics(
@ -392,7 +416,7 @@ class Query {
val staff: List<StatisticsStaff>,
@SerialName("studios")
val studios: List<StatisticsStudio>
)
) : java.io.Serializable
@Serializable
data class StatisticsFormat(
@ -408,7 +432,7 @@ class Query {
val mediaIds: List<Int>,
@SerialName("format")
val format: String
)
) : java.io.Serializable
@Serializable
data class StatisticsStatus(
@ -424,7 +448,7 @@ class Query {
val mediaIds: List<Int>,
@SerialName("status")
val status: String
)
) : java.io.Serializable
@Serializable
data class StatisticsScore(
@ -440,7 +464,7 @@ class Query {
val mediaIds: List<Int>,
@SerialName("score")
val score: Int
)
) : java.io.Serializable
@Serializable
data class StatisticsLength(
@ -456,7 +480,7 @@ class Query {
val mediaIds: List<Int>,
@SerialName("length")
val length: String? //can be null for manga
)
) : java.io.Serializable
@Serializable
data class StatisticsReleaseYear(
@ -472,7 +496,7 @@ class Query {
val mediaIds: List<Int>,
@SerialName("releaseYear")
val releaseYear: Int
)
) : java.io.Serializable
@Serializable
data class StatisticsStartYear(
@ -488,7 +512,7 @@ class Query {
val mediaIds: List<Int>,
@SerialName("startYear")
val startYear: Int
)
) : java.io.Serializable
@Serializable
data class StatisticsGenre(
@ -504,7 +528,7 @@ class Query {
val mediaIds: List<Int>,
@SerialName("genre")
val genre: String
)
) : java.io.Serializable
@Serializable
data class StatisticsTag(
@ -520,7 +544,7 @@ class Query {
val mediaIds: List<Int>,
@SerialName("tag")
val tag: Tag
)
) : java.io.Serializable
@Serializable
data class Tag(
@ -528,7 +552,7 @@ class Query {
val id: Int,
@SerialName("name")
val name: String
)
) : java.io.Serializable
@Serializable
data class StatisticsCountry(
@ -544,7 +568,7 @@ class Query {
val mediaIds: List<Int>,
@SerialName("country")
val country: String
)
) : java.io.Serializable
@Serializable
data class StatisticsVoiceActor(
@ -562,7 +586,7 @@ class Query {
val voiceActor: VoiceActor,
@SerialName("characterIds")
val characterIds: List<Int>
)
) : java.io.Serializable
@Serializable
data class VoiceActor(
@ -570,7 +594,7 @@ class Query {
val id: Int,
@SerialName("name")
val name: StaffName
)
) : java.io.Serializable
@Serializable
data class StaffName(
@ -588,7 +612,7 @@ class Query {
val alternative: List<String>?,
@SerialName("userPreferred")
val userPreferred: String?
)
) : java.io.Serializable
@Serializable
data class StatisticsStaff(
@ -604,7 +628,7 @@ class Query {
val mediaIds: List<Int>,
@SerialName("staff")
val staff: VoiceActor
)
) : java.io.Serializable
@Serializable
data class StatisticsStudio(
@ -620,7 +644,7 @@ class Query {
val mediaIds: List<Int>,
@SerialName("studio")
val studio: StatStudio
)
) : java.io.Serializable
@Serializable
data class StatStudio(
@ -630,7 +654,7 @@ class Query {
val name: String,
@SerialName("isAnimationStudio")
val isAnimationStudio: Boolean
)
) : java.io.Serializable
}

View file

@ -1,12 +1,24 @@
package ani.dantotsu.profile
import android.content.Intent
import android.os.Bundle
import android.view.ViewGroup.MarginLayoutParams
import android.widget.ImageButton
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.updateLayoutParams
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.R
import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.connections.anilist.api.User
import ani.dantotsu.databinding.ActivityFollowBinding
import ani.dantotsu.initActivity
import ani.dantotsu.navBarHeight
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.themes.ThemeManager
import com.xwray.groupie.GroupieAdapter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -14,19 +26,98 @@ import kotlinx.coroutines.withContext
class FollowActivity : AppCompatActivity(){
private lateinit var binding: ActivityFollowBinding
val adapter = GroupieAdapter()
var users: List<User>? = null
private lateinit var selected: ImageButton
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ThemeManager(this).applyTheme()
initActivity(this)
binding = ActivityFollowBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.listTitle.text = intent.getStringExtra("title")
val layoutType = PrefManager.getVal<Int>(PrefName.FollowerLayout)
selected = getSelected(layoutType)
binding.followerGrid.alpha = 0.33f
binding.followerList.alpha = 0.33f
selected(selected)
binding.root.updateLayoutParams<MarginLayoutParams> { topMargin += navBarHeight }
binding.listRecyclerView.layoutManager = LinearLayoutManager(
this,
LinearLayoutManager.VERTICAL,
false
)
binding.listRecyclerView.adapter = adapter
binding.listBack.setOnClickListener { finish() }
val title = intent.getStringExtra("title")
binding.listTitle.text = title
lifecycleScope.launch(Dispatchers.IO) {
val respond = Anilist.query.userFollowing(intent.getIntExtra("userId", 0))
val user = respond?.data?.following
val respond = when (title) {
"Following" -> Anilist.query.userFollowing(intent.getIntExtra("userId", 0))?.data?.page?.following
"Followers" -> Anilist.query.userFollowers(intent.getIntExtra("userId", 0))?.data?.page?.followers
else -> null
}
users = respond
withContext(Dispatchers.Main) {
user?.id
fillList()
}
}
binding.followerList.setOnClickListener {
selected(it as ImageButton)
PrefManager.setVal(PrefName.FollowerLayout, 0)
fillList()
}
binding.followerGrid.setOnClickListener {
selected(it as ImageButton)
PrefManager.setVal(PrefName.FollowerLayout, 1)
fillList()
}
}
private fun fillList() {
adapter.clear()
binding.listRecyclerView.layoutManager = when (getLayoutType(selected)) {
0 -> LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
1 -> GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false)
else -> LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
}
users?.forEach { user ->
if (getLayoutType(selected) == 0) {
adapter.add(FollowerItem(user.id, user.name ?: "Unknown", user.avatar?.medium, user.bannerImage) { onUserClick(it) })
} else {
adapter.add(GridFollowerItem(user.id, user.name ?: "Unknown", user.avatar?.medium) { onUserClick(it) })
}
}
}
fun selected(it: ImageButton) {
selected.alpha = 0.33f
selected = it
selected.alpha = 1f
}
private fun getSelected(pos: Int): ImageButton {
return when (pos) {
0 -> binding.followerList
1 -> binding.followerGrid
else -> binding.followerList
}
}
private fun getLayoutType(it: ImageButton): Int {
return when (it) {
binding.followerList -> 0
binding.followerGrid -> 1
else -> 0
}
}
private fun onUserClick(id: Int) {
val intent = Intent(this, ProfileActivity::class.java)
intent.putExtra("userId", id)
startActivity(intent)
}
}

View file

@ -0,0 +1,33 @@
package ani.dantotsu.profile
import android.view.View
import ani.dantotsu.R
import ani.dantotsu.databinding.ItemFollowerBinding
import ani.dantotsu.loadImage
import com.xwray.groupie.viewbinding.BindableItem
class FollowerItem(
private val id: Int,
private val name: String,
private val avatar: String?,
private val banner: String?,
val clickCallback: (Int) -> Unit
): BindableItem<ItemFollowerBinding>() {
private lateinit var binding: ItemFollowerBinding
override fun bind(viewBinding: ItemFollowerBinding, position: Int) {
binding = viewBinding
binding.profileUserName.text = name
avatar?.let { binding.profileUserAvatar.loadImage(it) }
banner?.let { binding.profileBannerImage.loadImage(it) }
binding.root.setOnClickListener { clickCallback(id) }
}
override fun getLayout(): Int {
return R.layout.item_follower
}
override fun initializeViewBinding(view: View): ItemFollowerBinding {
return ItemFollowerBinding.bind(view)
}
}

View file

@ -0,0 +1,31 @@
package ani.dantotsu.profile
import android.view.View
import ani.dantotsu.R
import ani.dantotsu.databinding.ItemFollowerGridBinding
import ani.dantotsu.loadImage
import com.xwray.groupie.viewbinding.BindableItem
class GridFollowerItem (
private val id: Int,
private val name: String,
private val avatar: String?,
val clickCallback: (Int) -> Unit
): BindableItem<ItemFollowerGridBinding>() {
private lateinit var binding: ItemFollowerGridBinding
override fun bind(viewBinding: ItemFollowerGridBinding, position: Int) {
binding = viewBinding
binding.profileUserName.text = name
avatar?.let { binding.profileUserAvatar.loadImage(it) }
binding.root.setOnClickListener { clickCallback(id) }
}
override fun getLayout(): Int {
return R.layout.item_follower_grid
}
override fun initializeViewBinding(view: View): ItemFollowerGridBinding {
return ItemFollowerGridBinding.bind(view)
}
}

View file

@ -5,6 +5,7 @@ import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.PopupMenu
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
@ -82,8 +83,10 @@ class ProfileActivity : AppCompatActivity() {
}
})
val userLevel = intent.getStringExtra("username") ?: ""
binding.followButton.visibility = if (user.id == Anilist.userid || Anilist.userid == null) View.GONE else View.VISIBLE
binding.followButton.text = if (user.isFollowing) "Unfollow" else if(user.isFollower) "Follows you" else "Follow"
binding.followButton.visibility =
if (user.id == Anilist.userid || Anilist.userid == null) View.GONE else View.VISIBLE
binding.followButton.text =
if (user.isFollowing) "Unfollow" else if (user.isFollower) "Follows you" else "Follow"
if (user.isFollowing && user.isFollower) binding.followButton.text = "Mutual"
binding.followButton.setOnClickListener {
lifecycleScope.launch(Dispatchers.IO) {
@ -92,8 +95,10 @@ class ProfileActivity : AppCompatActivity() {
withContext(Dispatchers.Main) {
snackString("Success")
user.isFollowing = res.data.toggleFollow.isFollowing
binding.followButton.text = if (user.isFollowing) "Unfollow" else if(user.isFollower) "Follows you" else "Follow"
if (user.isFollowing && user.isFollower) binding.followButton.text = "Mutual"
binding.followButton.text =
if (user.isFollowing) "Unfollow" else if (user.isFollower) "Follows you" else "Follow"
if (user.isFollowing && user.isFollower) binding.followButton.text =
"Mutual"
}
}
}
@ -101,12 +106,35 @@ class ProfileActivity : AppCompatActivity() {
binding.profileProgressBar.visibility = View.GONE
binding.profileTopContainer.visibility = View.VISIBLE
binding.temp.setOnClickListener {
binding.profileMenuButton.setOnClickListener {
val popup = PopupMenu(this@ProfileActivity, binding.profileMenuButton)
popup.menuInflater.inflate(R.menu.menu_profile, popup.menu)
popup.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.action_view_following -> {
ContextCompat.startActivity(
this@ProfileActivity, Intent(this@ProfileActivity, FollowActivity::class.java)
this@ProfileActivity,
Intent(this@ProfileActivity, FollowActivity::class.java)
.putExtra("title", "Following")
.putExtra("userId", user.id), null
.putExtra("userId", user.id),
null
)
true
}
R.id.action_view_followers -> {
ContextCompat.startActivity(
this@ProfileActivity,
Intent(this@ProfileActivity, FollowActivity::class.java)
.putExtra("title", "Followers")
.putExtra("userId", user.id),
null
)
true
}
else -> false
}
}
popup.show()
}
binding.profileUserAvatar.loadImage(user.avatar?.medium)
@ -122,6 +150,10 @@ class ProfileActivity : AppCompatActivity() {
if (!(PrefManager.getVal(PrefName.BannerAnimations) as Boolean)) binding.profileBannerImage.pause()
binding.profileBannerImage.loadImage(user.bannerImage)
binding.profileBannerImage.updateLayoutParams { height += statusBarHeight }
binding.profileBannerGradient.updateLayoutParams { height += statusBarHeight }
binding.profileMenuButton.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin += statusBarHeight
}
binding.profileBannerImage.setOnLongClickListener {
ImageViewDialog.newInstance(
this@ProfileActivity,
@ -132,7 +164,6 @@ class ProfileActivity : AppCompatActivity() {
}
}
}
override fun onResume() {

View file

@ -47,11 +47,11 @@ class ProfileFragment() : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activity = requireActivity() as ProfileActivity
user = arguments?.getSerializable("user") as Query.UserProfile
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
model.setData(user.id)
}
user = arguments?.getSerializable("user") as Query.UserProfile
val backGroundColorTypedValue = TypedValue()
val textColorTypedValue = TypedValue()
activity.theme.resolveAttribute(

View file

@ -66,6 +66,7 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
AnimeListSortOrder(Pref(Location.UI, String::class, "score")),
MangaListSortOrder(Pref(Location.UI, String::class, "score")),
CommentSortOrder(Pref(Location.UI, String::class, "newest")),
FollowerLayout(Pref(Location.UI, Int::class, 0)),
//Player
DefaultSpeed(Pref(Location.Player, Int::class, 5)),

View file

@ -1,38 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ProgressBar
android:id="@+id/listProgressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"/>
android:visibility="gone" />
<FrameLayout
android:layout_marginTop="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/listBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_marginStart="12dp"
android:src="@drawable/ic_round_arrow_back_ios_new_24"
app:tint="?attr/colorOnBackground"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/listTitle"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginStart="32dp"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginStart="44dp"
android:ellipsize="end"
android:fontFamily="@font/poppins_bold"
android:gravity="center|start"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"
android:textColor="?attr/colorOnBackground"
android:textSize="16sp"
android:textSize="18sp"
tools:text="xyz" />
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="8dp"
app:cardBackgroundColor="@color/nav_bg_inv"
app:cardCornerRadius="16dp"
app:cardElevation="0dp">
<ImageButton
android:id="@+id/followerList"
android:layout_width="36dp"
android:layout_height="36dp"
android:alpha="0.33"
android:background="?android:attr/selectableItemBackground"
android:scaleX="-1"
app:srcCompat="@drawable/ic_round_view_list_24"
app:tint="?attr/colorOnBackground"
tools:ignore="ContentDescription,SpeakableTextPresentCheck,ImageContrastCheck" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="46dp"
app:cardBackgroundColor="@color/nav_bg_inv"
app:cardCornerRadius="16dp"
app:cardElevation="0dp">
<ImageButton
android:id="@+id/followerGrid"
android:layout_width="36dp"
android:layout_height="36dp"
android:alpha="0.33"
android:background="?android:attr/selectableItemBackground"
app:srcCompat="@drawable/ic_round_grid_view_24"
app:tint="?attr/colorOnBackground"
tools:ignore="ContentDescription,SpeakableTextPresentCheck,ImageContrastCheck" />
</androidx.cardview.widget.CardView>
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/listRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
tools:listitem="@layout/item_follow"/>
android:layout_marginEnd="16dp"
tools:listitem="@layout/item_follower" />
</LinearLayout>

View file

@ -22,16 +22,22 @@
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
android:layout_marginBottom="72dp">
android:layout_marginBottom="72dp"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/profileTopContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible"
android:orientation="vertical">
tools:visibility="visible">
<com.flaviofaria.kenburnsview.KenBurnsView
android:id="@+id/profileBannerImage"
android:layout_width="match_parent"
@ -41,19 +47,17 @@
tools:src="@tools:sample/backgrounds/scenic" />
<ImageView
android:id="@+id/profileBannerGradient"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginTop="-200dp"
android:src="@drawable/linear_gradient_bg"
tools:ignore="ContentDescription" />
<LinearLayout
android:id="@+id/profileUserDataContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-171dp"
android:layout_gravity="center"
android:layout_gravity="center_horizontal|bottom"
android:orientation="vertical"
tools:visibility="visible">
@ -71,8 +75,8 @@
android:layout_height="82dp"
android:layout_gravity="center"
app:srcCompat="@drawable/ic_round_add_circle_24"
tools:tint="@color/transparent"
tools:ignore="ContentDescription,ImageContrastCheck" />
tools:ignore="ContentDescription,ImageContrastCheck"
tools:tint="@color/transparent" />
</com.google.android.material.card.MaterialCardView>
@ -80,11 +84,11 @@
android:id="@+id/profileUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_gravity="center"
android:textColor="?attr/colorPrimary"
android:layout_marginTop="10dp"
android:fontFamily="@font/poppins_semi_bold"
android:text="@string/username"
android:textColor="?attr/colorPrimary"
android:textSize="18sp" />
<Button
@ -92,32 +96,30 @@
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="true"
android:layout_gravity="center"
android:fontFamily="@font/poppins_bold"
android:textColor="@color/bg_opp"
android:text="Follow"
android:textSize="14sp"
android:backgroundTint="?attr/colorPrimaryContainer"
android:enabled="true"
android:fontFamily="@font/poppins_bold"
android:text="Follow"
android:textColor="@color/bg_opp"
android:textSize="14sp"
app:cornerRadius="8dp"
app:strokeColor="?attr/colorPrimaryContainer"
tools:ignore="SpeakableTextPresentCheck" />
<Button
android:id="@+id/temp"
style="@style/Widget.Material3.Button.OutlinedButton"
</LinearLayout>
<ImageView
android:id="@+id/profileMenuButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="true"
android:layout_gravity="center"
android:fontFamily="@font/poppins_bold"
android:textColor="@color/bg_opp"
android:text="temp"
android:textSize="14sp"
android:backgroundTint="?attr/colorPrimaryContainer"
app:cornerRadius="8dp"
app:strokeColor="?attr/colorPrimaryContainer"
tools:ignore="SpeakableTextPresentCheck" />
</LinearLayout>
android:layout_gravity="end"
android:layout_marginTop="20dp"
android:layout_marginEnd="16dp"
android:contentDescription="@string/menu"
android:src="@drawable/ic_round_dots_vertical_24" />
</FrameLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/profileViewPager"
@ -126,6 +128,7 @@
tools:ignore="SpeakableTextPresentCheck" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View file

@ -141,12 +141,12 @@
android:id="@+id/profileUserStatsTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="32dp"
android:fontFamily="@font/poppins_bold"
android:text="Stats"
android:textSize="16sp"
android:textSize="18sp"
tools:ignore="HardcodedText" />
<TableLayout
@ -341,18 +341,19 @@
android:id="@+id/profileUserBioTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="32dp"
android:fontFamily="@font/poppins_bold"
android:text="Bio"
android:textSize="16sp"
android:textSize="18sp"
tools:ignore="HardcodedText" />
<WebView
android:id="@+id/profileUserBio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textAlignment="textStart"
@ -373,11 +374,11 @@
android:id="@+id/profileFavAnime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginStart="8dp"
android:fontFamily="@font/poppins_bold"
android:padding="8dp"
android:text="@string/fav_anime"
android:textSize="16sp" />
android:textSize="18sp" />
<FrameLayout
android:layout_width="match_parent"
@ -447,11 +448,11 @@
android:id="@+id/profileFavManga"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginStart="8dp"
android:fontFamily="@font/poppins_bold"
android:padding="8dp"
android:text="@string/fav_manga"
android:textSize="16sp" />
android:textSize="18sp" />
<FrameLayout
android:layout_width="match_parent"
@ -517,12 +518,12 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="32dp"
android:fontFamily="@font/poppins_bold"
android:text="Favorite Characters"
android:textSize="16sp" />
android:textSize="18sp" />
<ani.dantotsu.FadingEdgeRecyclerView
android:id="@+id/profileFavCharactersRecycler"
@ -548,12 +549,12 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="32dp"
android:fontFamily="@font/poppins_bold"
android:text="Favorite Staff"
android:textSize="16sp" />
android:textSize="18sp" />
<ani.dantotsu.FadingEdgeRecyclerView
android:id="@+id/profileFavStaffRecycler"

View file

@ -1,55 +0,0 @@
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="80dp"
app:cardCornerRadius="16dp"
android:layout_marginBottom="16dp">
<ImageView
android:id="@+id/followBanner"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="ContentDescription,ImageContrastCheck" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_gravity="center"
app:cardCornerRadius="32dp">
<ImageView
android:id="@+id/followProfile"
android:layout_width="64dp"
android:layout_height="64dp"
tools:ignore="ContentDescription,ImageContrastCheck"
tools:srcCompat="@tools:sample/avatars" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/followName"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="10dp"
android:gravity="center_vertical"
android:fontFamily="@font/poppins_bold"
android:textColor="?attr/colorSecondary"
tools:text="Username"
tools:ignore="RtlSymmetry" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_gravity="bottom"
android:layout_height="4dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
</androidx.cardview.widget.CardView>

View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="120dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_marginBottom="8dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/profileBannerImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/linear_gradient_bg"
tools:ignore="ContentDescription" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bg_black_50"
tools:ignore="ContentDescription" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/profileUserAvatarContainer"
android:layout_width="82dp"
android:layout_height="82dp"
android:layout_gravity="start|center_vertical"
android:layout_marginStart="16dp"
android:backgroundTint="@color/bg_white"
app:cardCornerRadius="64dp">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/profileUserAvatar"
android:layout_width="82dp"
android:layout_height="82dp"
android:layout_gravity="center"
app:srcCompat="@drawable/ic_round_add_circle_24"
tools:tint="@color/transparent"
tools:ignore="ContentDescription,ImageContrastCheck" />
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/profileUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_marginStart="120dp"
android:text="Username"
android:textColor="@color/bg_white"
android:textSize="18sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
</FrameLayout>

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:padding="8dp"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<ImageView
android:id="@+id/profileUserAvatar"
android:layout_width="112dp"
android:layout_height="112dp"
android:layout_gravity="center"
tools:tint="@color/transparent"
tools:ignore="ContentDescription,ImageContrastCheck" />
<TextView
android:id="@+id/profileUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:text="Username"
android:textColor="?attr/colorOnBackground"
android:textSize="12sp"
android:ellipsize="end"
android:textStyle="bold"
tools:ignore="HardcodedText" />
</LinearLayout>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_view_following"
android:title="@string/view_following"
app:showAsAction="never" />
<item
android:id="@+id/action_view_followers"
android:title="@string/view_followers"
app:showAsAction="never" />
</menu>

View file

@ -8,6 +8,7 @@
<color name="bg">@color/bg_white</color>
<color name="bg_opp">@color/bg_black</color>
<color name="fg">#A8000000</color>
<color name="bg_black_50" alpha="128">#80000000</color>
<color name="nav_bg">#fff</color>
<color name="nav_bg_inv">#00FFFFFF</color>
<color name="nav_tab">#40000000</color>

View file

@ -666,6 +666,9 @@
<string name="highest_rated">Highest rated</string>
<string name="lowest_rated">Lowest rated</string>
<string name="compare"><u>Compare</u></string>
<string name="view_following">View Following</string>
<string name="menu">menu</string>
<string name="view_followers">View Followers</string>
</resources>