feat: global/personal feed | like posts | pagination
This commit is contained in:
parent
a9b03c45c6
commit
98f4d4f30b
19 changed files with 438 additions and 144 deletions
|
@ -115,7 +115,7 @@
|
|||
android:windowSoftInputMode="adjustResize|stateHidden"
|
||||
android:parentActivityName=".MainActivity" />
|
||||
<activity
|
||||
android:name=".profile.activity.ActivityActivity"
|
||||
android:name=".profile.activity.FeedActivity"
|
||||
android:label="Inbox Activity"
|
||||
android:parentActivityName=".MainActivity" >
|
||||
</activity>
|
||||
|
|
|
@ -28,6 +28,7 @@ import android.telephony.TelephonyManager
|
|||
import android.text.InputFilter
|
||||
import android.text.Spanned
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.util.TypedValue
|
||||
import android.view.*
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
|
@ -129,7 +130,8 @@ var loadIsMAL = false
|
|||
|
||||
fun logger(e: Any?, print: Boolean = true) {
|
||||
if (print)
|
||||
println(e)
|
||||
//println(e)
|
||||
Log.d("Logger", e.toString())
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,10 +8,10 @@ import ani.dantotsu.connections.anilist.Anilist.authorRoles
|
|||
import ani.dantotsu.connections.anilist.Anilist.executeQuery
|
||||
import ani.dantotsu.connections.anilist.api.FeedResponse
|
||||
import ani.dantotsu.connections.anilist.api.FuzzyDate
|
||||
import ani.dantotsu.connections.anilist.api.Notification
|
||||
import ani.dantotsu.connections.anilist.api.NotificationResponse
|
||||
import ani.dantotsu.connections.anilist.api.Page
|
||||
import ani.dantotsu.connections.anilist.api.Query
|
||||
import ani.dantotsu.connections.anilist.api.ToggleLike
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.isOnline
|
||||
import ani.dantotsu.logError
|
||||
|
@ -1265,10 +1265,15 @@ Page(page:$page,perPage:50) {
|
|||
}
|
||||
|
||||
suspend fun toggleFollow(id: Int): Query.ToggleFollow? {
|
||||
val response = executeQuery<Query.ToggleFollow>(
|
||||
return executeQuery<Query.ToggleFollow>(
|
||||
"""mutation{ToggleFollow(userId:$id){id, isFollowing, isFollower}}"""
|
||||
)
|
||||
return response
|
||||
}
|
||||
|
||||
suspend fun toggleLike(id: Int, type: String): ToggleLike? {
|
||||
return executeQuery<ToggleLike>(
|
||||
"""mutation Like{ToggleLikeV2(id:$id,type:$type){__typename}}"""
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getUserProfile(id: Int): Query.UserProfileResponse? {
|
||||
|
@ -1342,8 +1347,8 @@ Page(page:$page,perPage:50) {
|
|||
return default
|
||||
}
|
||||
|
||||
suspend fun getNotifications(id: Int): NotificationResponse? {
|
||||
val res = executeQuery<NotificationResponse>("""{User(id:$id){unreadNotificationCount}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)
|
||||
suspend fun getNotifications(id: Int, page: Int = 1): NotificationResponse? {
|
||||
val res = executeQuery<NotificationResponse>("""{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
|
||||
}
|
||||
|
@ -1354,7 +1359,11 @@ Page(page:$page,perPage:50) {
|
|||
val filter = if (userId != null) "userId:$userId,"
|
||||
else if (global) "isFollowing:false,"
|
||||
else "isFollowing:true,"
|
||||
val res = executeQuery<FeedResponse>("""{Page(page:$page,perPage:25){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<FeedResponse>("""{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
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ITEMS_PER_PAGE = 25
|
||||
}
|
||||
}
|
|
@ -7,19 +7,19 @@ import kotlinx.serialization.Serializable
|
|||
data class FeedResponse(
|
||||
@SerialName("data")
|
||||
val data: Data
|
||||
) {
|
||||
) : java.io.Serializable {
|
||||
@Serializable
|
||||
data class Data(
|
||||
@SerialName("Page")
|
||||
val page: ActivityPage
|
||||
)
|
||||
) : java.io.Serializable
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ActivityPage(
|
||||
@SerialName("activities")
|
||||
val activities: List<Activity>
|
||||
)
|
||||
) : java.io.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Activity(
|
||||
|
@ -52,9 +52,9 @@ data class Activity(
|
|||
@SerialName("isSubscribed")
|
||||
val isSubscribed: Boolean,
|
||||
@SerialName("likeCount")
|
||||
val likeCount: Int?,
|
||||
var likeCount: Int?,
|
||||
@SerialName("isLiked")
|
||||
val isLiked: Boolean?,
|
||||
var isLiked: Boolean?,
|
||||
@SerialName("isPinned")
|
||||
val isPinned: Boolean?,
|
||||
@SerialName("isPrivate")
|
||||
|
@ -69,7 +69,7 @@ data class Activity(
|
|||
val replies: List<Reply>?,
|
||||
@SerialName("likes")
|
||||
val likes: List<User>?,
|
||||
)
|
||||
) : java.io.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Reply(
|
||||
|
@ -89,4 +89,22 @@ data class Reply(
|
|||
val user: User,
|
||||
@SerialName("likes")
|
||||
val likes: List<User>?,
|
||||
)
|
||||
) : java.io.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ToggleLike(
|
||||
@SerialName("data")
|
||||
val data: Data
|
||||
) : java.io.Serializable {
|
||||
@Serializable
|
||||
data class Data(
|
||||
@SerialName("ToggleLikeV2")
|
||||
val toggleLike: LikeData
|
||||
) : java.io.Serializable
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class LikeData(
|
||||
@SerialName("__typename")
|
||||
val typename: String
|
||||
) : java.io.Serializable
|
|
@ -14,6 +14,7 @@ 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.statusBarHeight
|
||||
|
@ -36,6 +37,7 @@ class FollowActivity : AppCompatActivity(){
|
|||
initActivity(this)
|
||||
binding = ActivityFollowBinding.inflate(layoutInflater)
|
||||
binding.listToolbar.updateLayoutParams<MarginLayoutParams> { topMargin = statusBarHeight }
|
||||
binding.listFrameLayout.updateLayoutParams<MarginLayoutParams> { bottomMargin = navBarHeight }
|
||||
setContentView(binding.root)
|
||||
val layoutType = PrefManager.getVal<Int>(PrefName.FollowerLayout)
|
||||
selected = getSelected(layoutType)
|
||||
|
|
|
@ -22,7 +22,7 @@ import ani.dantotsu.initActivity
|
|||
import ani.dantotsu.loadImage
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.others.ImageViewDialog
|
||||
import ani.dantotsu.profile.activity.ActivityActivity
|
||||
import ani.dantotsu.profile.activity.FeedFragment
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.snackString
|
||||
|
@ -36,8 +36,8 @@ import nl.joery.animatedbottombar.AnimatedBottomBar
|
|||
|
||||
|
||||
class ProfileActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityProfileBinding
|
||||
private var selected: Int = 0
|
||||
lateinit var binding: ActivityProfileBinding
|
||||
private var selected: Int = 1
|
||||
private lateinit var navBar: AnimatedBottomBar
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
|
@ -49,8 +49,10 @@ class ProfileActivity : AppCompatActivity() {
|
|||
setContentView(binding.root)
|
||||
navBar = binding.profileNavBar
|
||||
navBar.updateLayoutParams<ViewGroup.MarginLayoutParams> { bottomMargin = navBarHeight }
|
||||
val feedTab = navBar.createTab(R.drawable.ic_round_filter_24, "Feed")
|
||||
val profileTab = navBar.createTab(R.drawable.ic_round_person_24, "Profile")
|
||||
val statsTab = navBar.createTab(R.drawable.ic_stats_24, "Stats")
|
||||
navBar.addTab(feedTab)
|
||||
navBar.addTab(profileTab)
|
||||
navBar.addTab(statsTab)
|
||||
navBar.visibility = View.GONE
|
||||
|
@ -70,6 +72,7 @@ class ProfileActivity : AppCompatActivity() {
|
|||
}
|
||||
binding.profileViewPager.adapter =
|
||||
ViewPagerAdapter(supportFragmentManager, lifecycle, user)
|
||||
binding.profileViewPager.setCurrentItem(selected, false)
|
||||
navBar.visibility = View.VISIBLE
|
||||
navBar.selectTabAt(selected)
|
||||
navBar.setOnTabSelectListener(object : AnimatedBottomBar.OnTabSelectListener {
|
||||
|
@ -106,15 +109,6 @@ class ProfileActivity : AppCompatActivity() {
|
|||
}
|
||||
binding.profileProgressBar.visibility = View.GONE
|
||||
binding.profileTopContainer.visibility = View.VISIBLE
|
||||
binding.profileActivityButton.setOnClickListener {
|
||||
ContextCompat.startActivity(
|
||||
this@ProfileActivity,
|
||||
Intent(this@ProfileActivity, ActivityActivity::class.java)
|
||||
.putExtra("userId", user.id)
|
||||
.putExtra("username", user.name),
|
||||
null
|
||||
)
|
||||
}
|
||||
binding.profileMenuButton.setOnClickListener {
|
||||
val popup = PopupMenu(this@ProfileActivity, binding.profileMenuButton)
|
||||
popup.menuInflater.inflate(R.menu.menu_profile, popup.menu)
|
||||
|
@ -161,7 +155,6 @@ class ProfileActivity : AppCompatActivity() {
|
|||
binding.profileBannerImage.updateLayoutParams { height += statusBarHeight }
|
||||
binding.profileBannerGradient.updateLayoutParams { height += statusBarHeight }
|
||||
binding.profileMenuButton.updateLayoutParams<ViewGroup.MarginLayoutParams> { topMargin += statusBarHeight }
|
||||
binding.profileActivityButton.updateLayoutParams<ViewGroup.MarginLayoutParams> { topMargin += statusBarHeight }
|
||||
binding.profileBannerImage.setOnLongClickListener {
|
||||
ImageViewDialog.newInstance(
|
||||
this@ProfileActivity,
|
||||
|
@ -188,10 +181,11 @@ class ProfileActivity : AppCompatActivity() {
|
|||
) :
|
||||
FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||
|
||||
override fun getItemCount(): Int = 2
|
||||
override fun getItemCount(): Int = 3
|
||||
override fun createFragment(position: Int): Fragment = when (position) {
|
||||
0 -> ProfileFragment.newInstance(user)
|
||||
1 -> StatsFragment.newInstance(user)
|
||||
0 -> FeedFragment.newInstance(user.id, false)
|
||||
1 -> ProfileFragment.newInstance(user)
|
||||
2 -> StatsFragment.newInstance(user)
|
||||
else -> ProfileFragment.newInstance(user)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class ProfileFragment() : Fragment() {
|
||||
class ProfileFragment : Fragment() {
|
||||
lateinit var binding: FragmentProfileBinding
|
||||
private lateinit var activity: ProfileActivity
|
||||
private lateinit var user: Query.UserProfile
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
package ani.dantotsu.profile.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import ani.dantotsu.connections.anilist.Anilist
|
||||
import ani.dantotsu.connections.anilist.api.Activity
|
||||
import ani.dantotsu.databinding.ActivityFollowBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ActivityActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityFollowBinding
|
||||
private var adapter: GroupieAdapter = GroupieAdapter()
|
||||
private var activityList: List<Activity> = emptyList()
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
initActivity(this)
|
||||
binding = ActivityFollowBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
binding.listTitle.text = "Activity"
|
||||
binding.listToolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> { topMargin = statusBarHeight }
|
||||
binding.listRecyclerView.adapter = adapter
|
||||
binding.listRecyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
||||
binding.followerGrid.visibility = ViewGroup.GONE
|
||||
binding.followerList.visibility = ViewGroup.GONE
|
||||
binding.listBack.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
binding.listProgressBar.visibility = ViewGroup.VISIBLE
|
||||
var userId: Int? = intent.getIntExtra("userId", -1)
|
||||
if (userId == -1) userId = null
|
||||
val global = intent.getBooleanExtra("global", false)
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,21 +6,29 @@ import android.view.View
|
|||
import androidx.core.content.ContextCompat
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.buildMarkwon
|
||||
import ani.dantotsu.connections.anilist.Anilist
|
||||
import ani.dantotsu.connections.anilist.api.Activity
|
||||
import ani.dantotsu.databinding.ItemActivityBinding
|
||||
import ani.dantotsu.loadImage
|
||||
import ani.dantotsu.snackString
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.xwray.groupie.viewbinding.BindableItem
|
||||
import jp.wasabeef.glide.transformations.BlurTransformation
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ActivityItem(
|
||||
private val activity: Activity,
|
||||
val clickCallback: (Int) -> Unit
|
||||
): BindableItem<ItemActivityBinding>() {
|
||||
val clickCallback: (Int, type: String) -> Unit
|
||||
) : BindableItem<ItemActivityBinding>() {
|
||||
private lateinit var binding: ItemActivityBinding
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun bind(viewBinding: ItemActivityBinding, position: Int) {
|
||||
binding = viewBinding
|
||||
|
@ -28,24 +36,48 @@ class ActivityItem(
|
|||
binding.activityUserName.text = activity.user?.name
|
||||
binding.activityUserAvatar.loadImage(activity.user?.avatar?.medium)
|
||||
binding.activityTime.text = ActivityItemBuilder.getDateTime(activity.createdAt)
|
||||
val color = if (activity.isLiked == true)
|
||||
ContextCompat.getColor(binding.root.context, R.color.yt_red)
|
||||
else
|
||||
ContextCompat.getColor(binding.root.context, R.color.bg_opp)
|
||||
binding.activityFavorite.setColorFilter(color)
|
||||
binding.commentRepliesContainer.visibility = if (activity.replyCount > 0) View.VISIBLE else View.GONE
|
||||
val likeColor = ContextCompat.getColor(binding.root.context, R.color.yt_red)
|
||||
val notLikeColor = ContextCompat.getColor(binding.root.context, R.color.bg_opp)
|
||||
binding.activityLike.setColorFilter(if (activity.isLiked == true) likeColor else notLikeColor)
|
||||
binding.commentRepliesContainer.visibility =
|
||||
if (activity.replyCount > 0) View.VISIBLE else View.GONE
|
||||
binding.activityLikeCount.text = activity.likeCount.toString()
|
||||
|
||||
binding.activityLike.setOnClickListener {
|
||||
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
scope.launch {
|
||||
val res = Anilist.query.toggleLike(activity.id, "ACTIVITY")
|
||||
withContext(Dispatchers.Main) {
|
||||
if (res != null) {
|
||||
|
||||
if (activity.isLiked == true) {
|
||||
activity.likeCount = activity.likeCount?.minus(1)
|
||||
} else {
|
||||
activity.likeCount = activity.likeCount?.plus(1)
|
||||
}
|
||||
binding.activityLikeCount.text = activity.likeCount.toString()
|
||||
activity.isLiked = !activity.isLiked!!
|
||||
binding.activityLike.setColorFilter(if (activity.isLiked == true) likeColor else notLikeColor)
|
||||
|
||||
} else {
|
||||
snackString("Failed to like activity")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val context = binding.root.context
|
||||
|
||||
when (activity.typename) {
|
||||
"ListActivity" ->{
|
||||
"ListActivity" -> {
|
||||
binding.activityContent.visibility = View.GONE
|
||||
binding.activityBannerContainer.visibility = View.VISIBLE
|
||||
|
||||
binding.activityMediaName.text = activity.media?.title?.userPreferred
|
||||
binding.activityText.text = "${activity.user!!.name} ${activity.status} ${activity.media!!.title!!.userPreferred}"
|
||||
binding.activityCover.loadImage(activity.media.coverImage?.medium)
|
||||
val banner = activity.media.bannerImage
|
||||
binding.activityText.text =
|
||||
"""${activity.user!!.name} ${activity.status} ${activity.progress ?: ""}"""
|
||||
binding.activityCover.loadImage(activity.media?.coverImage?.medium)
|
||||
val banner = activity.media?.bannerImage
|
||||
if (banner != null) {
|
||||
if (!(context as android.app.Activity).isDestroyed) {
|
||||
Glide.with(context as Context)
|
||||
|
@ -58,6 +90,7 @@ class ActivityItem(
|
|||
binding.activityBannerImage.setImageResource(R.drawable.linear_gradient_bg)
|
||||
}
|
||||
}
|
||||
|
||||
"TextActivity" -> {
|
||||
binding.activityBannerContainer.visibility = View.GONE
|
||||
binding.activityContent.visibility = View.VISIBLE
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package ani.dantotsu.profile.activity
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.ActivityFeedBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import nl.joery.animatedbottombar.AnimatedBottomBar
|
||||
|
||||
class FeedActivity: AppCompatActivity() {
|
||||
private lateinit var binding: ActivityFeedBinding
|
||||
private var selected: Int = 0
|
||||
private lateinit var navBar: AnimatedBottomBar
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
initActivity(this)
|
||||
binding = ActivityFeedBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
navBar = binding.feedNavBar
|
||||
navBar.updateLayoutParams<ViewGroup.MarginLayoutParams> { bottomMargin += navBarHeight }
|
||||
val personalTab = navBar.createTab(R.drawable.ic_round_person_24, "Personal")
|
||||
val globalTab = navBar.createTab(R.drawable.ic_globe_24, "Global")
|
||||
navBar.addTab(personalTab)
|
||||
navBar.addTab(globalTab)
|
||||
binding.listTitle.text = "Activities"
|
||||
binding.feedViewPager.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin += navBarHeight
|
||||
topMargin += statusBarHeight
|
||||
}
|
||||
binding.listToolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> { topMargin += statusBarHeight }
|
||||
binding.feedViewPager.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle)
|
||||
binding.feedViewPager.setCurrentItem(selected, false)
|
||||
binding.feedViewPager.isUserInputEnabled = false
|
||||
navBar.selectTabAt(selected)
|
||||
navBar.setOnTabSelectListener(object : AnimatedBottomBar.OnTabSelectListener {
|
||||
override fun onTabSelected(
|
||||
lastIndex: Int,
|
||||
lastTab: AnimatedBottomBar.Tab?,
|
||||
newIndex: Int,
|
||||
newTab: AnimatedBottomBar.Tab
|
||||
) {
|
||||
selected = newIndex
|
||||
binding.feedViewPager.setCurrentItem(selected, true)
|
||||
}
|
||||
})
|
||||
binding.listBack.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
navBar.selectTabAt(selected)
|
||||
}
|
||||
|
||||
|
||||
private class ViewPagerAdapter(
|
||||
fragmentManager: FragmentManager,
|
||||
lifecycle: Lifecycle
|
||||
) : FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||
override fun getItemCount(): Int = 2
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return when (position) {
|
||||
0 -> FeedFragment.newInstance(null, false)
|
||||
else -> FeedFragment.newInstance(null, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
111
app/src/main/java/ani/dantotsu/profile/activity/FeedFragment.kt
Normal file
111
app/src/main/java/ani/dantotsu/profile/activity/FeedFragment.kt
Normal file
|
@ -0,0 +1,111 @@
|
|||
package ani.dantotsu.profile.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import ani.dantotsu.connections.anilist.Anilist
|
||||
import ani.dantotsu.connections.anilist.AnilistQueries
|
||||
import ani.dantotsu.connections.anilist.api.Activity
|
||||
import ani.dantotsu.databinding.FragmentFeedBinding
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.profile.ProfileActivity
|
||||
import ani.dantotsu.snackString
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class FeedFragment : Fragment() {
|
||||
private lateinit var binding: FragmentFeedBinding
|
||||
private var adapter: GroupieAdapter = GroupieAdapter()
|
||||
private var activityList: List<Activity> = emptyList()
|
||||
private lateinit var activity: androidx.activity.ComponentActivity
|
||||
private var page: Int = 1
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = FragmentFeedBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
activity = requireActivity()
|
||||
binding.listRecyclerView.adapter = adapter
|
||||
binding.listRecyclerView.layoutManager =
|
||||
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
|
||||
binding.listProgressBar.visibility = ViewGroup.VISIBLE
|
||||
var userId: Int? = 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 = if (activity is ProfileActivity) {
|
||||
(activity as ProfileActivity).binding.profileScrollView
|
||||
} else {
|
||||
binding.listRecyclerView
|
||||
}
|
||||
binding.listRecyclerView.setOnTouchListener { _, event ->
|
||||
if (event?.action == MotionEvent.ACTION_UP) {
|
||||
if (adapter.itemCount % AnilistQueries.ITEMS_PER_PAGE != 0) {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (this::binding.isInitialized) {
|
||||
binding.root.requestLayout()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(userId: Int?, global: Boolean): FeedFragment {
|
||||
val fragment = FeedFragment()
|
||||
val args = Bundle()
|
||||
args.putInt("userId", userId ?: -1)
|
||||
args.putBoolean("global", global)
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,18 +3,23 @@ package ani.dantotsu.profile.activity
|
|||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import ani.dantotsu.connections.anilist.Anilist
|
||||
import ani.dantotsu.connections.anilist.AnilistQueries
|
||||
import ani.dantotsu.connections.anilist.api.Notification
|
||||
import ani.dantotsu.databinding.ActivityFollowBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.media.MediaDetailsActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.profile.ProfileActivity
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
|
@ -26,8 +31,9 @@ class NotificationActivity : AppCompatActivity() {
|
|||
private lateinit var binding: ActivityFollowBinding
|
||||
private var adapter: GroupieAdapter = GroupieAdapter()
|
||||
private var notificationList: List<Notification> = emptyList()
|
||||
private var page: Int = 1
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@SuppressLint("SetTextI18n", "ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
|
@ -36,6 +42,7 @@ class NotificationActivity : AppCompatActivity() {
|
|||
setContentView(binding.root)
|
||||
binding.listTitle.text = "Notifications"
|
||||
binding.listToolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> { topMargin = statusBarHeight }
|
||||
binding.listFrameLayout.updateLayoutParams<ViewGroup.MarginLayoutParams> { bottomMargin = navBarHeight }
|
||||
binding.listRecyclerView.adapter = adapter
|
||||
binding.listRecyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
||||
binding.followerGrid.visibility = ViewGroup.GONE
|
||||
|
@ -52,6 +59,30 @@ class NotificationActivity : AppCompatActivity() {
|
|||
}
|
||||
withContext(Dispatchers.Main){
|
||||
binding.listProgressBar.visibility = ViewGroup.GONE
|
||||
binding.listRecyclerView.setOnTouchListener { _, event ->
|
||||
if (event?.action == MotionEvent.ACTION_UP) {
|
||||
if (adapter.itemCount % AnilistQueries.ITEMS_PER_PAGE != 0) {
|
||||
snackString("No more notifications")
|
||||
} else if (!binding.listRecyclerView.canScrollVertically(1) && !binding.followRefresh.isVisible
|
||||
&& binding.listRecyclerView.adapter!!.itemCount != 0 &&
|
||||
(binding.listRecyclerView.layoutManager as LinearLayoutManager).findLastVisibleItemPosition() == (binding.listRecyclerView.adapter!!.itemCount - 1)
|
||||
) {
|
||||
page++
|
||||
binding.followRefresh.visibility = ViewGroup.VISIBLE
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val res = Anilist.query.getNotifications(Anilist.userid?:0, page)
|
||||
withContext(Dispatchers.Main) {
|
||||
res?.data?.page?.notifications?.let { notifications ->
|
||||
notificationList += notifications
|
||||
adapter.addAll(notifications.map { NotificationItem(it, ::onNotificationClick) })
|
||||
}
|
||||
binding.followRefresh.visibility = ViewGroup.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import ani.dantotsu.incognitoNotification
|
|||
import ani.dantotsu.loadImage
|
||||
import ani.dantotsu.profile.activity.NotificationActivity
|
||||
import ani.dantotsu.offline.OfflineFragment
|
||||
import ani.dantotsu.profile.activity.FeedActivity
|
||||
import ani.dantotsu.setSafeOnClickListener
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
|
@ -108,6 +109,11 @@ class SettingsDialogFragment : BottomSheetDialogFragment() {
|
|||
dismiss()
|
||||
}
|
||||
|
||||
binding.settingsActivity.setSafeOnClickListener {
|
||||
startActivity(Intent(activity, FeedActivity::class.java))
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.settingsNotification.setOnClickListener {
|
||||
startActivity(Intent(activity, NotificationActivity::class.java))
|
||||
dismiss()
|
||||
|
|
10
app/src/main/res/drawable/ic_globe_24.xml
Normal file
10
app/src/main/res/drawable/ic_globe_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,880q-82,0 -155,-31.5t-127.5,-86Q143,708 111.5,635T80,480q0,-83 31.5,-155.5t86,-127Q252,143 325,111.5T480,80q83,0 155.5,31.5t127,86q54.5,54.5 86,127T880,480q0,82 -31.5,155t-86,127.5q-54.5,54.5 -127,86T480,880ZM480,798q26,-36 45,-75t31,-83L404,640q12,44 31,83t45,75ZM376,782q-18,-33 -31.5,-68.5T322,640L204,640q29,50 72.5,87t99.5,55ZM584,782q56,-18 99.5,-55t72.5,-87L638,640q-9,38 -22.5,73.5T584,782ZM170,560h136q-3,-20 -4.5,-39.5T300,480q0,-21 1.5,-40.5T306,400L170,400q-5,20 -7.5,39.5T160,480q0,21 2.5,40.5T170,560ZM386,560h188q3,-20 4.5,-39.5T580,480q0,-21 -1.5,-40.5T574,400L386,400q-3,20 -4.5,39.5T380,480q0,21 1.5,40.5T386,560ZM654,560h136q5,-20 7.5,-39.5T800,480q0,-21 -2.5,-40.5T790,400L654,400q3,20 4.5,39.5T660,480q0,21 -1.5,40.5T654,560ZM638,320h118q-29,-50 -72.5,-87T584,178q18,33 31.5,68.5T638,320ZM404,320h152q-12,-44 -31,-83t-45,-75q-26,36 -45,75t-31,83ZM204,320h118q9,-38 22.5,-73.5T376,178q-56,18 -99.5,55T204,320Z"/>
|
||||
</vector>
|
|
@ -1,19 +1,13 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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="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" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/listToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal">
|
||||
|
@ -38,18 +32,38 @@
|
|||
android:fontFamily="@font/poppins_bold"
|
||||
android:gravity="center|start"
|
||||
android:singleLine="true"
|
||||
android:text="Activity"
|
||||
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"
|
||||
android:textColor="?attr/colorOnBackground"
|
||||
android:textSize="18sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
tools:text="Activities" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/listRecyclerView"
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/feedViewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
tools:listitem="@layout/item_activity" />
|
||||
</LinearLayout>
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="72dp"
|
||||
android:layout_marginTop="48dp"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
<nl.joery.animatedbottombar.AnimatedBottomBar
|
||||
android:id="@+id/feedNavBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="72dp"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
android:background="?attr/colorSurface"
|
||||
android:padding="0dp"
|
||||
app:abb_animationInterpolator="@anim/over_shoot"
|
||||
app:abb_indicatorAppearance="round"
|
||||
app:abb_indicatorLocation="top"
|
||||
app:abb_selectedTabType="text"
|
||||
app:abb_textAppearance="@style/NavBarText"
|
||||
app:itemActiveIndicatorStyle="@style/BottomNavBar"
|
||||
app:itemIconTint="@color/tab_layout_icon"
|
||||
app:itemRippleColor="#00000000"
|
||||
app:itemTextAppearanceActive="@style/NavBarText"
|
||||
app:itemTextAppearanceInactive="@style/NavBarText"
|
||||
app:itemTextColor="@color/tab_layout_icon" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -93,11 +93,26 @@
|
|||
|
||||
</FrameLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/listRecyclerView"
|
||||
<FrameLayout
|
||||
android:id="@+id/listFrameLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
tools:listitem="@layout/item_follower" />
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/listRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:nestedScrollingEnabled="true" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/followRefresh"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
|
@ -20,6 +20,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/profileScrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="72dp"
|
||||
|
@ -118,15 +119,6 @@
|
|||
android:layout_marginEnd="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/profileActivityButton"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:contentDescription="@string/menu"
|
||||
android:src="@drawable/inbox_empty"
|
||||
app:tint="@color/bg_opp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/profileMenuButton"
|
||||
android:layout_width="32dp"
|
||||
|
|
|
@ -1,6 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<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" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/listRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:nestedScrollingEnabled="true"
|
||||
android:visibility="visible"
|
||||
tools:listitem="@layout/item_activity" />
|
||||
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/feedRefresh"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -70,14 +70,14 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/activityFavorite"
|
||||
android:id="@+id/activityLike"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_round_favorite_24"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activityFavoriteCount"
|
||||
android:id="@+id/activityLikeCount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue