()
user.favourites?.staff?.nodes?.forEach { i ->
- favStaff.add(Character(i.id, i.name.full, i.image.large, i.image.large, ""))
+ favStaff.add(Author(i.id, i.name.full, i.image.large , "" ))
}
if (favStaff.isEmpty()) {
binding.profileFavStaffContainer.visibility = View.GONE
}
- binding.profileFavStaffRecycler.adapter = CharacterAdapter(favStaff)
+ binding.profileFavStaffRecycler.adapter = AuthorAdapter(favStaff)
binding.profileFavStaffRecycler.layoutManager = LinearLayoutManager(
requireContext(),
LinearLayoutManager.HORIZONTAL,
@@ -184,21 +185,18 @@ class ProfileFragment() : Fragment() {
container: View,
recyclerView: RecyclerView,
progress: View,
- empty: View,
title: View
) {
container.visibility = View.VISIBLE
progress.visibility = View.VISIBLE
recyclerView.visibility = View.GONE
- empty.visibility = View.GONE
title.visibility = View.INVISIBLE
mode.observe(viewLifecycleOwner) {
recyclerView.visibility = View.GONE
- empty.visibility = View.GONE
if (it != null) {
if (it.isNotEmpty()) {
- recyclerView.adapter = MediaAdaptor(0, it, requireActivity())
+ recyclerView.adapter = MediaAdaptor(0, it, requireActivity(), fav=true)
recyclerView.layoutManager = LinearLayoutManager(
requireContext(),
LinearLayoutManager.HORIZONTAL,
@@ -209,7 +207,7 @@ class ProfileFragment() : Fragment() {
LayoutAnimationController(setSlideIn(), 0.25f)
} else {
- empty.visibility = View.VISIBLE
+ container.visibility = View.GONE
}
title.visibility = View.VISIBLE
title.startAnimation(setSlideUp())
@@ -218,7 +216,22 @@ class ProfileFragment() : Fragment() {
}
}
- private fun styled(html: String, backGroundColor: Int, textColor: Int): String {
+ private fun styled(html: String, backGroundColor: Int, textColor: Int): String { //istg anilist has the worst api
+ //remove some of the html entities
+ val step1 = html.replace(" ", " ")
+ .replace("&", "&")
+ .replace("<", "<")
+ .replace(">", ">")
+ .replace(""", "\"")
+ .replace("'", "'")
+ .replace("", "")
+ .replace("`", "")
+ .replace("~", "")
+
+ val step2 = step1.replace("(?s)___(.*?)___".toRegex(), "
$1
")
+ val step3 = step2.replace("(?s)__(.*?)__".toRegex(), "
$1
")
+
+
return """
@@ -236,6 +249,10 @@ class ProfileFragment() : Fragment() {
max-width: 100%;
height: auto; /* Maintain aspect ratio */
}
+ video {
+ max-width: 100%;
+ height: auto; /* Maintain aspect ratio */
+ }
a {
color: ${textColor.toCssColor()};
}
@@ -243,7 +260,7 @@ class ProfileFragment() : Fragment() {
- $html
+ $step3
""".trimIndent()
diff --git a/app/src/main/java/ani/dantotsu/profile/activity/ActivityItem.kt b/app/src/main/java/ani/dantotsu/profile/activity/ActivityItem.kt
new file mode 100644
index 00000000..f1ced201
--- /dev/null
+++ b/app/src/main/java/ani/dantotsu/profile/activity/ActivityItem.kt
@@ -0,0 +1,22 @@
+package ani.dantotsu.profile.activity
+
+import android.view.View
+import ani.dantotsu.R
+import ani.dantotsu.databinding.ItemNotificationBinding
+import com.xwray.groupie.viewbinding.BindableItem
+
+class ActivityItem(
+): BindableItem() {
+ private lateinit var binding: ItemNotificationBinding
+ override fun bind(viewBinding: ItemNotificationBinding, position: Int) {
+ binding = viewBinding
+ }
+
+ override fun getLayout(): Int {
+ return R.layout.item_notification
+ }
+
+ override fun initializeViewBinding(view: View): ItemNotificationBinding {
+ return ItemNotificationBinding.bind(view)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ani/dantotsu/profile/activity/NotificationActivity.kt b/app/src/main/java/ani/dantotsu/profile/activity/NotificationActivity.kt
new file mode 100644
index 00000000..a7ff26dc
--- /dev/null
+++ b/app/src/main/java/ani/dantotsu/profile/activity/NotificationActivity.kt
@@ -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 = 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 { 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
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt b/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt
new file mode 100644
index 00000000..31290be3
--- /dev/null
+++ b/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt
@@ -0,0 +1,184 @@
+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.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,
+ val clickCallback: (Int, NotificationActivity.Companion.NotificationClickType) -> Unit
+): BindableItem() {
+ private lateinit var binding: ItemNotificationBinding
+ private lateinit var clickType: NotificationActivity.Companion.NotificationClickType
+ private var id = 0
+ override fun bind(viewBinding: ItemNotificationBinding, position: Int) {
+ binding = viewBinding
+ setBinding()
+ }
+
+ override fun getLayout(): Int {
+ return R.layout.item_notification
+ }
+
+ override fun initializeViewBinding(view: View): ItemNotificationBinding {
+ 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)
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.ACTIVITY_REPLY -> {
+ binding.notificationCover.loadImage(notification.user?.avatar?.large)
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.FOLLOWING -> {
+ binding.notificationCover.loadImage(notification.user?.avatar?.large)
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.ACTIVITY_MENTION -> {
+ binding.notificationCover.loadImage(notification.user?.avatar?.large)
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.THREAD_COMMENT_MENTION -> {
+ binding.notificationCover.loadImage(notification.user?.avatar?.large)
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.THREAD_SUBSCRIBED -> {
+ binding.notificationCover.loadImage(notification.user?.avatar?.large)
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.THREAD_COMMENT_REPLY -> {
+ binding.notificationCover.loadImage(notification.user?.avatar?.large)
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.AIRING -> {
+ binding.notificationCover.loadImage(notification.media?.coverImage?.large)
+ image()
+ clickType = NotificationActivity.Companion.NotificationClickType.MEDIA
+ id = notification.media?.id ?: 0
+ }
+ NotificationType.ACTIVITY_LIKE -> {
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.ACTIVITY_REPLY_LIKE -> {
+ binding.notificationCover.loadImage(notification.user?.avatar?.large)
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.THREAD_LIKE -> {
+ binding.notificationCover.loadImage(notification.user?.avatar?.large)
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.THREAD_COMMENT_LIKE -> {
+ binding.notificationCover.loadImage(notification.user?.avatar?.large)
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.ACTIVITY_REPLY_SUBSCRIBED -> {
+ binding.notificationCover.loadImage(notification.user?.avatar?.large)
+ image(true)
+ clickType = NotificationActivity.Companion.NotificationClickType.USER
+ id = notification.user?.id ?: 0
+ }
+ NotificationType.RELATED_MEDIA_ADDITION -> {
+ binding.notificationCover.loadImage(notification.media?.coverImage?.large)
+ image()
+ clickType = NotificationActivity.Companion.NotificationClickType.MEDIA
+ id = notification.media?.id ?: 0
+ }
+ NotificationType.MEDIA_DATA_CHANGE -> {
+ binding.notificationCover.loadImage(notification.media?.coverImage?.large)
+ image()
+ clickType = NotificationActivity.Companion.NotificationClickType.MEDIA
+ id = notification.media?.id ?: 0
+ }
+ NotificationType.MEDIA_MERGE -> {
+ binding.notificationCover.loadImage(notification.media?.coverImage?.large)
+ image()
+ clickType = NotificationActivity.Companion.NotificationClickType.MEDIA
+ id = notification.media?.id ?: 0
+ }
+ NotificationType.MEDIA_DELETION -> {
+ binding.notificationCover.visibility = View.GONE
+ clickType = NotificationActivity.Companion.NotificationClickType.UNDEFINED
+ id = 0
+ }
+ }
+ }
+
+}
\ 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/NotificationItemBuilder.kt
new file mode 100644
index 00000000..c894f65a
--- /dev/null
+++ b/app/src/main/java/ani/dantotsu/profile/activity/NotificationItemBuilder.kt
@@ -0,0 +1,170 @@
+package ani.dantotsu.profile.activity
+
+import ani.dantotsu.connections.anilist.api.Notification
+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 {
+
+ companion object {
+ fun getContent(notification: Notification): String {
+ val notificationType: NotificationType =
+ NotificationType.valueOf(notification.notificationType)
+ return when (notificationType) {
+ NotificationType.ACTIVITY_MESSAGE -> {
+ "${notification.user?.name} sent you a message"
+ }
+
+ NotificationType.ACTIVITY_REPLY -> {
+ "${notification.user?.name} replied to your activity"
+ }
+
+ NotificationType.FOLLOWING -> {
+ "${notification.user?.name} followed you"
+ }
+
+ NotificationType.ACTIVITY_MENTION -> {
+ "${notification.user?.name} mentioned you in their activity"
+ }
+
+ NotificationType.THREAD_COMMENT_MENTION -> {
+ "${notification.user?.name} mentioned you in a forum comment"
+ }
+
+ NotificationType.THREAD_SUBSCRIBED -> {
+ "${notification.user?.name} commented in one of your subscribed forum threads"
+ }
+
+ NotificationType.THREAD_COMMENT_REPLY -> {
+ "${notification.user?.name} replied to your forum comment"
+ }
+
+ NotificationType.AIRING -> {
+ "Episode ${notification.episode} of ${notification.media?.title?.english ?: notification.media?.title?.romaji} has aired"
+ }
+
+ NotificationType.ACTIVITY_LIKE -> {
+ "${notification.user?.name} liked your activity"
+ }
+
+ NotificationType.ACTIVITY_REPLY_LIKE -> {
+ "${notification.user?.name} liked your reply"
+ }
+
+ NotificationType.THREAD_LIKE -> {
+ "${notification.user?.name} liked your forum thread"
+ }
+
+ NotificationType.THREAD_COMMENT_LIKE -> {
+ "${notification.user?.name} liked your forum comment"
+ }
+
+ NotificationType.ACTIVITY_REPLY_SUBSCRIBED -> {
+ "${notification.user?.name} replied to activity you have also replied to"
+ }
+
+ NotificationType.RELATED_MEDIA_ADDITION -> {
+ "${notification.media?.title?.english ?: notification.media?.title?.romaji} has been added to the site"
+ }
+
+ NotificationType.MEDIA_DATA_CHANGE -> {
+ "${notification.media?.title?.english ?: notification.media?.title?.romaji} has had a data change: ${notification.reason}"
+ }
+
+ NotificationType.MEDIA_MERGE -> {
+ "${notification.deletedMediaTitles?.joinToString(", ")} have been merged into ${notification.media?.title?.english ?: notification.media?.title?.romaji}"
+ }
+
+ NotificationType.MEDIA_DELETION -> {
+ "${notification.deletedMediaTitle} has been deleted from the site"
+ }
+ }
+ }
+
+
+ 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)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsDialogFragment.kt b/app/src/main/java/ani/dantotsu/settings/SettingsDialogFragment.kt
index dfbe5be6..8a1c9be4 100644
--- a/app/src/main/java/ani/dantotsu/settings/SettingsDialogFragment.kt
+++ b/app/src/main/java/ani/dantotsu/settings/SettingsDialogFragment.kt
@@ -13,7 +13,6 @@ import ani.dantotsu.MainActivity
import ani.dantotsu.profile.ProfileActivity
import ani.dantotsu.R
import ani.dantotsu.connections.anilist.Anilist
-import ani.dantotsu.currContext
import ani.dantotsu.databinding.BottomSheetSettingsBinding
import ani.dantotsu.download.anime.OfflineAnimeFragment
import ani.dantotsu.download.manga.OfflineMangaFragment
@@ -24,9 +23,8 @@ import ani.dantotsu.home.MangaFragment
import ani.dantotsu.home.NoInternet
import ani.dantotsu.incognitoNotification
import ani.dantotsu.loadImage
+import ani.dantotsu.profile.activity.NotificationActivity
import ani.dantotsu.offline.OfflineFragment
-import ani.dantotsu.openLinkInBrowser
-import ani.dantotsu.others.imagesearch.ImageSearchActivity
import ani.dantotsu.setSafeOnClickListener
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
@@ -79,32 +77,35 @@ class SettingsDialogFragment : BottomSheetDialogFragment() {
Anilist.loginIntent(requireActivity())
}
}
+ binding.settingsNotificationCount.visibility = if (Anilist.unreadNotificationCount > 0) View.VISIBLE else View.GONE
+ binding.settingsNotificationCount.text = Anilist.unreadNotificationCount.toString()
binding.settingsUserAvatar.setOnClickListener{
ContextCompat.startActivity(
- currContext()!!, Intent(currContext()!!, ProfileActivity::class.java)
+ requireContext(), Intent(requireContext(), ProfileActivity::class.java)
.putExtra("userId", Anilist.userid), null
)
}
- binding.settingsIncognito.isChecked =
- PrefManager.getVal(PrefName.Incognito)
+ binding.settingsIncognito.isChecked = PrefManager.getVal(PrefName.Incognito)
binding.settingsIncognito.setOnCheckedChangeListener { _, isChecked ->
PrefManager.setVal(PrefName.Incognito, isChecked)
incognitoNotification(requireContext())
}
+
binding.settingsExtensionSettings.setSafeOnClickListener {
startActivity(Intent(activity, ExtensionsActivity::class.java))
dismiss()
}
+
binding.settingsSettings.setSafeOnClickListener {
startActivity(Intent(activity, SettingsActivity::class.java))
dismiss()
}
- binding.settingsAnilistSettings.setOnClickListener {
- openLinkInBrowser("https://anilist.co/settings/lists")
+
+ binding.settingsNotification.setOnClickListener {
+ startActivity(Intent(activity, NotificationActivity::class.java))
dismiss()
}
-
binding.settingsDownloads.isChecked = PrefManager.getVal(PrefName.OfflineMode)
binding.settingsDownloads.setOnCheckedChangeListener { _, isChecked ->
Timer().schedule(300) {
diff --git a/app/src/main/res/drawable/inbox_empty.xml b/app/src/main/res/drawable/inbox_empty.xml
new file mode 100644
index 00000000..bb6540aa
--- /dev/null
+++ b/app/src/main/res/drawable/inbox_empty.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/inbox_filled.xml b/app/src/main/res/drawable/inbox_filled.xml
new file mode 100644
index 00000000..08ad4bf1
--- /dev/null
+++ b/app/src/main/res/drawable/inbox_filled.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/notification_circle.xml b/app/src/main/res/drawable/notification_circle.xml
new file mode 100644
index 00000000..d864d738
--- /dev/null
+++ b/app/src/main/res/drawable/notification_circle.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_activity.xml b/app/src/main/res/layout/activity_activity.xml
new file mode 100644
index 00000000..584c5588
--- /dev/null
+++ b/app/src/main/res/layout/activity_activity.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_follow.xml b/app/src/main/res/layout/activity_follow.xml
index 7cd44c3f..ce25a262 100644
--- a/app/src/main/res/layout/activity_follow.xml
+++ b/app/src/main/res/layout/activity_follow.xml
@@ -15,6 +15,7 @@
android:visibility="gone" />
@@ -33,11 +34,11 @@
android:id="@+id/listTitle"
android:layout_width="wrap_content"
android:layout_height="48dp"
- android:layout_marginStart="44dp"
android:layout_gravity="center_vertical"
- android:gravity="center|start"
+ android:layout_marginStart="44dp"
android:ellipsize="end"
android:fontFamily="@font/poppins_bold"
+ android:gravity="center|start"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"
android:textColor="?attr/colorOnBackground"
@@ -87,12 +88,11 @@
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml
index 71011c98..1583039d 100644
--- a/app/src/main/res/layout/activity_profile.xml
+++ b/app/src/main/res/layout/activity_profile.xml
@@ -58,8 +58,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
- android:orientation="vertical"
- tools:visibility="visible">
+ android:layout_marginBottom="8dp"
+ android:orientation="vertical">
+ app:strokeColor="?attr/colorSecondaryContainer"
+ tools:ignore="HardcodedText,SpeakableTextPresentCheck" />
-
-
+ android:orientation="horizontal">
+
+
+
+
+
-
+ android:layout_height="match_parent"
+ android:background="@drawable/bottom_sheet_background">
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ android:layout_gravity="bottom"
+ android:orientation="horizontal"
+ android:padding="16dp">
-
-
-
-
-
-
-
-
-
+ android:layout_marginTop="4dp"
+ android:backgroundTint="@color/nav_bg_inv"
+ app:cardCornerRadius="26dp">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ android:layout_height="match_parent"
+ android:layout_marginEnd="58dp"
+ android:orientation="vertical">
-
-
+
-
+
-
-
-
-
-
-
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_feed.xml b/app/src/main/res/layout/fragment_feed.xml
new file mode 100644
index 00000000..77d9ef65
--- /dev/null
+++ b/app/src/main/res/layout/fragment_feed.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index f8279ae2..31cea274 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -135,23 +135,43 @@
-
+
-
+ android:layout_marginTop="4dp"
+ android:backgroundTint="@color/nav_bg_inv"
+ app:cardCornerRadius="26dp">
-
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_notifs.xml b/app/src/main/res/layout/fragment_notifs.xml
new file mode 100644
index 00000000..77d9ef65
--- /dev/null
+++ b/app/src/main/res/layout/fragment_notifs.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml
index 639b3f7e..687423b0 100644
--- a/app/src/main/res/layout/fragment_profile.xml
+++ b/app/src/main/res/layout/fragment_profile.xml
@@ -143,10 +143,11 @@
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="32dp"
- android:padding="8dp"
android:fontFamily="@font/poppins_bold"
android:text="@string/stats"
- android:textSize="18sp"/>
+ android:padding="8dp"
+ android:textSize="18sp"
+ tools:ignore="HardcodedText" />
+ android:orientation="vertical"
+ tools:layout_height="wrap_content">
@@ -365,8 +367,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:visibility="gone"
- tools:visibility="visible">
+ android:visibility="gone">
-
-
-
-
-
-
-
-
+ android:layout_height="wrap_content">
-
-
-
-
-
-
-
-
-
+ android:layout_height="wrap_content">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_anime_page.xml b/app/src/main/res/layout/item_anime_page.xml
index f211e3f3..52b064dc 100644
--- a/app/src/main/res/layout/item_anime_page.xml
+++ b/app/src/main/res/layout/item_anime_page.xml
@@ -59,26 +59,43 @@
tools:ignore="LabelFor,TextContrastCheck" />
-
+
-
+ android:layout_marginTop="4dp"
+ android:backgroundTint="@color/nav_bg_inv"
+ app:cardCornerRadius="26dp">
-
+
+
+
+
+
+ tools:text="SOURCE" />
diff --git a/app/src/main/res/layout/item_follower.xml b/app/src/main/res/layout/item_follower.xml
index 15fa5a28..e26ac3a5 100644
--- a/app/src/main/res/layout/item_follower.xml
+++ b/app/src/main/res/layout/item_follower.xml
@@ -1,49 +1,53 @@
+
+ app:cardCornerRadius="24dp">
+
-
+
+ tools:ignore="ContentDescription,ImageContrastCheck"
+ tools:tint="@color/transparent" />
diff --git a/app/src/main/res/layout/item_manga_page.xml b/app/src/main/res/layout/item_manga_page.xml
index 12918809..d3e94aeb 100644
--- a/app/src/main/res/layout/item_manga_page.xml
+++ b/app/src/main/res/layout/item_manga_page.xml
@@ -61,25 +61,43 @@
tools:ignore="LabelFor,TextContrastCheck" />
-
+
-
+ android:layout_marginTop="4dp"
+ android:backgroundTint="@color/nav_bg_inv"
+ app:cardCornerRadius="26dp">
-
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_media_compact.xml b/app/src/main/res/layout/item_media_compact.xml
index 389b0ae9..34b5fbe7 100644
--- a/app/src/main/res/layout/item_media_compact.xml
+++ b/app/src/main/res/layout/item_media_compact.xml
@@ -94,9 +94,11 @@
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginBottom="4dp"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="24dp"
android:gravity="center"
- android:orientation="horizontal"
android:visibility="gone"
+ android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
+ tools:text="Relation" />
@@ -149,6 +151,7 @@
tools:text="@string/get_recommendations" />
diff --git a/app/src/main/res/layout/item_media_large.xml b/app/src/main/res/layout/item_media_large.xml
index a7205c81..4c57323c 100644
--- a/app/src/main/res/layout/item_media_large.xml
+++ b/app/src/main/res/layout/item_media_large.xml
@@ -9,7 +9,6 @@
app:cardBackgroundColor="@color/nav_bg"
app:cardCornerRadius="28dp">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 11b0e05b..89cc8d51 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -123,6 +123,7 @@
Synopsis
Characters
Relations
+ Staff
Roles
Details