This commit is contained in:
rebelonion 2024-05-19 14:18:16 -05:00
commit 91f728150c
13 changed files with 406 additions and 73 deletions

View file

@ -1505,7 +1505,7 @@ Page(page:$page,perPage:50) {
return author
}
suspend fun getReviews(mediaId: Int, page: Int = 1, sort: String = "UPDATED_AT_DESC"): Query.ReviewsResponse? {
suspend fun getReviews(mediaId: Int, page: Int = 1, sort: String = "CREATED_AT_DESC"): Query.ReviewsResponse? {
return executeQuery<Query.ReviewsResponse>(
"""{Page(page:$page,perPage:10){pageInfo{currentPage,hasNextPage,total}reviews(mediaId:$mediaId,sort:$sort){id,mediaId,mediaType,summary,body(asHtml:true)rating,ratingAmount,userRating,score,private,siteUrl,createdAt,updatedAt,user{id,name,bannerImage avatar{medium,large}}}}}""",
force = true

View file

@ -84,15 +84,15 @@ class Contributors {
"https://anilist.co/user/6244220"
),
Developer(
"Zaidsenior",
"Ziadsenior",
"https://s4.anilist.co/file/anilistcdn/user/avatar/large/b6049773-8cjYeUOFUguv.jpg",
"Comment Moderator",
"Comment Moderator and Arabic Translator",
"https://anilist.co/user/6049773"
),
Developer(
"hastsu",
"https://cdn.discordapp.com/avatars/602422545077108749/20b4a6efa4314550e4ed51cdbe4fef3d.webp?size=160",
"Comment Moderator",
"Comment Moderator and Arabic Translator",
"https://anilist.co/user/6183359"
),
)

View file

@ -12,13 +12,14 @@ import ani.dantotsu.getThemeColor
class CircleView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
private var parts: Int = 3
private var gapAngle: Float = 9f
private var gapAngle: Float = 12f
private val path = Path()
private var isUser = false
private var booleanList = listOf<Boolean>()
private val paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
style = Paint.Style.STROKE
strokeWidth = 6f
strokeCap = Paint.Cap.ROUND
}
@SuppressLint("DrawAllocation")

View file

@ -42,6 +42,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Calendar
import java.util.Locale
import kotlin.math.abs
class Stories @JvmOverloads constructor(
@ -264,29 +265,44 @@ class Stories @JvmOverloads constructor(
private var startClickTime = 0L
private var startX = 0f
private var startY = 0f
private var isLongPress = false
private val swipeThreshold = 100
override fun onTouch(view: View?, event: MotionEvent?): Boolean {
val maxClickDuration = 200
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
startX = event.x
startY = event.y
startClickTime = Calendar.getInstance().timeInMillis
pause()
isLongPress = false
}
MotionEvent.ACTION_MOVE -> {
val deltaX = event.x - startX
val deltaY = event.y - startY
if (!isLongPress && (abs(deltaX) > swipeThreshold || abs(deltaY) > swipeThreshold)) {
isLongPress = true
}
}
MotionEvent.ACTION_UP -> {
val clickDuration = Calendar.getInstance().timeInMillis - startClickTime
if (clickDuration < maxClickDuration) {
//click occurred
view?.let {
if (it.id == R.id.leftTouchPanel) {
leftPanelTouch()
} else if (it.id == R.id.rightTouchPanel) {
rightPanelTouch()
}
if (clickDuration < maxClickDuration && !isLongPress) {
when (view?.id) {
R.id.leftTouchPanel -> leftPanelTouch()
R.id.rightTouchPanel -> rightPanelTouch()
}
} else {
//hold click occurred
resume()
}
val deltaX = event.x - startX
if (abs(deltaX) > swipeThreshold) {
if (deltaX > 0) onStoriesPrevious()
else onStoriesCompleted()
}
}
}
return true
@ -359,16 +375,14 @@ class Stories @JvmOverloads constructor(
)
}
fun visible(isList: Boolean) {
val visible = if (isList) View.VISIBLE else View.GONE
val gone = if (isList) View.GONE else View.VISIBLE
binding.textActivity.visibility = gone
binding.textActivityContainer.visibility = gone
binding.infoText.visibility = visible
binding.coverImage.visibility = visible
binding.textActivity.isVisible = !isList
binding.textActivityContainer.isVisible = !isList
binding.infoText.isVisible = isList
binding.coverImage.isVisible = isList
binding.infoText.visibility = if (isList) View.VISIBLE else View.INVISIBLE
binding.infoText.text = ""
binding.contentImageViewKen.visibility = visible
binding.contentImageView.visibility = visible
binding.contentImageViewKen.isVisible = isList
binding.contentImageView.isVisible = isList
}
when (story.typename) {
@ -387,8 +401,7 @@ class Stories @JvmOverloads constructor(
story.status?.contains("completed") == false &&
!story.status.contains("plans") &&
!story.status.contains("repeating")
)
{
) {
"of ${story.media?.title?.userPreferred}"
} else {
""
@ -413,9 +426,7 @@ class Stories @JvmOverloads constructor(
ViewCompat.getTransitionName(binding.coverImage)!!
).toBundle()
)
}
}
"TextActivity" -> {
@ -445,11 +456,13 @@ class Stories @JvmOverloads constructor(
val likeColor = ContextCompat.getColor(context, R.color.yt_red)
val notLikeColor = ContextCompat.getColor(context, R.color.bg_opp)
binding.activityRepliesContainer.setOnClickListener {
RepliesBottomDialog.newInstance(story.id).show(activity.supportFragmentManager, "replies")
RepliesBottomDialog.newInstance(story.id)
.show(activity.supportFragmentManager, "replies")
}
binding.activityLike.setColorFilter(if (story.isLiked == true) likeColor else notLikeColor)
binding.replyCount.text = story.replyCount.toString()
binding.activityLikeCount.text = story.likeCount.toString()
binding.activityLike.setColorFilter(if (story.isLiked == true) likeColor else notLikeColor)
binding.activityReplies.setColorFilter(ContextCompat.getColor(context, R.color.bg_opp))
binding.activityLikeContainer.setOnClickListener {
like()
}

View file

@ -77,7 +77,7 @@ class ReviewActivity : AppCompatActivity() {
binding.listBack.setOnClickListener { onBackPressedDispatcher.onBackPressed() }
lifecycleScope.launch(Dispatchers.IO) {
val response = Anilist.query.getReviews(mediaId)
val response = Anilist.query.getReviews(mediaId)?.data?.page
withContext(Dispatchers.Main) {
binding.listProgressBar.visibility = View.GONE
binding.listRecyclerView.setOnTouchListener { _, event ->
@ -94,9 +94,9 @@ class ReviewActivity : AppCompatActivity() {
}
false
}
currentPage = response?.data?.page?.pageInfo?.currentPage ?: 1
hasNextPage = response?.data?.page?.pageInfo?.hasNextPage ?: false
response?.data?.page?.reviews?.let {
currentPage = response?.pageInfo?.currentPage ?: 1
hasNextPage = response?.pageInfo?.hasNextPage ?: false
response?.reviews?.let {
reviews.addAll(it)
fillList()
}
@ -122,29 +122,10 @@ class ReviewActivity : AppCompatActivity() {
private fun fillList() {
adapter.clear()
reviews.forEach {
val username = it.user?.name ?: "Unknown"
val name = SpannableString(username + " - " + it.score)
//change the size of the score
name.setSpan(
android.text.style.RelativeSizeSpan(0.9f),
0,
name.length,
android.text.Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
//give the text an underline
name.setSpan(
android.text.style.UnderlineSpan(),
username.length + 3,
name.length,
android.text.Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
adapter.add(
FollowerItem(
it.id,
name,
it.user?.avatar?.medium,
it.user?.bannerImage,
it.summary,
ReviewAdapter(
it,
this,
this::onUserClick
)
)

View file

@ -0,0 +1,129 @@
package ani.dantotsu.media
import android.content.Context
import android.text.SpannableString
import android.view.View
import androidx.lifecycle.lifecycleScope
import ani.dantotsu.R
import ani.dantotsu.blurImage
import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.connections.anilist.api.Query
import ani.dantotsu.databinding.ItemFollowerBinding
import ani.dantotsu.databinding.ItemReviewsBinding
import ani.dantotsu.getThemeColor
import ani.dantotsu.loadImage
import ani.dantotsu.profile.activity.ActivityItemBuilder
import ani.dantotsu.toast
import com.xwray.groupie.viewbinding.BindableItem
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class ReviewAdapter(
private var review: Query.Review,
val context: ReviewActivity,
val clickCallback: (Int) -> Unit
) : BindableItem<ItemReviewsBinding>() {
private lateinit var binding: ItemReviewsBinding
override fun bind(viewBinding: ItemReviewsBinding, position: Int) {
binding = viewBinding
binding.reviewUserName.text = review.user?.name
binding.reviewUserAvatar.loadImage(review.user?.avatar?.medium)
binding.reviewText.text = review.summary
binding.reviewPostTime.text = ActivityItemBuilder.getDateTime(review.createdAt)
binding.reviewTag.text = "[${review.score}]"
binding.root.setOnClickListener { clickCallback(review.id) }
userVote(review.userRating)
enableVote()
binding.reviewTotalVotes.text = review.rating.toString()
}
override fun getLayout(): Int {
return R.layout.item_reviews
}
override fun initializeViewBinding(view: View): ItemReviewsBinding {
return ItemReviewsBinding.bind(view)
}
private fun userVote(type: String) {
when (type) {
"NO_VOTE" -> {
binding.reviewUpVote.setImageResource(R.drawable.ic_round_upvote_inactive_24)
binding.reviewDownVote.setImageResource(R.drawable.ic_round_upvote_inactive_24)
binding.reviewUpVote.alpha = 0.6f
binding.reviewDownVote.alpha = 0.6f
}
"UP_VOTE" -> {
binding.reviewUpVote.setImageResource(R.drawable.ic_round_upvote_active_24)
binding.reviewDownVote.setImageResource(R.drawable.ic_round_upvote_inactive_24)
binding.reviewUpVote.alpha = 1f
binding.reviewDownVote.alpha = 0.6f
}
"DOWN_VOTE" -> {
binding.reviewUpVote.setImageResource(R.drawable.ic_round_upvote_inactive_24)
binding.reviewDownVote.setImageResource(R.drawable.ic_round_upvote_active_24)
binding.reviewDownVote.alpha = 1f
binding.reviewUpVote.alpha = 0.6f
}
}
}
private fun rateReview(rating: String) {
disableVote()
context.lifecycleScope.launch {
val result = Anilist.mutation.rateReview(review.id, rating)
if (result != null) {
withContext(Dispatchers.Main) {
val res = result.data.rateReview
review.rating = res.rating
review.ratingAmount = res.ratingAmount
review.userRating = res.userRating
userVote(review.userRating)
binding.reviewTotalVotes.text = review.rating.toString()
userVote(review.userRating)
enableVote()
}
} else {
withContext(Dispatchers.Main) {
toast(
context.getString(R.string.error_message, "response is null")
)
enableVote()
}
}
}
}
private fun disableVote() {
binding.reviewUpVote.setOnClickListener(null)
binding.reviewDownVote.setOnClickListener(null)
binding.reviewUpVote.isEnabled = false
binding.reviewDownVote.isEnabled = false
}
private fun enableVote() {
binding.reviewUpVote.setOnClickListener {
if (review.userRating == "UP_VOTE") {
rateReview("NO_VOTE")
} else {
rateReview("UP_VOTE")
}
disableVote()
}
binding.reviewDownVote.setOnClickListener {
if (review.userRating == "DOWN_VOTE") {
rateReview("NO_VOTE")
} else {
rateReview("DOWN_VOTE")
}
disableVote()
}
binding.reviewUpVote.isEnabled = true
binding.reviewDownVote.isEnabled = true
}
}

View file

@ -5,6 +5,7 @@ import android.view.View
import androidx.core.content.ContextCompat
import ani.dantotsu.R
import ani.dantotsu.databinding.ItemSubscriptionBinding
import ani.dantotsu.loadImage
import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.notifications.subscription.SubscriptionHelper
import com.xwray.groupie.GroupieAdapter
@ -25,7 +26,7 @@ class SubscriptionItem(
else
SubscriptionHelper.getMangaParser(media.id).name
val mediaName = media.name
val showName = "$mediaName - $parserName"
val showName = "$mediaName ($parserName)"
binding.subscriptionName.text = showName
binding.root.setOnClickListener {
ContextCompat.startActivity(
@ -36,6 +37,7 @@ class SubscriptionItem(
null
)
}
binding.subscriptionCover.loadImage(media.image)
binding.deleteSubscription.setOnClickListener {
SubscriptionHelper.deleteSubscription(id, true)
adapter.remove(this)

View file

@ -2,6 +2,7 @@
<androidx.core.widget.NestedScrollView 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:scrollbars="none"
android:layout_width="match_parent"
android:layout_height="match_parent">

View file

@ -28,7 +28,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="0dp"
android:gravity="center_vertical"
@ -45,7 +45,9 @@
android:id="@+id/devRole"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/poppins_bold" />
android:text="@string/lorem_ipsum"
android:maxLines="2"
android:fontFamily="@font/poppins_semi_bold" />
</LinearLayout>
</LinearLayout>

View file

@ -74,11 +74,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:ellipsize="end"
android:fontFamily="@font/poppins_semi_bold"
android:ellipsize="end"
android:alpha="0.75"
android:maxLines="2"
android:text="@string/lorem_ipsum"
android:textSize="14sp"
android:textSize="12sp"
android:visibility="gone" />
</LinearLayout>
</androidx.cardview.widget.CardView>

View file

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/commentsCardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="4dp">
<LinearLayout
android:id="@+id/linearLayout5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="0dp"
android:paddingEnd="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.card.MaterialCardView
android:id="@+id/reviewUserAvatarContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="12dp"
android:backgroundTint="@color/transparent"
app:cardCornerRadius="64dp"
app:strokeColor="@color/transparent">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/reviewUserAvatar"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_gravity="center"
app:srcCompat="@drawable/ic_round_add_circle_24"
tools:ignore="ContentDescription,ImageContrastCheck"
tools:tint="@color/bg_black_50" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<LinearLayout
android:id="@+id/reviewUserDetailsLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="@+id/reviewText"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/reviewUserName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="4dp"
android:ellipsize="end"
android:fontFamily="@font/poppins_bold"
android:paddingTop="1dp"
android:paddingBottom="0dp"
android:singleLine="true"
android:text="Username"
android:textColor="?attr/colorPrimary"
android:textSize="15sp"
tools:ignore="HardcodedText,RtlSymmetry" />
<TextView
android:id="@+id/reviewTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dp"
android:alpha="0.8"
android:fontFamily="@font/poppins_bold"
android:text="[1]"
android:textSize="12sp"
tools:ignore="HardcodedText" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:alpha="0.6"
android:fontFamily="@font/poppins_semi_bold"
android:text="•"
android:textSize="16sp"
tools:ignore="HardcodedText,RtlSymmetry" />
<TextView
android:id="@+id/reviewPostTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dp"
android:alpha="0.6"
android:fontFamily="@font/poppins_semi_bold"
android:text="Time"
android:textSize="12sp"
tools:ignore="HardcodedText,RtlSymmetry" />
</LinearLayout>
<TextView
android:id="@+id/reviewText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="@font/poppins_semi_bold"
android:maxLines="2"
android:scrollHorizontally="false"
android:text="@string/slogan"
android:textSize="12sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="@+id/linearLayout7"
app:layout_constraintHeight_max="200dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/linearLayout5"
app:layout_constraintTop_toBottomOf="@+id/reviewUserDetailsLayout" />
<LinearLayout
android:id="@+id/linearLayout6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="52dp"
android:orientation="horizontal"
app:layout_constraintStart_toEndOf="@+id/linearLayout5"
app:layout_constraintTop_toBottomOf="@+id/reviewText">
<Space
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageView
android:id="@+id/reviewUpVote"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="12dp"
android:alpha="0.6"
android:padding="2dp"
app:srcCompat="@drawable/ic_round_upvote_inactive_24"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/reviewTotalVotes"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="4dp"
android:alpha="0.6"
android:fontFamily="@font/poppins_semi_bold"
android:gravity="center"
android:text="100"
android:textSize="12sp"
app:layout_constraintStart_toEndOf="@+id/commentUpVote"
app:layout_constraintTop_toBottomOf="@+id/reviewText"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/reviewDownVote"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="4dp"
android:alpha="0.6"
android:padding="2dp"
android:rotation="180"
app:layout_constraintStart_toEndOf="@+id/commentTotalVotes"
app:layout_constraintTop_toBottomOf="@+id/reviewText"
app:srcCompat="@drawable/ic_round_upvote_inactive_24"
tools:ignore="ContentDescription" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="4dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -30,7 +30,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_circle_cancel"
android:src="@drawable/ic_round_close_24"
android:textSize="14sp"
app:tint="?attr/colorOnBackground"
tools:ignore="ContentDescription" />

View file

@ -8,14 +8,35 @@
android:layout_marginHorizontal="8dp"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<com.google.android.material.card.MaterialCardView
android:id="@+id/subscriptionCoverContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_margin="16dp"
android:layout_marginStart="16dp"
android:backgroundTint="@color/bg_white"
app:cardCornerRadius="16dp"
app:strokeColor="@color/transparent">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/subscriptionCover"
android:layout_width="108dp"
android:layout_height="160dp"
android:layout_gravity="center"
android:scaleType="centerCrop"
tools:ignore="ContentDescription,ImageContrastCheck"
tools:srcCompat="@tools:sample/backgrounds/scenic"
tools:tint="@color/transparent" />
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/subscriptionName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:fontFamily="@font/poppins_bold"
android:fontFamily="@font/poppins_semi_bold"
android:text="@string/placeholder"
android:textSize="16sp" />
@ -26,7 +47,7 @@
android:layout_gravity="center_vertical"
android:layout_marginEnd="8dp"
android:contentDescription="@string/delete"
android:src="@drawable/ic_circle_cancel"
android:src="@drawable/ic_round_close_24"
app:tint="?attr/colorOnBackground" />
</LinearLayout>