diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt index 070146c4780..912444886a8 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt @@ -6,6 +6,7 @@ import ani.dantotsu.checkGenreTime import ani.dantotsu.checkId 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 @@ -1348,4 +1349,12 @@ Page(page:$page,perPage:50) { } return res } + + suspend fun getFeed(userId: Int?, global: Boolean = false, page: Int = 1): FeedResponse? { + val filter = if (userId != null) "userId:$userId," + else if (global) "isFollowing:false," + else "isFollowing:true," + val res = executeQuery("""{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}}}}}}""") + return res + } } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/api/Feed.kt b/app/src/main/java/ani/dantotsu/connections/anilist/api/Feed.kt new file mode 100644 index 00000000000..ca31d6f96a0 --- /dev/null +++ b/app/src/main/java/ani/dantotsu/connections/anilist/api/Feed.kt @@ -0,0 +1,92 @@ +package ani.dantotsu.connections.anilist.api + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class FeedResponse( + @SerialName("data") + val data: Data +) { + @Serializable + data class Data( + @SerialName("Page") + val page: ActivityPage + ) +} + +@Serializable +data class ActivityPage( + @SerialName("activities") + val activities: List +) + +@Serializable +data class Activity( + @SerialName("__typename") + val typename: String, + @SerialName("id") + val id: Int, + @SerialName("recipientId") + val recipientId: Int?, + @SerialName("messengerId") + val messengerId: Int?, + @SerialName("userId") + val userId: Int?, + @SerialName("type") + val type: String, + @SerialName("replyCount") + val replyCount: Int, + @SerialName("status") + val status: String?, + @SerialName("progress") + val progress: String?, + @SerialName("text") + val text: String?, + @SerialName("message") + val message: String?, + @SerialName("siteUrl") + val siteUrl: String?, + @SerialName("isLocked") + val isLocked: Boolean, + @SerialName("isSubscribed") + val isSubscribed: Boolean, + @SerialName("likeCount") + val likeCount: Int?, + @SerialName("isLiked") + val isLiked: Boolean?, + @SerialName("isPinned") + val isPinned: Boolean?, + @SerialName("isPrivate") + val isPrivate: Boolean?, + @SerialName("createdAt") + val createdAt: Int, + @SerialName("user") + val user: User?, + @SerialName("media") + val media: Media?, + @SerialName("replies") + val replies: List?, + @SerialName("likes") + val likes: List?, +) + +@Serializable +data class Reply( + @SerialName("id") + val id: Int, + @SerialName("userId") + val userId: Int, + @SerialName("text") + val text: String, + @SerialName("likeCount") + val likeCount: Int, + @SerialName("isLiked") + val isLiked: Boolean, + @SerialName("createdAt") + val createdAt: Int, + @SerialName("user") + val user: User, + @SerialName("likes") + val likes: List?, +) \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/profile/ActivityActivity.kt b/app/src/main/java/ani/dantotsu/profile/ActivityActivity.kt index 47d2ad6755f..341bde712cc 100644 --- a/app/src/main/java/ani/dantotsu/profile/ActivityActivity.kt +++ b/app/src/main/java/ani/dantotsu/profile/ActivityActivity.kt @@ -5,13 +5,22 @@ 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.profile.activity.ActivityItem import ani.dantotsu.statusBarHeight import ani.dantotsu.themes.ThemeManager +import com.xwray.groupie.GroupieAdapter +import kotlinx.coroutines.launch class ActivityActivity : AppCompatActivity() { private lateinit var binding: ActivityFollowBinding + private var adapter: GroupieAdapter = GroupieAdapter() + private var activityList: List = emptyList() @SuppressLint("SetTextI18n") override fun onCreate(savedInstanceState: Bundle?) { @@ -23,7 +32,24 @@ class ActivityActivity : AppCompatActivity() { binding.listTitle.text = "Activity" binding.listToolbar.updateLayoutParams { 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() + } + + var userId: Int? = intent.getIntExtra("userId", -1) + if (userId == -1) userId = null + val global = intent.getBooleanExtra("global", false) + + lifecycleScope.launch { + val res = Anilist.query.getFeed(userId, global) + res?.data?.page?.activities?.let { activities -> + activityList = activities + adapter.update(activityList.map { ActivityItem(it){} }) + } + } } } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/profile/activity/ActivityItem.kt b/app/src/main/java/ani/dantotsu/profile/activity/ActivityItem.kt index f1ced2016b0..7860d93e1d3 100644 --- a/app/src/main/java/ani/dantotsu/profile/activity/ActivityItem.kt +++ b/app/src/main/java/ani/dantotsu/profile/activity/ActivityItem.kt @@ -1,22 +1,61 @@ package ani.dantotsu.profile.activity +import android.content.Context import android.view.View +import androidx.core.content.ContextCompat import ani.dantotsu.R -import ani.dantotsu.databinding.ItemNotificationBinding +import ani.dantotsu.connections.anilist.api.Activity +import ani.dantotsu.databinding.ItemActivityBinding +import ani.dantotsu.loadImage +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 class ActivityItem( -): BindableItem() { - private lateinit var binding: ItemNotificationBinding - override fun bind(viewBinding: ItemNotificationBinding, position: Int) { + private val activity: Activity, + val clickCallback: (Int) -> Unit +): BindableItem() { + private lateinit var binding: ItemActivityBinding + override fun bind(viewBinding: ItemActivityBinding, position: Int) { binding = viewBinding + when (activity.typename) { + "ListActivity" ->{ + 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.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 context = binding.root.context + val banner = activity.media.bannerImage + if (banner != null) { + if (!(context as android.app.Activity).isDestroyed) + Glide.with(context as Context) + .load(GlideUrl(banner)) + .diskCacheStrategy(DiskCacheStrategy.ALL).override(400) + .apply(RequestOptions.bitmapTransform(BlurTransformation(2, 2))) + .into(binding.activityBannerImage) + } else { + binding.activityBannerImage.setImageResource(R.drawable.linear_gradient_bg) + } + } + } } override fun getLayout(): Int { - return R.layout.item_notification + return R.layout.item_activity } - override fun initializeViewBinding(view: View): ItemNotificationBinding { - return ItemNotificationBinding.bind(view) + override fun initializeViewBinding(view: View): ItemActivityBinding { + return ItemActivityBinding.bind(view) } } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/profile/activity/NotificationItemBuilder.kt b/app/src/main/java/ani/dantotsu/profile/activity/ActivityItemBuilder.kt similarity index 78% rename from app/src/main/java/ani/dantotsu/profile/activity/NotificationItemBuilder.kt rename to app/src/main/java/ani/dantotsu/profile/activity/ActivityItemBuilder.kt index c894f65a60d..d810258b8cb 100644 --- a/app/src/main/java/ani/dantotsu/profile/activity/NotificationItemBuilder.kt +++ b/app/src/main/java/ani/dantotsu/profile/activity/ActivityItemBuilder.kt @@ -5,63 +5,7 @@ import ani.dantotsu.connections.anilist.api.NotificationType import java.text.SimpleDateFormat import java.util.Date import java.util.Locale - -/* -* ACTIVITY_MESSAGE - -A user has sent you message -ACTIVITY_REPLY - -A user has replied to your activity -FOLLOWING - -A user has followed you -ACTIVITY_MENTION - -A user has mentioned you in their activity -THREAD_COMMENT_MENTION - -A user has mentioned you in a forum comment -THREAD_SUBSCRIBED - -A user has commented in one of your subscribed forum threads -THREAD_COMMENT_REPLY - -A user has replied to your forum comment -AIRING - -An anime you are currently watching has aired -ACTIVITY_LIKE - -A user has liked your activity -ACTIVITY_REPLY_LIKE - -A user has liked your activity reply -THREAD_LIKE - -A user has liked your forum thread -THREAD_COMMENT_LIKE - -A user has liked your forum comment -ACTIVITY_REPLY_SUBSCRIBED - -A user has replied to activity you have also replied to -RELATED_MEDIA_ADDITION - -A new anime or manga has been added to the site where its related media is on the user's list -MEDIA_DATA_CHANGE - -An anime or manga has had a data change that affects how a user may track it in their lists -MEDIA_MERGE - -Anime or manga entries on the user's list have been merged into a single entry -MEDIA_DELETION - -An anime or manga on the user's list has been deleted from the site - -* */ - -interface NotificationItemBuilder { +class ActivityItemBuilder { companion object { fun getContent(notification: Notification): String { diff --git a/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt b/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt index d0930c7b8c3..31e84a7615f 100644 --- a/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt +++ b/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt @@ -4,7 +4,6 @@ import android.app.Activity import android.content.Context import android.util.TypedValue import android.view.View -import android.view.ViewGroup import ani.dantotsu.R import ani.dantotsu.connections.anilist.api.Notification import ani.dantotsu.connections.anilist.api.NotificationType @@ -73,8 +72,8 @@ class NotificationItem( private fun setBinding() { val notificationType: NotificationType = NotificationType.valueOf(notification.notificationType) - binding.notificationText.text = NotificationItemBuilder.getContent(notification) - binding.notificationDate.text = NotificationItemBuilder.getDateTime(notification.createdAt) + binding.notificationText.text = ActivityItemBuilder.getContent(notification) + binding.notificationDate.text = ActivityItemBuilder.getDateTime(notification.createdAt) binding.root.setOnClickListener { clickCallback(id, clickType) } when (notificationType) { diff --git a/app/src/main/res/layout/item_activity.xml b/app/src/main/res/layout/item_activity.xml index 1349501ded8..eb63b17a32e 100644 --- a/app/src/main/res/layout/item_activity.xml +++ b/app/src/main/res/layout/item_activity.xml @@ -61,6 +61,7 @@