fix: some UI changes (for better or worse)
This commit is contained in:
parent
7ac679f927
commit
a2ca16355a
26 changed files with 493 additions and 444 deletions
|
@ -1,48 +1,29 @@
|
|||
package ani.dantotsu.profile
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.ActivityActivityBinding
|
||||
import ani.dantotsu.databinding.ActivityFollowBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
|
||||
|
||||
class ActivityActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityActivityBinding
|
||||
private lateinit var binding: ActivityFollowBinding
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val immersiveMode = PrefManager.getVal<Boolean>(PrefName.ImmersiveMode)
|
||||
if (immersiveMode) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
}
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
initActivity(this)
|
||||
binding = ActivityActivityBinding.inflate(layoutInflater)
|
||||
if (!immersiveMode) {
|
||||
this.window.statusBarColor =
|
||||
ContextCompat.getColor(this, R.color.nav_bg_inv)
|
||||
binding.root.fitsSystemWindows = true
|
||||
|
||||
} else {
|
||||
binding.root.fitsSystemWindows = false
|
||||
window.setFlags(
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN
|
||||
)
|
||||
binding.listTitle.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = statusBarHeight
|
||||
}
|
||||
}
|
||||
binding = ActivityFollowBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
binding.listTitle.text = "Activity"
|
||||
binding.listToolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> { topMargin = statusBarHeight }
|
||||
binding.followerGrid.visibility = ViewGroup.GONE
|
||||
binding.followerList.visibility = ViewGroup.GONE
|
||||
}
|
||||
}
|
|
@ -2,23 +2,17 @@ package ani.dantotsu.profile
|
|||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.MarginLayoutParams
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import android.widget.ImageButton
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import ani.dantotsu.R
|
||||
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,31 +30,11 @@ class FollowActivity : AppCompatActivity(){
|
|||
private lateinit var selected: ImageButton
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val immersiveMode = PrefManager.getVal<Boolean>(PrefName.ImmersiveMode)
|
||||
if (immersiveMode) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
}
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
initActivity(this)
|
||||
binding = ActivityFollowBinding.inflate(layoutInflater)
|
||||
|
||||
if (!immersiveMode) {
|
||||
this.window.statusBarColor =
|
||||
ContextCompat.getColor(this, R.color.nav_bg_inv)
|
||||
binding.root.fitsSystemWindows = true
|
||||
|
||||
} else {
|
||||
binding.root.fitsSystemWindows = false
|
||||
window.setFlags(
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN
|
||||
)
|
||||
binding.listTitle.updateLayoutParams<MarginLayoutParams> {
|
||||
topMargin = statusBarHeight
|
||||
}
|
||||
}
|
||||
|
||||
binding.listToolbar.updateLayoutParams<MarginLayoutParams> { topMargin = statusBarHeight }
|
||||
setContentView(binding.root)
|
||||
val layoutType = PrefManager.getVal<Int>(PrefName.FollowerLayout)
|
||||
selected = getSelected(layoutType)
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
package ani.dantotsu.profile
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.ItemFollowerBinding
|
||||
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 FollowerItem(
|
||||
private val id: Int,
|
||||
|
@ -18,9 +25,16 @@ class FollowerItem(
|
|||
override fun bind(viewBinding: ItemFollowerBinding, position: Int) {
|
||||
binding = viewBinding
|
||||
binding.profileUserName.text = name
|
||||
val context = binding.profileBannerImage.context
|
||||
avatar?.let { binding.profileUserAvatar.loadImage(it) }
|
||||
if (banner != null) {
|
||||
binding.profileBannerImage.loadImage(banner)
|
||||
if (!(context as Activity).isDestroyed)
|
||||
Glide.with(context as Context)
|
||||
.load(GlideUrl(banner))
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL).override(400)
|
||||
.apply(RequestOptions.bitmapTransform(BlurTransformation(2, 6)))
|
||||
.into(binding.profileBannerImage)
|
||||
} else {
|
||||
binding.profileBannerImage.setImageResource(R.drawable.linear_gradient_bg)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
package ani.dantotsu.profile.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
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.Notification
|
||||
import ani.dantotsu.databinding.ActivityFollowBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.media.MediaDetailsActivity
|
||||
import ani.dantotsu.profile.ProfileActivity
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class NotificationActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityFollowBinding
|
||||
private var adapter: GroupieAdapter = GroupieAdapter()
|
||||
private var notificationList: List<Notification> = 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 = "Notifications"
|
||||
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()
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
val res = Anilist.query.getNotifications(Anilist.userid?:0)
|
||||
res?.data?.page?.notifications?.let { notifications ->
|
||||
notificationList = notifications
|
||||
adapter.update(notificationList.map { NotificationItem(it, ::onNotificationClick) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onNotificationClick(id: Int, type: NotificationClickType) {
|
||||
when (type) {
|
||||
NotificationClickType.USER -> {
|
||||
ContextCompat.startActivity(
|
||||
this, Intent(this, ProfileActivity::class.java)
|
||||
.putExtra("userId", id), null
|
||||
)
|
||||
}
|
||||
NotificationClickType.MEDIA -> {
|
||||
ContextCompat.startActivity(
|
||||
this, Intent(this, MediaDetailsActivity::class.java)
|
||||
.putExtra("mediaId", id), null
|
||||
)
|
||||
}
|
||||
NotificationClickType.UNDEFINED -> {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
enum class NotificationClickType {
|
||||
USER, MEDIA, UNDEFINED
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,27 @@
|
|||
package ani.dantotsu.profile.activity
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.connections.anilist.api.Notification
|
||||
import ani.dantotsu.connections.anilist.api.NotificationType
|
||||
import ani.dantotsu.databinding.ItemNotificationBinding
|
||||
import ani.dantotsu.loadImage
|
||||
import ani.dantotsu.notifications.NotificationActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.statusBarHeight
|
||||
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 NotificationItem(
|
||||
private val notification: Notification,
|
||||
|
@ -29,107 +43,133 @@ class NotificationItem(
|
|||
return ItemNotificationBinding.bind(view)
|
||||
}
|
||||
|
||||
private fun image(user: Boolean = false) {
|
||||
val context = binding.notificationBannerImage.context
|
||||
val cover = if (user) notification.user?.bannerImage else notification.media?.bannerImage
|
||||
if (cover != null) {
|
||||
if (!(context as Activity).isDestroyed)
|
||||
Glide.with(context as Context)
|
||||
.load(GlideUrl(cover))
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL).override(400)
|
||||
.apply(RequestOptions.bitmapTransform(BlurTransformation(2, 6)))
|
||||
.into(binding.notificationBannerImage)
|
||||
} else {
|
||||
binding.notificationBannerImage.setImageResource(R.drawable.linear_gradient_bg)
|
||||
}
|
||||
if (user) {
|
||||
binding.notificationCover.visibility = View.GONE
|
||||
binding.notificationCoverUserContainer.visibility = View.VISIBLE
|
||||
binding.notificationCoverUser.loadImage(notification.user?.avatar?.large)
|
||||
val height = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80f, context.resources.displayMetrics).toInt()
|
||||
binding.notificationBannerImage.layoutParams.height = height
|
||||
binding.notificationBannerGradient.layoutParams.height = height
|
||||
} else{
|
||||
binding.notificationCoverUser.visibility = View.VISIBLE
|
||||
binding.notificationCoverUserContainer.visibility = View.GONE
|
||||
binding.notificationCover.loadImage(notification.media?.coverImage?.large)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setBinding() {
|
||||
val notificationType: NotificationType =
|
||||
NotificationType.valueOf(notification.notificationType)
|
||||
binding.notificationText.text = NotificationItemBuilder.getContent(notification)
|
||||
binding.notificationDate.text = NotificationItemBuilder.getDateTime(notification.createdAt)
|
||||
binding.root.setOnClickListener { clickCallback(id, clickType) }
|
||||
|
||||
|
||||
when (notificationType) {
|
||||
NotificationType.ACTIVITY_MESSAGE -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.ACTIVITY_REPLY -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.FOLLOWING -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.ACTIVITY_MENTION -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.THREAD_COMMENT_MENTION -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.THREAD_SUBSCRIBED -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.THREAD_COMMENT_REPLY -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.AIRING -> {
|
||||
binding.notificationCover.loadImage(notification.media?.coverImage?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.media?.bannerImage)
|
||||
image()
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.MEDIA
|
||||
id = notification.media?.id ?: 0
|
||||
}
|
||||
NotificationType.ACTIVITY_LIKE -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.ACTIVITY_REPLY_LIKE -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.THREAD_LIKE -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.THREAD_COMMENT_LIKE -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.ACTIVITY_REPLY_SUBSCRIBED -> {
|
||||
binding.notificationCover.loadImage(notification.user?.avatar?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.user?.bannerImage)
|
||||
image(true)
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.USER
|
||||
id = notification.user?.id ?: 0
|
||||
}
|
||||
NotificationType.RELATED_MEDIA_ADDITION -> {
|
||||
binding.notificationCover.loadImage(notification.media?.coverImage?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.media?.bannerImage)
|
||||
image()
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.MEDIA
|
||||
id = notification.media?.id ?: 0
|
||||
}
|
||||
NotificationType.MEDIA_DATA_CHANGE -> {
|
||||
binding.notificationCover.loadImage(notification.media?.coverImage?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.media?.bannerImage)
|
||||
image()
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.MEDIA
|
||||
id = notification.media?.id ?: 0
|
||||
}
|
||||
NotificationType.MEDIA_MERGE -> {
|
||||
binding.notificationCover.loadImage(notification.media?.coverImage?.large)
|
||||
binding.notificationBannerImage.loadImage(notification.media?.bannerImage)
|
||||
image()
|
||||
clickType = NotificationActivity.Companion.NotificationClickType.MEDIA
|
||||
id = notification.media?.id ?: 0
|
||||
}
|
||||
|
|
|
@ -138,11 +138,33 @@ interface NotificationItemBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
fun getDateTime(time: Int): String {
|
||||
val date = Date(time * 1000L)
|
||||
val sdf = SimpleDateFormat("dd/MM/yyyy hh:mm a", Locale.getDefault())
|
||||
return sdf.format(date)
|
||||
}
|
||||
|
||||
fun getDateTime(timestamp: Int): String {
|
||||
|
||||
val targetDate = Date(timestamp * 1000L)
|
||||
|
||||
if (targetDate < Date(946684800000L)) { // January 1, 2000 (who want dates before that?)
|
||||
return ""
|
||||
}
|
||||
|
||||
val currentDate = Date()
|
||||
val difference = currentDate.time - targetDate.time
|
||||
|
||||
return when (val daysDifference = difference / (1000 * 60 * 60 * 24)) {
|
||||
0L -> {
|
||||
val hoursDifference = difference / (1000 * 60 * 60)
|
||||
val minutesDifference = (difference / (1000 * 60)) % 60
|
||||
|
||||
when {
|
||||
hoursDifference > 0 -> "$hoursDifference hour${if (hoursDifference > 1) "s" else ""} ago"
|
||||
minutesDifference > 0 -> "$minutesDifference minute${if (minutesDifference > 1) "s" else ""} ago"
|
||||
else -> "Just now"
|
||||
}
|
||||
}
|
||||
1L -> "1 day ago"
|
||||
in 2..6 -> "$daysDifference days ago"
|
||||
else -> SimpleDateFormat("dd MMM yyyy", Locale.getDefault()).format(targetDate)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue