feat(social): like button fix

This commit is contained in:
aayush262 2024-04-26 19:57:55 +05:30
parent 856deb7755
commit da456d3067
19 changed files with 223 additions and 172 deletions

View file

@ -6,11 +6,13 @@ import ani.dantotsu.checkGenreTime
import ani.dantotsu.checkId import ani.dantotsu.checkId
import ani.dantotsu.connections.anilist.Anilist.authorRoles import ani.dantotsu.connections.anilist.Anilist.authorRoles
import ani.dantotsu.connections.anilist.Anilist.executeQuery import ani.dantotsu.connections.anilist.Anilist.executeQuery
import ani.dantotsu.connections.anilist.api.Activity
import ani.dantotsu.connections.anilist.api.FeedResponse import ani.dantotsu.connections.anilist.api.FeedResponse
import ani.dantotsu.connections.anilist.api.FuzzyDate import ani.dantotsu.connections.anilist.api.FuzzyDate
import ani.dantotsu.connections.anilist.api.NotificationResponse import ani.dantotsu.connections.anilist.api.NotificationResponse
import ani.dantotsu.connections.anilist.api.Page import ani.dantotsu.connections.anilist.api.Page
import ani.dantotsu.connections.anilist.api.Query import ani.dantotsu.connections.anilist.api.Query
import ani.dantotsu.connections.anilist.api.Social
import ani.dantotsu.connections.anilist.api.ToggleLike import ani.dantotsu.connections.anilist.api.ToggleLike
import ani.dantotsu.currContext import ani.dantotsu.currContext
import ani.dantotsu.isOnline import ani.dantotsu.isOnline
@ -33,6 +35,7 @@ import java.io.ByteArrayOutputStream
import java.io.ObjectInputStream import java.io.ObjectInputStream
import java.io.ObjectOutputStream import java.io.ObjectOutputStream
import java.io.Serializable import java.io.Serializable
import java.util.Calendar
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
class AnilistQueries { class AnilistQueries {
@ -507,7 +510,7 @@ class AnilistQueries {
suspend fun initHomePage(): Map<String, ArrayList<Media>> { suspend fun initHomePage(): Map<String, ArrayList<Media>> {
val toShow: List<Boolean> = val toShow: List<Boolean> =
PrefManager.getVal(PrefName.HomeLayoutShow) // anime continue, anime fav, anime planned, manga continue, manga fav, manga planned, recommendations PrefManager.getVal(PrefName.HomeLayout) // anime continue, anime fav, anime planned, manga continue, manga fav, manga planned, recommendations
var query = """{""" var query = """{"""
if (toShow.getOrNull(0) == true) query += """currentAnime: ${ if (toShow.getOrNull(0) == true) query += """currentAnime: ${
continueMediaQuery( continueMediaQuery(
@ -1637,12 +1640,43 @@ Page(page:$page,perPage:50) {
force = true force = true
) )
} }
private fun status(page: Int = 1): String {
return """Page(page:$page,perPage:50){activities(isFollowing: true, type:MEDIA_LIST,sort:ID_DESC){__typename ... on TextActivity{id userId type replyCount text(asHtml:true)siteUrl isLocked isSubscribed likeCount isLiked isPinned createdAt user{id name bannerImage avatar{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}... on ListActivity{id userId type replyCount status progress siteUrl isLocked isSubscribed likeCount isLiked isPinned createdAt user{id name bannerImage avatar{medium large}}media{id title{english romaji native userPreferred}bannerImage coverImage{extraLarge medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}... on MessageActivity{id recipientId messengerId type replyCount likeCount message(asHtml:true)isLocked isSubscribed isLiked isPrivate siteUrl createdAt recipient{id name bannerImage avatar{medium large}}messenger{id name bannerImage avatar{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}}}"""
}
suspend fun getStatus( suspend fun getStatus(
): FeedResponse? { ): MutableList<User> {
return executeQuery<FeedResponse>( fun query() = """{
"""{Page(page:1,perPage:50){activities(isFollowing: true, type:MEDIA_LIST,sort:ID_DESC){__typename ... on TextActivity{id userId type replyCount text(asHtml:true)siteUrl isLocked isSubscribed likeCount isLiked isPinned createdAt user{id name bannerImage avatar{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}... on ListActivity{id userId type replyCount status progress siteUrl isLocked isSubscribed likeCount isLiked isPinned createdAt user{id name bannerImage avatar{medium large}}media{id title{english romaji native userPreferred}bannerImage coverImage{extraLarge medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}... on MessageActivity{id recipientId messengerId type replyCount likeCount message(asHtml:true)isLocked isSubscribed isLiked isPrivate siteUrl createdAt recipient{id name bannerImage avatar{medium large}}messenger{id name bannerImage avatar{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}}}}""", Page1:${status(1)}
force = true Page2:${status(2)}
) }""".trimIndent()
val list = mutableListOf<User>()
val threeDaysAgo = Calendar.getInstance().apply {
add(Calendar.DAY_OF_MONTH, -10)
}.timeInMillis
executeQuery<Social>(query(), force = true)?.data?.let { data ->
val activities = listOf(data.page1.activities, data.page2.activities).flatten()
.filterNot { it.userId == Anilist.userid }
.sortedByDescending { it.createdAt }
.filter { it.createdAt < threeDaysAgo }
val groupedActivities = activities.groupBy { it.userId }
groupedActivities.forEach { (_, userActivities) ->
val user = userActivities.firstOrNull()?.user
if (user != null) {
list.add(
User(
user.id,
user.name ?: "",
user.avatar?.medium,
user.bannerImage,
activity = userActivities.toList()
)
)
}
}
}
return list
} }
suspend fun getUpcomingAnime(id: String): List<Media> { suspend fun getUpcomingAnime(id: String): List<Media> {
val res = executeQuery<Query.MediaListCollection>( val res = executeQuery<Query.MediaListCollection>(

View file

@ -108,28 +108,7 @@ class AnilistHomeViewModel : ViewModel() {
fun getUserStatus(): LiveData<ArrayList<User>> = userStatus fun getUserStatus(): LiveData<ArrayList<User>> = userStatus
suspend fun initUserStatus() { suspend fun initUserStatus() {
Anilist.query.getStatus()?.data?.page?.activities?.let { activities -> Anilist.query.getStatus().let { userStatus.postValue(ArrayList(it)) }
val groupedActivities = activities
.filterNot { it.userId == Anilist.userid }
.sortedByDescending { ActivityItemBuilder.getDateTime(it.createdAt) }
.groupBy { it.userId }
val userList = groupedActivities.mapNotNull { (_, activities) ->
val user = activities.firstOrNull()?.user
user?.let {
User(
it.id,
it.name ?: "",
it.avatar?.medium,
it.bannerImage,
activity = activities
)
}
}.toMutableList()
userList.sortByDescending { user ->
user.activity.maxByOrNull { it.createdAt }?.createdAt
}
userStatus.postValue(ArrayList(userList))
}
} }
suspend fun loadMain(context: FragmentActivity) { suspend fun loadMain(context: FragmentActivity) {

View file

@ -14,7 +14,17 @@ data class FeedResponse(
val page: ActivityPage val page: ActivityPage
) : java.io.Serializable ) : java.io.Serializable
} }
@Serializable
data class Social(
@SerialName("data")
val data: Data
) : java.io.Serializable {
@Serializable
data class Data(
@SerialName("Page1") val page1: ActivityPage,
@SerialName("Page2") val page2: ActivityPage
) : java.io.Serializable
}
@Serializable @Serializable
data class ActivityPage( data class ActivityPage(
@SerialName("activities") @SerialName("activities")

View file

@ -314,10 +314,9 @@ class HomeFragment : Fragment() {
binding.homeRecommendedEmpty, binding.homeRecommendedEmpty,
binding.homeRecommended binding.homeRecommended
) )
binding.homeUserStatusContainer.visibility = View.VISIBLE binding.homeUserStatusContainer.visibility = if (PrefManager.getVal<List<Boolean>>(PrefName.HomeLayout)[7]) View.VISIBLE else View.GONE
binding.homeUserStatusProgressBar.visibility = View.VISIBLE binding.homeUserStatusProgressBar.visibility = View.VISIBLE
binding.homeUserStatusRecyclerView.visibility = View.GONE binding.homeUserStatusRecyclerView.visibility = View.GONE
binding.homeUserStatus.visibility = View.INVISIBLE
model.getUserStatus().observe(viewLifecycleOwner) { model.getUserStatus().observe(viewLifecycleOwner) {
binding.homeUserStatusRecyclerView.visibility = View.GONE binding.homeUserStatusRecyclerView.visibility = View.GONE
if (it != null) { if (it != null) {
@ -335,12 +334,10 @@ class HomeFragment : Fragment() {
} else { } else {
binding.homeUserStatusContainer.visibility = View.GONE binding.homeUserStatusContainer.visibility = View.GONE
} }
binding.homeUserStatus.visibility = View.VISIBLE
binding.homeUserStatus.startAnimation(setSlideUp())
binding.homeUserStatusProgressBar.visibility = View.GONE binding.homeUserStatusProgressBar.visibility = View.GONE
} }
}
}
binding.homeUserAvatarContainer.startAnimation(setSlideUp()) binding.homeUserAvatarContainer.startAnimation(setSlideUp())
model.empty.observe(viewLifecycleOwner) model.empty.observe(viewLifecycleOwner)
@ -371,7 +368,7 @@ class HomeFragment : Fragment() {
binding.homeContinueReadingContainer, binding.homeContinueReadingContainer,
binding.homeFavMangaContainer, binding.homeFavMangaContainer,
binding.homePlannedMangaContainer, binding.homePlannedMangaContainer,
binding.homeRecommendedContainer binding.homeRecommendedContainer,
) )
val live = Refresh.activity.getOrPut(1) { MutableLiveData(false) } val live = Refresh.activity.getOrPut(1) { MutableLiveData(false) }
@ -388,9 +385,9 @@ class HomeFragment : Fragment() {
model.setListImages() model.setListImages()
var empty = true var empty = true
val homeLayoutShow: List<Boolean> = val homeLayoutShow: List<Boolean> =
PrefManager.getVal(PrefName.HomeLayoutShow) PrefManager.getVal(PrefName.HomeLayout)
runBlocking { runBlocking {
model.initUserStatus() if (homeLayoutShow.getOrNull(7) == true) model.initUserStatus()
model.initHomePage() model.initHomePage()
} }
(array.indices).forEach { i -> (array.indices).forEach { i ->

View file

@ -2,51 +2,46 @@ package ani.dantotsu.home
import android.os.Bundle import android.os.Bundle
import android.view.ViewGroup import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import ani.dantotsu.connections.anilist.api.Activity import ani.dantotsu.R
import ani.dantotsu.databinding.ActivityStatusBinding import ani.dantotsu.databinding.ActivityStatusBinding
import ani.dantotsu.initActivity import ani.dantotsu.initActivity
import ani.dantotsu.others.getSerialized import ani.dantotsu.others.getSerialized
import ani.dantotsu.themes.ThemeManager import ani.dantotsu.themes.ThemeManager
import ani.dantotsu.home.status.data.StoryItem
import ani.dantotsu.home.status.listener.StoriesCallback import ani.dantotsu.home.status.listener.StoriesCallback
import ani.dantotsu.navBarHeight import ani.dantotsu.navBarHeight
import ani.dantotsu.profile.activity.ActivityItemBuilder import ani.dantotsu.profile.User
import ani.dantotsu.statusBarHeight import ani.dantotsu.statusBarHeight
class StatusActivity : AppCompatActivity(), StoriesCallback { class StatusActivity : AppCompatActivity(), StoriesCallback {
private lateinit var activity: List<Activity> private lateinit var activity: ArrayList<User>
private lateinit var binding: ActivityStatusBinding private lateinit var binding: ActivityStatusBinding
private var position: Int = -1
private lateinit var slideInLeft: Animation
private lateinit var slideOutRight: Animation
private lateinit var slideOutLeft: Animation
private lateinit var slideInRight: Animation
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
ThemeManager(this).applyTheme() ThemeManager(this).applyTheme()
initActivity(this) initActivity(this)
binding = ActivityStatusBinding.inflate(layoutInflater) binding = ActivityStatusBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
activity = intent.getSerialized("activity")!! activity = intent.getSerialized("user")!!
position = intent.getIntExtra("position", -1)
binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams> { binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = statusBarHeight topMargin = statusBarHeight
bottomMargin = navBarHeight bottomMargin = navBarHeight
} }
val storiesList = activity.map { StoryItem( slideInLeft = AnimationUtils.loadAnimation(this, R.anim.slide_in_left)
id = it.userId, slideOutRight = AnimationUtils.loadAnimation(this, R.anim.slide_out_right)
activityId = it.id, slideOutLeft = AnimationUtils.loadAnimation(this, R.anim.slide_out_left)
mediaId = it.media?.id, slideInRight = AnimationUtils.loadAnimation(this, R.anim.slide_in_right)
userName = it.user?.name,
userAvatar = it.user?.avatar?.large, binding.stories.setStoriesList(activity[position].activity, this)
time = ActivityItemBuilder.getDateTime(it.createdAt),
info = "${it.user!!.name} ${it.status} ${
it.progress
?: it.media?.title?.userPreferred
}",
cover = it.media?.coverImage?.extraLarge,
banner = it.media?.bannerImage ?: it.media?.coverImage?.extraLarge,
likes = it.likeCount ?: 0,
likedBy = it.likes,
isLiked = it.isLiked == true
) }
binding.stories.setStoriesList(storiesList, this)
} }
override fun onPause() { override fun onPause() {
@ -67,7 +62,25 @@ class StatusActivity : AppCompatActivity(), StoriesCallback {
} }
} }
override fun onStoriesEnd() { override fun onStoriesEnd() {
finish() position += 1
if (position < activity.size - 1) {
binding.stories.startAnimation(slideOutLeft)
binding.stories.setStoriesList(activity[position].activity, this)
binding.stories.startAnimation(slideInRight)
} else {
finish()
}
}
override fun onStoriesStart() {
position -= 1
if (position >= 0) {
binding.stories.startAnimation(slideOutRight)
binding.stories.setStoriesList(activity[position].activity, this)
binding.stories.startAnimation(slideInLeft)
} else {
finish()
}
} }
} }

View file

@ -23,7 +23,8 @@ class UserStatus(private val user: ArrayList<User>) :
Intent( Intent(
itemView.context, itemView.context,
StatusActivity::class.java StatusActivity::class.java
).putExtra("activity", user[bindingAdapterPosition].activity as Serializable), ).putExtra("user", user as Serializable)
.putExtra("position", bindingAdapterPosition),
null null
) )
} }

View file

@ -3,10 +3,8 @@ package ani.dantotsu.home.status
import android.animation.Animator import android.animation.Animator
import android.animation.ObjectAnimator import android.animation.ObjectAnimator
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Rect
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MotionEvent import android.view.MotionEvent
@ -21,17 +19,17 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.webkit.internal.ApiFeature.T
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.blurImage import ani.dantotsu.blurImage
import ani.dantotsu.connections.anilist.Anilist import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.home.status.data.StoryItem import ani.dantotsu.connections.anilist.api.Activity
import ani.dantotsu.home.status.listener.StoriesCallback import ani.dantotsu.home.status.listener.StoriesCallback
import ani.dantotsu.loadImage import ani.dantotsu.loadImage
import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.profile.ProfileActivity import ani.dantotsu.profile.ProfileActivity
import ani.dantotsu.profile.User import ani.dantotsu.profile.User
import ani.dantotsu.profile.UsersDialogFragment import ani.dantotsu.profile.UsersDialogFragment
import ani.dantotsu.profile.activity.ActivityItemBuilder
import ani.dantotsu.snackString import ani.dantotsu.snackString
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -39,14 +37,14 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.util.Calendar import java.util.Calendar
import java.util.Locale
class Stories @JvmOverloads class Stories @JvmOverloads
constructor( constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), View.OnTouchListener { ) : ConstraintLayout(context, attrs, defStyleAttr), View.OnTouchListener {
private lateinit var activityList: List<Activity>
private lateinit var storiesList: List<StoryItem>
private lateinit var activ: FragmentActivity private lateinit var activ: FragmentActivity
private lateinit var loadingViewLayout: ConstraintLayout private lateinit var loadingViewLayout: ConstraintLayout
private lateinit var leftTouchPanel: FrameLayout private lateinit var leftTouchPanel: FrameLayout
@ -56,6 +54,7 @@ constructor(
private lateinit var loadingView: ProgressBar private lateinit var loadingView: ProgressBar
private lateinit var activityLikeCount: TextView private lateinit var activityLikeCount: TextView
private lateinit var activityLike: ImageView private lateinit var activityLike: ImageView
private lateinit var activityLikeContainer: LinearLayout
private lateinit var userName: TextView private lateinit var userName: TextView
private lateinit var userAvatar: ImageView private lateinit var userAvatar: ImageView
private lateinit var time: TextView private lateinit var time: TextView
@ -66,14 +65,12 @@ constructor(
private var storyIndex: Int = 1 private var storyIndex: Int = 1
private var userClicked: Boolean = false private var userClicked: Boolean = false
private lateinit var storiesListener: StoriesCallback private lateinit var storiesListener: StoriesCallback
private var oldStoryItem = StoryItem()
init { init {
initLayout() initLayout()
} }
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
private fun initLayout() { fun initLayout() {
val inflater: LayoutInflater = LayoutInflater.from(context) val inflater: LayoutInflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.fragment_status, this, false) val view = inflater.inflate(R.layout.fragment_status, this, false)
addView(view) addView(view)
@ -95,6 +92,7 @@ constructor(
infoText = findViewById(R.id.infoText) infoText = findViewById(R.id.infoText)
activityLikeCount = findViewById(R.id.activityLikeCount) activityLikeCount = findViewById(R.id.activityLikeCount)
activityLike = findViewById(R.id.activityLike) activityLike = findViewById(R.id.activityLike)
activityLikeContainer = findViewById(R.id.statusUserActions)
leftTouchPanel.setOnTouchListener(this) leftTouchPanel.setOnTouchListener(this)
rightTouchPanel.setOnTouchListener(this) rightTouchPanel.setOnTouchListener(this)
@ -102,15 +100,16 @@ constructor(
} }
fun setStoriesList(storiesList: List<StoryItem>, activity: FragmentActivity) { fun setStoriesList(activityList: List<Activity>, activity: FragmentActivity) {
this.storiesList = storiesList this.activityList = activityList
this.activ = activity this.activ = activity
addLoadingViews(storiesList) addLoadingViews(activityList)
} }
private fun addLoadingViews(storiesList: List<StoryItem>) { private fun addLoadingViews(storiesList: List<Activity>) {
var idCounter = 1 var idCounter = 1
for (story in storiesList) { for (story in storiesList) {
loadingViewLayout.removeView(findViewWithTag<ProgressBar>("story${idCounter}"))
val progressBar = ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal) val progressBar = ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal)
progressBar.visibility = View.VISIBLE progressBar.visibility = View.VISIBLE
progressBar.id = idCounter progressBar.id = idCounter
@ -231,15 +230,14 @@ constructor(
animation.duration = secondsToMillis(storyDuration) animation.duration = secondsToMillis(storyDuration)
animation.interpolator = LinearInterpolator() animation.interpolator = LinearInterpolator()
animation.addListener(object : Animator.AnimatorListener { animation.addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animator: Animator) { override fun onAnimationStart(animator: Animator) {}
}
override fun onAnimationEnd(animator: Animator) { override fun onAnimationEnd(animator: Animator) {
if (storyIndex - 1 <= storiesList.size) { if (storyIndex - 1 <= activityList.size) {
if (userClicked) { if (userClicked) {
userClicked = false userClicked = false
} else { } else {
if (storyIndex < storiesList.size) { if (storyIndex < activityList.size) {
storyIndex += 1 storyIndex += 1
showStory() showStory()
} else { } else {
@ -261,7 +259,7 @@ constructor(
override fun onAnimationRepeat(animator: Animator) {} override fun onAnimationRepeat(animator: Animator) {}
}) })
loadStory(storiesList[storyIndex - 1]) loadStory(activityList[storyIndex - 1])
} }
private fun getId(tag: String): Int { private fun getId(tag: String): Int {
@ -321,19 +319,23 @@ constructor(
} }
private fun rightPanelTouch() { private fun rightPanelTouch() {
if (storyIndex == storiesList.size) { if (storyIndex == activityList.size) {
completeProgressBar(storyIndex) completeProgressBar(storyIndex)
onStoriesCompleted() onStoriesCompleted()
return return
} }
userClicked = true userClicked = true
animation.end() animation.end()
if (storyIndex < storiesList.size) if (storyIndex < activityList.size)
storyIndex += 1 storyIndex += 1
showStory() showStory()
} }
private fun leftPanelTouch() { private fun leftPanelTouch() {
if (storyIndex == 1) {
onStoriesPrevious()
return
}
userClicked = true userClicked = true
animation.end() animation.end()
resetProgressBar(storyIndex) resetProgressBar(storyIndex)
@ -343,8 +345,19 @@ constructor(
} }
private fun onStoriesCompleted() { private fun onStoriesCompleted() {
if (::storiesListener.isInitialized) if (::storiesListener.isInitialized){
storyIndex = 1
storiesListener.onStoriesEnd() storiesListener.onStoriesEnd()
resetProgressBar(storyIndex)
}
}
private fun onStoriesPrevious() {
if (::storiesListener.isInitialized) {
storyIndex = 1
storiesListener.onStoriesStart()
resetProgressBar(storyIndex)
}
} }
fun pause() { fun pause() {
animation.pause() animation.pause()
@ -352,40 +365,54 @@ constructor(
fun resume() { fun resume() {
animation.resume() animation.resume()
} }
private fun loadStory(story: StoryItem) { private fun loadStory(story: Activity) {
loadingView.visibility = View.GONE loadingView.visibility = View.GONE
animation.start() animation.start()
blurImage(imageContentView, story.banner) blurImage(imageContentView, story.media?.bannerImage ?: story.media?.coverImage?.extraLarge)
userAvatar.loadImage(story.userAvatar) userAvatar.loadImage(story.user?.avatar?.large)
coverImage.loadImage(story.cover) coverImage.loadImage(story.media?.coverImage?.extraLarge)
userName.text = story.userName userName.text = story.user?.name
time.text = story.time time.text = ActivityItemBuilder.getDateTime(story.createdAt)
infoText.text = story.info val text = "${story.status?.replaceFirstChar {
if (it.isLowerCase()) {
it.titlecase(Locale.ROOT)
}
else {
it.toString()
}
}} ${story.progress ?: story.media?.title?.userPreferred}"
infoText.text = text
statusUserContainer.setOnClickListener { statusUserContainer.setOnClickListener {
ContextCompat.startActivity(context, Intent(context, ProfileActivity::class.java).putExtra("userId", story.id), null) ContextCompat.startActivity(context, Intent(context, ProfileActivity::class.java)
.putExtra("userId", story.userId),
null)
} }
coverImage.setOnClickListener{ coverImage.setOnClickListener{
ContextCompat.startActivity(context, Intent(context, MediaDetailsActivity::class.java).putExtra("mediaId", story.mediaId), null) ContextCompat.startActivity(context, Intent(context, MediaDetailsActivity::class.java)
.putExtra("mediaId", story.media?.id),
null)
} }
val likeColor = ContextCompat.getColor(context, R.color.yt_red) val likeColor = ContextCompat.getColor(context, R.color.yt_red)
val notLikeColor = ContextCompat.getColor(context, R.color.bg_opp) val notLikeColor = ContextCompat.getColor(context, R.color.bg_opp)
activityLikeCount.text = story.likes.toString() activityLikeCount.text = story.likeCount.toString()
activityLike.setColorFilter(if (story.isLiked) likeColor else notLikeColor) activityLike.setColorFilter(if (story.isLiked == true) likeColor else notLikeColor)
activityLike.setOnClickListener { activityLikeContainer.setOnClickListener {
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
scope.launch { scope.launch {
val res = Anilist.query.toggleLike(story.activityId!!, "ACTIVITY") val res = Anilist.query.toggleLike(story.id, "ACTIVITY")
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
if (res != null) { if (res != null) {
if (story.isLiked == true) {
if (story.isLiked) { story.likeCount = story.likeCount?.minus(1)
story.likes = story.likes.minus(1)
} else { } else {
story.likes = story.likes.plus(1) story.likeCount = story.likeCount?.plus(1)
} }
activityLikeCount.text = (story.likes ?: 0).toString() activityLikeCount.text = (story.likeCount ?: 0).toString()
story.isLiked = !story.isLiked story.isLiked = !story.isLiked!!
activityLike.setColorFilter(if (story.isLiked) likeColor else notLikeColor) activityLike.setColorFilter(if (story.isLiked == true) likeColor else notLikeColor)
} else { } else {
snackString("Failed to like activity") snackString("Failed to like activity")
@ -393,21 +420,17 @@ constructor(
} }
} }
} }
val userList = arrayListOf<User>() val userList = arrayListOf<User>()
story.likedBy?.forEach { i -> story.likes?.forEach { i ->
userList.add(User(i.id, i.name.toString(), i.avatar?.medium, i.bannerImage)) userList.add(User(i.id, i.name.toString(), i.avatar?.medium, i.bannerImage))
} }
activityLikeContainer.setOnLongClickListener {
activityLike.setOnLongClickListener {
UsersDialogFragment().apply { UsersDialogFragment().apply {
userList(userList) userList(userList)
show(activ.supportFragmentManager, "dialog") show(activ.supportFragmentManager, "dialog")
} }
true true
} }
oldStoryItem = story
} }
} }

View file

@ -1,20 +0,0 @@
package ani.dantotsu.home.status.data
import ani.dantotsu.connections.anilist.api.User
data class StoryItem(
val id : Int? = null,
val activityId : Int? = null,
val mediaId: Int? = null,
val userName: String? = null,
val userAvatar: String? = null,
val time: String? = null,
val info: String? = null,
val cover: String? = null,
val banner: String? = null,
var likes : Int = 0,
val likedBy: List<User>? = null,
var isLiked : Boolean = false
)

View file

@ -3,4 +3,5 @@ package ani.dantotsu.home.status.listener
interface StoriesCallback { interface StoriesCallback {
fun onStoriesEnd() fun onStoriesEnd()
fun onStoriesStart()
} }

View file

@ -36,18 +36,18 @@ class UserInterfaceSettingsActivity : AppCompatActivity() {
} }
binding.uiSettingsHomeLayout.setOnClickListener { binding.uiSettingsHomeLayout.setOnClickListener {
val set = PrefManager.getVal<List<Boolean>>(PrefName.HomeLayoutShow).toMutableList() val set = PrefManager.getVal<List<Boolean>>(PrefName.HomeLayout).toMutableList()
val views = resources.getStringArray(R.array.home_layouts) val views = resources.getStringArray(R.array.home_layouts)
val dialog = AlertDialog.Builder(this, R.style.MyPopup) val dialog = AlertDialog.Builder(this, R.style.MyPopup)
.setTitle(getString(R.string.home_layout_show)).apply { .setTitle(getString(R.string.home_layout_show)).apply {
setMultiChoiceItems( setMultiChoiceItems(
views, views,
PrefManager.getVal<List<Boolean>>(PrefName.HomeLayoutShow).toBooleanArray() PrefManager.getVal<List<Boolean>>(PrefName.HomeLayout).toBooleanArray()
) { _, i, value -> ) { _, i, value ->
set[i] = value set[i] = value
} }
setPositiveButton("Done") { _, _ -> setPositiveButton("Done") { _, _ ->
PrefManager.setVal(PrefName.HomeLayoutShow, set) PrefManager.setVal(PrefName.HomeLayout, set)
restartApp() restartApp()
} }
}.show() }.show()

View file

@ -63,11 +63,11 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
ImmersiveMode(Pref(Location.UI, Boolean::class, false)), ImmersiveMode(Pref(Location.UI, Boolean::class, false)),
SmallView(Pref(Location.UI, Boolean::class, true)), SmallView(Pref(Location.UI, Boolean::class, true)),
DefaultStartUpTab(Pref(Location.UI, Int::class, 1)), DefaultStartUpTab(Pref(Location.UI, Int::class, 1)),
HomeLayoutShow( HomeLayout(
Pref( Pref(
Location.UI, Location.UI,
List::class, List::class,
listOf(true, false, false, true, false, false, true) listOf(true, false, false, true, false, false, true, true)
) )
), ),
BannerAnimations(Pref(Location.UI, Boolean::class, true)), BannerAnimations(Pref(Location.UI, Boolean::class, true)),

View file

@ -0,0 +1,6 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="-100%"
android:toXDelta="0%" />
</set>

View file

@ -0,0 +1,6 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="100%"
android:toXDelta="0%" />
</set>

View file

@ -0,0 +1,6 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0%"
android:toXDelta="-100%" />
</set>

View file

@ -0,0 +1,6 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0%"
android:toXDelta="100%" />
</set>

View file

@ -309,50 +309,34 @@
</LinearLayout> </LinearLayout>
</FrameLayout> </FrameLayout>
<LinearLayout
<FrameLayout
android:id="@+id/homeUserStatusContainer" android:id="@+id/homeUserStatusContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="vertical" android:minHeight="100dp">
android:visibility="gone">
<TextView <ProgressBar
android:id="@+id/homeUserStatus" android:id="@+id/homeUserStatusProgressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp" android:layout_gravity="center" />
android:fontFamily="@font/poppins_bold"
android:padding="8dp"
android:text="@string/social"
android:textSize="16sp" />
<FrameLayout <ani.dantotsu.FadingEdgeRecyclerView
android:id="@+id/homeUserStatusRecyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="100dp"> android:clipToPadding="false"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:requiresFadingEdge="horizontal"
tools:itemCount="4"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_user_status"
tools:orientation="horizontal" />
</FrameLayout>
<ProgressBar
android:id="@+id/homeUserStatusProgressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="90dp" />
<ani.dantotsu.FadingEdgeRecyclerView
android:id="@+id/homeUserStatusRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:requiresFadingEdge="horizontal"
tools:itemCount="4"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_user_status"
tools:orientation="horizontal" />
</FrameLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/homeContinueWatchingContainer" android:id="@+id/homeContinueWatchingContainer"
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -112,10 +112,12 @@
tools:ignore="HardcodedText,RtlSymmetry" /> tools:ignore="HardcodedText,RtlSymmetry" />
<LinearLayout <LinearLayout
android:id="@+id/statusUserActions"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:orientation="vertical" android:orientation="vertical"
android:paddingHorizontal="24dp"
tools:ignore="UseCompoundDrawables"> tools:ignore="UseCompoundDrawables">
<ImageView <ImageView

View file

@ -12,7 +12,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:backgroundTint="@color/bg_white" android:backgroundTint="@color/transparent"
app:strokeColor="@color/transparent"
app:cardCornerRadius="124dp"> app:cardCornerRadius="124dp">
<ImageView <ImageView
@ -28,10 +29,11 @@
android:id="@+id/profileUserName" android:id="@+id/profileUserName"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="@font/poppins_semi_bold"
android:layout_gravity="center_horizontal|center_vertical" android:layout_gravity="center_horizontal|center_vertical"
android:ellipsize="end" android:ellipsize="end"
android:text="@string/username" android:text="@string/username"
android:textColor="?attr/colorOnBackground" android:textColor="?attr/colorOnBackground"
android:textSize="14sp" /> android:textSize="12sp" />
</LinearLayout> </LinearLayout>

View file

@ -305,6 +305,7 @@
<item>Favourite Manga</item> <item>Favourite Manga</item>
<item>Planned Manga</item> <item>Planned Manga</item>
<item>Recommended</item> <item>Recommended</item>
<item>Social Feeds</item>
</string-array> </string-array>
<string name="startUpTab">Default Start Up Tab</string> <string name="startUpTab">Default Start Up Tab</string>