feat(social): continue from where you left
This commit is contained in:
parent
73ef5f4bbc
commit
133354a22d
8 changed files with 70 additions and 38 deletions
|
@ -140,7 +140,7 @@
|
||||||
android:name=".settings.SettingsAboutActivity"
|
android:name=".settings.SettingsAboutActivity"
|
||||||
android:parentActivityName=".MainActivity" />
|
android:parentActivityName=".MainActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".home.StatusActivity"
|
android:name=".home.status.StatusActivity"
|
||||||
android:parentActivityName=".MainActivity" />
|
android:parentActivityName=".MainActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".settings.SettingsAccountActivity"
|
android:name=".settings.SettingsAccountActivity"
|
||||||
|
|
|
@ -1655,26 +1655,33 @@ Page(page:$page,perPage:50) {
|
||||||
}.timeInMillis
|
}.timeInMillis
|
||||||
executeQuery<Social>(query(), force = true)?.data?.let { data ->
|
executeQuery<Social>(query(), force = true)?.data?.let { data ->
|
||||||
val activities = listOf(data.page1.activities, data.page2.activities).flatten()
|
val activities = listOf(data.page1.activities, data.page2.activities).flatten()
|
||||||
.filterNot { it.userId == Anilist.userid }
|
|
||||||
.sortedByDescending { it.createdAt }
|
.sortedByDescending { it.createdAt }
|
||||||
.filter { it.createdAt < threeDaysAgo }
|
.filter { it.createdAt < threeDaysAgo }
|
||||||
|
|
||||||
|
val anilistActivities = mutableListOf<User>()
|
||||||
val groupedActivities = activities.groupBy { it.userId }
|
val groupedActivities = activities.groupBy { it.userId }
|
||||||
|
|
||||||
groupedActivities.forEach { (_, userActivities) ->
|
groupedActivities.forEach { (_, userActivities) ->
|
||||||
val user = userActivities.firstOrNull()?.user
|
val user = userActivities.firstOrNull()?.user
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
list.add(
|
val userToAdd = User(
|
||||||
User(
|
user.id,
|
||||||
user.id,
|
user.name ?: "",
|
||||||
user.name ?: "",
|
user.avatar?.medium,
|
||||||
user.avatar?.medium,
|
user.bannerImage,
|
||||||
user.bannerImage,
|
activity = userActivities.toList()
|
||||||
activity = userActivities.toList()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
if (user.id == Anilist.userid) {
|
||||||
|
anilistActivities.add(0, userToAdd)
|
||||||
|
} else {
|
||||||
|
list.add(userToAdd)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
list.addAll(0, anilistActivities)
|
||||||
}
|
}
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import ani.dantotsu.connections.anilist.AnilistHomeViewModel
|
||||||
import ani.dantotsu.connections.anilist.getUserId
|
import ani.dantotsu.connections.anilist.getUserId
|
||||||
import ani.dantotsu.currContext
|
import ani.dantotsu.currContext
|
||||||
import ani.dantotsu.databinding.FragmentHomeBinding
|
import ani.dantotsu.databinding.FragmentHomeBinding
|
||||||
|
import ani.dantotsu.home.status.UserStatusAdapter
|
||||||
import ani.dantotsu.loadImage
|
import ani.dantotsu.loadImage
|
||||||
import ani.dantotsu.media.Media
|
import ani.dantotsu.media.Media
|
||||||
import ani.dantotsu.media.MediaAdaptor
|
import ani.dantotsu.media.MediaAdaptor
|
||||||
|
@ -321,7 +322,7 @@ class HomeFragment : Fragment() {
|
||||||
binding.homeUserStatusRecyclerView.visibility = View.GONE
|
binding.homeUserStatusRecyclerView.visibility = View.GONE
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
if (it.isNotEmpty()) {
|
if (it.isNotEmpty()) {
|
||||||
binding.homeUserStatusRecyclerView.adapter = UserStatus(it)
|
binding.homeUserStatusRecyclerView.adapter = UserStatusAdapter(it)
|
||||||
binding.homeUserStatusRecyclerView.layoutManager = LinearLayoutManager(
|
binding.homeUserStatusRecyclerView.layoutManager = LinearLayoutManager(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
LinearLayoutManager.HORIZONTAL,
|
LinearLayoutManager.HORIZONTAL,
|
||||||
|
|
|
@ -14,6 +14,7 @@ class CircleView(context: Context, attrs: AttributeSet?) : View(context, attrs)
|
||||||
private var parts: Int = 3
|
private var parts: Int = 3
|
||||||
private var gapAngle: Float = 9f
|
private var gapAngle: Float = 9f
|
||||||
private val path = Path()
|
private val path = Path()
|
||||||
|
private var isUser = false
|
||||||
private var booleanList = listOf<Boolean>()
|
private var booleanList = listOf<Boolean>()
|
||||||
private val paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
private val paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||||
style = Paint.Style.STROKE
|
style = Paint.Style.STROKE
|
||||||
|
@ -32,13 +33,14 @@ class CircleView(context: Context, attrs: AttributeSet?) : View(context, attrs)
|
||||||
val typedValue = TypedValue()
|
val typedValue = TypedValue()
|
||||||
context.theme.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValue, true)
|
context.theme.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValue, true)
|
||||||
val primaryColor = typedValue.data
|
val primaryColor = typedValue.data
|
||||||
|
val typedValue1 = TypedValue()
|
||||||
|
context.theme.resolveAttribute(com.google.android.material.R.attr.colorOnPrimary, typedValue1, true)
|
||||||
|
val secondColor = typedValue1.data
|
||||||
fun setColor(int: Int) {
|
fun setColor(int: Int) {
|
||||||
if (int < booleanList.size && booleanList[int]) {
|
paint.color = if (int < booleanList.size && booleanList[int]) {
|
||||||
|
if (isUser) secondColor else Color.GRAY
|
||||||
paint.color = Color.GRAY
|
|
||||||
} else {
|
} else {
|
||||||
|
if (isUser) secondColor else primaryColor
|
||||||
paint.color = primaryColor
|
|
||||||
}
|
}
|
||||||
canvas.drawPath(path, paint)
|
canvas.drawPath(path, paint)
|
||||||
}
|
}
|
||||||
|
@ -74,9 +76,10 @@ class CircleView(context: Context, attrs: AttributeSet?) : View(context, attrs)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setParts(parts: Int, list : List<Boolean> = mutableListOf()) {
|
fun setParts(parts: Int, list : List<Boolean> = mutableListOf(), isUser: Boolean) {
|
||||||
this.parts = parts
|
this.parts = parts
|
||||||
this.booleanList = list
|
this.booleanList = list
|
||||||
|
this.isUser = isUser
|
||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package ani.dantotsu.home
|
package ani.dantotsu.home.status
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
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.Animation
|
||||||
|
@ -8,12 +7,11 @@ 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.R
|
import ani.dantotsu.R
|
||||||
|
import ani.dantotsu.connections.anilist.api.Activity
|
||||||
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.themes.ThemeManager
|
import ani.dantotsu.themes.ThemeManager
|
||||||
import ani.dantotsu.home.status.listener.StoriesCallback
|
import ani.dantotsu.home.status.listener.StoriesCallback
|
||||||
import ani.dantotsu.media.Media
|
|
||||||
import ani.dantotsu.navBarHeight
|
import ani.dantotsu.navBarHeight
|
||||||
import ani.dantotsu.profile.User
|
import ani.dantotsu.profile.User
|
||||||
import ani.dantotsu.settings.saving.PrefManager
|
import ani.dantotsu.settings.saving.PrefManager
|
||||||
|
@ -44,10 +42,21 @@ class StatusActivity : AppCompatActivity(), StoriesCallback {
|
||||||
slideOutLeft = AnimationUtils.loadAnimation(this, R.anim.slide_out_left)
|
slideOutLeft = AnimationUtils.loadAnimation(this, R.anim.slide_out_left)
|
||||||
slideInRight = AnimationUtils.loadAnimation(this, R.anim.slide_in_right)
|
slideInRight = AnimationUtils.loadAnimation(this, R.anim.slide_in_right)
|
||||||
|
|
||||||
binding.stories.setStoriesList(activity[position].activity, this)
|
val watchedActivity = PrefManager.getCustomVal<Set<Int>>("${activity[position].id}_activities", setOf())
|
||||||
|
val startFrom = findFirstNonMatch(watchedActivity, activity[position].activity )
|
||||||
|
val startIndex = if ( startFrom > 0) startFrom else 0
|
||||||
|
binding.stories.setStoriesList(activity[position].activity, this, startIndex + 1)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
private fun findFirstNonMatch(watchedActivity: Set<Int>, activity: List<Activity>): Int {
|
||||||
|
for (activityItem in activity) {
|
||||||
|
if (activityItem.id !in watchedActivity) {
|
||||||
|
return activity.indexOf(activityItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
binding.stories.pause()
|
binding.stories.pause()
|
||||||
|
@ -68,8 +77,11 @@ class StatusActivity : AppCompatActivity(), StoriesCallback {
|
||||||
override fun onStoriesEnd() {
|
override fun onStoriesEnd() {
|
||||||
position += 1
|
position += 1
|
||||||
if (position < activity.size - 1) {
|
if (position < activity.size - 1) {
|
||||||
|
val watchedActivity = PrefManager.getCustomVal<Set<Int>>("${activity[position].id}_activities", setOf())
|
||||||
|
val startFrom = findFirstNonMatch(watchedActivity, activity[position].activity )
|
||||||
|
val startIndex= if ( startFrom > 0) startFrom else 0
|
||||||
binding.stories.startAnimation(slideOutLeft)
|
binding.stories.startAnimation(slideOutLeft)
|
||||||
binding.stories.setStoriesList(activity[position].activity, this)
|
binding.stories.setStoriesList(activity[position].activity, this, startIndex + 1)
|
||||||
binding.stories.startAnimation(slideInRight)
|
binding.stories.startAnimation(slideInRight)
|
||||||
} else {
|
} else {
|
||||||
finish()
|
finish()
|
||||||
|
@ -79,8 +91,11 @@ class StatusActivity : AppCompatActivity(), StoriesCallback {
|
||||||
override fun onStoriesStart() {
|
override fun onStoriesStart() {
|
||||||
position -= 1
|
position -= 1
|
||||||
if (position >= 0) {
|
if (position >= 0) {
|
||||||
|
val watchedActivity = PrefManager.getCustomVal<Set<Int>>("${activity[position].id}_activities", setOf())
|
||||||
|
val startFrom = findFirstNonMatch(watchedActivity, activity[position].activity )
|
||||||
|
val startIndex = if ( startFrom > 0) startFrom else 0
|
||||||
binding.stories.startAnimation(slideOutRight)
|
binding.stories.startAnimation(slideOutRight)
|
||||||
binding.stories.setStoriesList(activity[position].activity, this)
|
binding.stories.setStoriesList(activity[position].activity, this, startIndex + 1)
|
||||||
binding.stories.startAnimation(slideInLeft)
|
binding.stories.startAnimation(slideInLeft)
|
||||||
} else {
|
} else {
|
||||||
finish()
|
finish()
|
|
@ -67,7 +67,7 @@ constructor(
|
||||||
private lateinit var time: TextView
|
private lateinit var time: TextView
|
||||||
private lateinit var infoText: TextView
|
private lateinit var infoText: TextView
|
||||||
private lateinit var coverImage: ImageView
|
private lateinit var coverImage: ImageView
|
||||||
private var storyDuration: String = "4"
|
private var storyDuration: String = "6"
|
||||||
private lateinit var animation: ObjectAnimator
|
private lateinit var animation: ObjectAnimator
|
||||||
private var storyIndex: Int = 1
|
private var storyIndex: Int = 1
|
||||||
private var userClicked: Boolean = false
|
private var userClicked: Boolean = false
|
||||||
|
@ -110,9 +110,10 @@ constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun setStoriesList(activityList: List<Activity>, activity: FragmentActivity) {
|
fun setStoriesList(activityList: List<Activity>, activity: FragmentActivity, startIndex : Int = 1) {
|
||||||
this.activityList = activityList
|
this.activityList = activityList
|
||||||
this.activ = activity
|
this.activ = activity
|
||||||
|
this.storyIndex = startIndex
|
||||||
addLoadingViews(activityList)
|
addLoadingViews(activityList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,6 +235,9 @@ constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showStory() {
|
private fun showStory() {
|
||||||
|
if (storyIndex > 1) {
|
||||||
|
completeProgressBar(storyIndex - 1)
|
||||||
|
}
|
||||||
val progressBar = findViewWithTag<ProgressBar>("story${storyIndex}")
|
val progressBar = findViewWithTag<ProgressBar>("story${storyIndex}")
|
||||||
loadingView.visibility = View.VISIBLE
|
loadingView.visibility = View.VISIBLE
|
||||||
animation = ObjectAnimator.ofInt(progressBar, "progress", 0, 100)
|
animation = ObjectAnimator.ofInt(progressBar, "progress", 0, 100)
|
||||||
|
@ -292,9 +296,11 @@ constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun completeProgressBar(storyIndex: Int) {
|
private fun completeProgressBar(storyIndex: Int) {
|
||||||
val lastProgressBar = findViewWithTag<ProgressBar>("story${storyIndex}")
|
for (i in 1 until storyIndex + 1) {
|
||||||
lastProgressBar?.let {
|
val progressBar = findViewWithTag<ProgressBar>("story${i}")
|
||||||
it.progress = 100
|
progressBar?.let {
|
||||||
|
it.progress = 100
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package ani.dantotsu.home
|
package ani.dantotsu.home.status
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import ani.dantotsu.connections.anilist.Anilist
|
||||||
import ani.dantotsu.databinding.ItemUserStatusBinding
|
import ani.dantotsu.databinding.ItemUserStatusBinding
|
||||||
import ani.dantotsu.loadImage
|
import ani.dantotsu.loadImage
|
||||||
import ani.dantotsu.profile.ProfileActivity
|
import ani.dantotsu.profile.ProfileActivity
|
||||||
|
@ -12,8 +13,8 @@ import ani.dantotsu.profile.User
|
||||||
import ani.dantotsu.setAnimation
|
import ani.dantotsu.setAnimation
|
||||||
import ani.dantotsu.settings.saving.PrefManager
|
import ani.dantotsu.settings.saving.PrefManager
|
||||||
|
|
||||||
class UserStatus(private val user: ArrayList<User>) :
|
class UserStatusAdapter(private val user: ArrayList<User>) :
|
||||||
RecyclerView.Adapter<UserStatus.UsersViewHolder>() {
|
RecyclerView.Adapter<UserStatusAdapter.UsersViewHolder>() {
|
||||||
|
|
||||||
inner class UsersViewHolder(val binding: ItemUserStatusBinding) :
|
inner class UsersViewHolder(val binding: ItemUserStatusBinding) :
|
||||||
RecyclerView.ViewHolder(binding.root) {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
@ -58,12 +59,12 @@ class UserStatus(private val user: ArrayList<User>) :
|
||||||
setAnimation(b.root.context, b.root)
|
setAnimation(b.root.context, b.root)
|
||||||
val user = user[position]
|
val user = user[position]
|
||||||
b.profileUserAvatar.loadImage(user.pfp)
|
b.profileUserAvatar.loadImage(user.pfp)
|
||||||
b.profileUserName.text = user.name
|
b.profileUserName.text = if (Anilist.userid == user.id) "You" else user.name
|
||||||
|
|
||||||
val watchedActivityIds =
|
val watchedActivity =
|
||||||
PrefManager.getCustomVal<Set<Int>>("${user.id}_activities", setOf())
|
PrefManager.getCustomVal<Set<Int>>("${user.id}_activities", setOf())
|
||||||
val activityIdToStatusList = user.activity.map { watchedActivityIds.contains(it.id) }
|
val booleanList = user.activity.map { watchedActivity.contains(it.id) }
|
||||||
b.profileUserStatusIndicator.setParts(user.activity.size, activityIdToStatusList)
|
b.profileUserStatusIndicator.setParts(user.activity.size, booleanList, user.id == Anilist.userid)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,6 @@
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="marquee"
|
||||||
android:fontFamily="@font/poppins_semi_bold"
|
android:fontFamily="@font/poppins_semi_bold"
|
||||||
android:gravity="start"
|
android:gravity="start"
|
||||||
android:lineSpacingExtra="-8sp"
|
|
||||||
android:maxLines="3"
|
android:maxLines="3"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:textAlignment="textStart"
|
android:textAlignment="textStart"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue