diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 43c9c29f..c42fee0d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -194,7 +194,7 @@
android:label="Inbox Activity"
android:parentActivityName=".MainActivity" />
- private lateinit var subscriptionStore: List
- private var adapter: GroupieAdapter = GroupieAdapter()
- private var notificationList: List = emptyList()
- val filters = ArrayList()
- private var currentPage: Int = 1
- private var hasNextPage: Boolean = true
-
- @SuppressLint("ClickableViewAccessibility")
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- ThemeManager(this).applyTheme()
- initActivity(this)
- binding = ActivityFollowBinding.inflate(layoutInflater)
- setContentView(binding.root)
- binding.listTitle.text = getString(R.string.notifications)
- binding.listToolbar.updateLayoutParams {
- topMargin = statusBarHeight
- }
- binding.listFrameLayout.updateLayoutParams {
- bottomMargin = navBarHeight
- }
- 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 {
- onBackPressedDispatcher.onBackPressed()
- }
- binding.listProgressBar.visibility = ViewGroup.VISIBLE
- commentStore = PrefManager.getNullableVal>(
- PrefName.CommentNotificationStore,
- null
- ) ?: listOf()
- subscriptionStore = PrefManager.getNullableVal>(
- PrefName.SubscriptionNotificationStore,
- null
- ) ?: listOf()
-
- binding.followFilterButton.setOnClickListener {
- val dialogView = LayoutInflater.from(currContext()).inflate(R.layout.custom_dialog_layout, null)
- val checkboxContainer = dialogView.findViewById(R.id.checkboxContainer)
- val tickAllButton = dialogView.findViewById(R.id.toggleButton)
- val title = dialogView.findViewById(R.id.scantitle)
- title.visibility = ViewGroup.GONE
- fun getToggleImageResource(container: ViewGroup): Int {
- var allChecked = true
- var allUnchecked = true
-
- for (i in 0 until container.childCount) {
- val checkBox = container.getChildAt(i) as CheckBox
- if (!checkBox.isChecked) {
- allChecked = false
- } else {
- allUnchecked = false
- }
- }
- return when {
- allChecked -> R.drawable.untick_all_boxes
- allUnchecked -> R.drawable.tick_all_boxes
- else -> R.drawable.invert_all_boxes
- }
- }
- NotificationType.entries.forEach { notificationType ->
- val checkBox = CheckBox(currContext())
- checkBox.text = notificationType.toFormattedString()
- checkBox.isChecked = !filters.contains(notificationType.value.fromFormattedString())
- checkBox.setOnCheckedChangeListener { _, isChecked ->
- if (isChecked) {
- filters.remove(notificationType.value.fromFormattedString())
- } else {
- filters.add(notificationType.value.fromFormattedString())
- }
- tickAllButton.setImageResource(getToggleImageResource(checkboxContainer))
- }
- checkboxContainer.addView(checkBox)
- }
- tickAllButton.setImageResource(getToggleImageResource(checkboxContainer))
- tickAllButton.setOnClickListener {
- for (i in 0 until checkboxContainer.childCount) {
- val checkBox = checkboxContainer.getChildAt(i) as CheckBox
- checkBox.isChecked = !checkBox.isChecked
- }
-
- tickAllButton.setImageResource(getToggleImageResource(checkboxContainer))
- }
- val alertD = AlertDialog.Builder(this, R.style.MyPopup)
- alertD.setTitle("Filter")
- alertD.setView(dialogView)
- alertD.setPositiveButton("OK") { _, _ ->
- currentPage = 1
- hasNextPage = true
- adapter.clear()
- adapter.addAll(notificationList.filter { notification ->
- !filters.contains(notification.notificationType)
- }.map {
- NotificationItem(
- it,
- ::onNotificationClick
- )
- })
- loadPage(-1) {
- binding.followRefresh.visibility = ViewGroup.GONE
- }
- }
- alertD.setNegativeButton("Cancel") { _, _ -> }
- val dialog = alertD.show()
- dialog.window?.setDimAmount(0.8f)
- }
-
- val activityId = intent.getIntExtra("activityId", -1)
- lifecycleScope.launch {
- loadPage(activityId) {
- binding.listProgressBar.visibility = ViewGroup.GONE
- }
- withContext(Dispatchers.Main) {
- binding.listProgressBar.visibility = ViewGroup.GONE
- binding.listRecyclerView.setOnTouchListener { _, event ->
- if (event?.action == MotionEvent.ACTION_UP) {
- if (hasNextPage && !binding.listRecyclerView.canScrollVertically(1) && !binding.followRefresh.isVisible
- && binding.listRecyclerView.adapter!!.itemCount != 0 &&
- (binding.listRecyclerView.layoutManager as LinearLayoutManager).findLastVisibleItemPosition() == (binding.listRecyclerView.adapter!!.itemCount - 1)
- ) {
- binding.followRefresh.visibility = ViewGroup.VISIBLE
- loadPage(-1) {
- binding.followRefresh.visibility = ViewGroup.GONE
- }
- }
- }
- false
- }
-
- binding.followSwipeRefresh.setOnRefreshListener {
- currentPage = 1
- hasNextPage = true
- adapter.clear()
- notificationList = emptyList()
- loadPage(-1) {
- binding.followSwipeRefresh.isRefreshing = false
- }
- }
- }
- }
- }
-
- private fun loadPage(activityId: Int, onFinish: () -> Unit = {}) {
- lifecycleScope.launch(Dispatchers.IO) {
- val resetNotification = activityId == -1
- val res = Anilist.query.getNotifications(
- Anilist.userid ?: PrefManager.getVal(PrefName.AnilistUserId).toIntOrNull()
- ?: 0, currentPage, resetNotification = resetNotification
- )
- withContext(Dispatchers.Main) {
- val newNotifications: MutableList = mutableListOf()
- res?.data?.page?.notifications?.let { notifications ->
- Logger.log("Notifications: $notifications")
- newNotifications += if (activityId != -1) {
- notifications.filter { it.id == activityId }
- } else {
- notifications
- }.toMutableList()
- }
- if (activityId == -1) {
- val furthestTime = newNotifications.minOfOrNull { it.createdAt } ?: 0
- commentStore.forEach {
- if ((it.time > furthestTime * 1000L || !hasNextPage) && notificationList.none { notification ->
- notification.commentId == it.commentId && notification.createdAt == (it.time / 1000L).toInt()
- }) {
- val notification = Notification(
- it.type.toString(),
- System.currentTimeMillis().toInt(),
- commentId = it.commentId,
- notificationType = it.type.toString(),
- mediaId = it.mediaId,
- context = it.title + "\n" + it.content,
- createdAt = (it.time / 1000L).toInt(),
- )
- newNotifications += notification
- }
- }
- subscriptionStore.forEach {
- if ((it.time > furthestTime * 1000L || !hasNextPage) && notificationList.none { notification ->
- notification.mediaId == it.mediaId && notification.createdAt == (it.time / 1000L).toInt()
- }) {
- val notification = Notification(
- it.type,
- System.currentTimeMillis().toInt(),
- commentId = it.mediaId,
- mediaId = it.mediaId,
- notificationType = it.type,
- context = it.title + ": " + it.content,
- createdAt = (it.time / 1000L).toInt(),
- image = it.image,
- banner = it.banner ?: it.image
- )
- newNotifications += notification
- }
- }
- newNotifications.sortByDescending { it.createdAt }
- }
-
- notificationList += newNotifications
- adapter.addAll(newNotifications.filter { notification ->
- !filters.contains(notification.notificationType)
- }.map {
- NotificationItem(
- it,
- ::onNotificationClick
- )
- })
- currentPage = res?.data?.page?.pageInfo?.currentPage?.plus(1) ?: 1
- hasNextPage = res?.data?.page?.pageInfo?.hasNextPage ?: false
- binding.followSwipeRefresh.isRefreshing = false
- onFinish()
- }
- }
- }
-
- private fun onNotificationClick(id: Int, optional: 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.ACTIVITY -> {
- ContextCompat.startActivity(
- this, Intent(this, FeedActivity::class.java)
- .putExtra("activityId", id), null
- )
- }
-
- NotificationClickType.COMMENT -> {
- ContextCompat.startActivity(
- this, Intent(this, MediaDetailsActivity::class.java)
- .putExtra("FRAGMENT_TO_LOAD", "COMMENTS")
- .putExtra("mediaId", id)
- .putExtra("commentId", optional ?: -1),
- null
- )
-
- }
-
- NotificationClickType.UNDEFINED -> {
- // Do nothing
- }
- }
- }
-
- companion object {
- enum class NotificationClickType {
- USER, MEDIA, ACTIVITY, COMMENT, UNDEFINED
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/ani/dantotsu/profile/notification/NotificationActivity.kt b/app/src/main/java/ani/dantotsu/profile/notification/NotificationActivity.kt
new file mode 100644
index 00000000..8af2cf24
--- /dev/null
+++ b/app/src/main/java/ani/dantotsu/profile/notification/NotificationActivity.kt
@@ -0,0 +1,94 @@
+package ani.dantotsu.profile.notification
+
+import android.os.Bundle
+import android.view.ViewGroup
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.updateLayoutParams
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
+import androidx.lifecycle.Lifecycle
+import androidx.viewpager2.adapter.FragmentStateAdapter
+import androidx.viewpager2.widget.ViewPager2
+import ani.dantotsu.R
+import ani.dantotsu.databinding.ActivityNotificationBinding
+import ani.dantotsu.initActivity
+import ani.dantotsu.navBarHeight
+import ani.dantotsu.statusBarHeight
+import ani.dantotsu.themes.ThemeManager
+import nl.joery.animatedbottombar.AnimatedBottomBar
+
+class NotificationActivity : AppCompatActivity() {
+ private lateinit var binding: ActivityNotificationBinding
+ private var selected: Int = 0
+ lateinit var navBar: AnimatedBottomBar
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ ThemeManager(this).applyTheme()
+ initActivity(this)
+ binding = ActivityNotificationBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ binding.notificationTitle.text = getString(R.string.notifications)
+ binding.notificationToolbar.updateLayoutParams {
+ topMargin = statusBarHeight
+ }
+ navBar = binding.notificationNavBar
+ binding.root.updateLayoutParams {
+ bottomMargin = navBarHeight
+ }
+ val mediaTab = navBar.createTab(R.drawable.ic_round_movie_filter_24, "Media")
+ val userTab = navBar.createTab(R.drawable.ic_round_person_24, "User")
+ val subscriptionTab = navBar.createTab(R.drawable.ic_round_notifications_active_24, "Subscriptions")
+ val commentTab = navBar.createTab(R.drawable.ic_round_comment_24, "Comments")
+ navBar.addTab(mediaTab)
+ navBar.addTab(userTab)
+ navBar.addTab(subscriptionTab)
+ navBar.addTab(commentTab)
+ binding.notificationBack.setOnClickListener {
+ onBackPressedDispatcher.onBackPressed()
+ }
+ val getOne = intent.getIntExtra("activityId", -1)
+ binding.notificationViewPager.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle, getOne)
+ binding.notificationViewPager.setOffscreenPageLimit(4)
+ binding.notificationViewPager.setCurrentItem(selected, false)
+ binding.notificationViewPager
+ navBar.selectTabAt(selected)
+ navBar.setOnTabSelectListener(object : AnimatedBottomBar.OnTabSelectListener {
+ override fun onTabSelected(
+ lastIndex: Int,
+ lastTab: AnimatedBottomBar.Tab?,
+ newIndex: Int,
+ newTab: AnimatedBottomBar.Tab
+ ) {
+ selected = newIndex
+ binding.notificationViewPager.setCurrentItem(selected, true)
+ }
+ })
+ binding.notificationViewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
+ override fun onPageSelected(position: Int) {
+ super.onPageSelected(position)
+ navBar.selectTabAt(position)
+ }
+ })
+ }
+ override fun onResume() {
+ if (this::navBar.isInitialized) {
+ navBar.selectTabAt(selected)
+ }
+ super.onResume()
+ }
+ private class ViewPagerAdapter(
+ fragmentManager: FragmentManager,
+ lifecycle: Lifecycle,
+ val id: Int = -1
+ ) : FragmentStateAdapter(fragmentManager, lifecycle) {
+ override fun getItemCount(): Int = 4
+
+ override fun createFragment(position: Int): Fragment = when (position) {
+ 0 -> NotificationFragment(if (id != -1) "getOne" else "media", id)
+ 1 -> NotificationFragment("user")
+ 2 -> NotificationFragment("subscription")
+ 3 -> NotificationFragment("comment")
+ else -> NotificationFragment("media")
+ }
+ }
+}
diff --git a/app/src/main/java/ani/dantotsu/profile/notification/NotificationFragment.kt b/app/src/main/java/ani/dantotsu/profile/notification/NotificationFragment.kt
new file mode 100644
index 00000000..c6494b9d
--- /dev/null
+++ b/app/src/main/java/ani/dantotsu/profile/notification/NotificationFragment.kt
@@ -0,0 +1,238 @@
+package ani.dantotsu.profile.notification
+
+import android.content.Intent
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.core.content.ContextCompat
+import androidx.core.view.isVisible
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.lifecycleScope
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import ani.dantotsu.R
+import ani.dantotsu.connections.anilist.Anilist
+import ani.dantotsu.connections.anilist.api.Notification
+import ani.dantotsu.databinding.FragmentNotificationsBinding
+import ani.dantotsu.media.MediaDetailsActivity
+import ani.dantotsu.notifications.comment.CommentStore
+import ani.dantotsu.notifications.subscription.SubscriptionStore
+import ani.dantotsu.profile.ProfileActivity
+import ani.dantotsu.profile.activity.FeedActivity
+import ani.dantotsu.setBaseline
+import ani.dantotsu.settings.saving.PrefManager
+import ani.dantotsu.settings.saving.PrefName
+import com.xwray.groupie.GroupieAdapter
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+class NotificationFragment(val type: String, private val getID: Int = -1) : Fragment() {
+ private lateinit var binding: FragmentNotificationsBinding
+ private var adapter: GroupieAdapter = GroupieAdapter()
+ private var currentPage = 1
+ private var hasNextPage = false
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ binding = FragmentNotificationsBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val navbar = (activity as NotificationActivity).navBar
+ binding.listRecyclerView.setBaseline(navbar)
+ binding.listRecyclerView.adapter = adapter
+ binding.listRecyclerView.layoutManager = LinearLayoutManager(context)
+ binding.emptyTextView.text = getString(R.string.no_notifications)
+ lifecycleScope.launch {
+ val list = when (type) {
+ "getOne" -> getOne(getID)
+ "media" -> getMediaUpdates()
+ "user" -> getUserUpdates()
+ "subscription" -> getSubscriptions()
+ "comment" -> getComments()
+ else -> listOf()
+ }
+ adapter.addAll(list.map { NotificationItem(it, ::onClick) })
+ if (adapter.itemCount != 0) {
+ binding.listProgressBar.isVisible = false
+ }else{
+ binding.listProgressBar.isVisible = false
+ binding.emptyTextView.isVisible = true
+ }
+ }
+ binding.followSwipeRefresh.setOnRefreshListener {
+ lifecycleScope.launch {
+ adapter.clear()
+ currentPage = 1
+ val list = when (type) {
+ "getOne" -> getOne(getID)
+ "media" -> getMediaUpdates()
+ "user" -> getUserUpdates()
+ "subscription" -> getSubscriptions()
+ "comment" -> getComments()
+ else -> listOf()
+ }
+ adapter.addAll(list.map { NotificationItem(it, ::onClick) })
+ binding.followSwipeRefresh.isRefreshing = false
+ }
+ }
+ binding.listRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+ if (shouldLoadMore()) {
+ lifecycleScope.launch {
+ val list = when (type) {
+ "media" -> getMediaUpdates()
+ "user" -> getUserUpdates()
+ else -> listOf()
+ }
+ binding.followRefresh.visibility = View.VISIBLE
+ adapter.addAll(list.map {
+ NotificationItem(
+ it,
+ ::onClick
+ )
+ })
+ binding.followRefresh.visibility = View.GONE
+ }
+ }
+ }
+ })
+
+ }
+
+ private suspend fun getNotificationsFiltered(filter: (Notification) -> Boolean): List {
+ val userId = Anilist.userid ?: PrefManager.getVal(PrefName.AnilistUserId).toIntOrNull() ?: 0
+ val res = withContext(Dispatchers.IO) {
+ Anilist.query.getNotifications(userId, currentPage)
+ }
+ currentPage = res?.data?.page?.pageInfo?.currentPage?.plus(1) ?: 1
+ hasNextPage = res?.data?.page?.pageInfo?.hasNextPage ?: false
+ return res?.data?.page?.notifications?.filter(filter) ?: listOf()
+ }
+
+ private suspend fun getMediaUpdates(): List {
+ return getNotificationsFiltered { it.media != null }
+ }
+
+ private suspend fun getUserUpdates(): List {
+ return getNotificationsFiltered { it.media == null }
+ }
+
+ private suspend fun getOne(id: Int): List {
+ return getNotificationsFiltered { it.id == id }
+ }
+
+ private fun getSubscriptions(): List {
+ val list = PrefManager.getNullableVal>(
+ PrefName.SubscriptionNotificationStore,
+ null
+ ) ?: listOf()
+ return list.sortedByDescending{ (it.time / 1000L).toInt() }
+ .filter{ it.image != null }.map {
+ Notification(
+ it.type,
+ System.currentTimeMillis().toInt(),
+ commentId = it.mediaId,
+ mediaId = it.mediaId,
+ notificationType = it.type,
+ context = it.title + ": " + it.content,
+ createdAt = (it.time / 1000L).toInt(),
+ image = it.image,
+ banner = it.banner ?: it.image
+ )
+ }
+ }
+
+ private fun getComments(): List {
+ val list = PrefManager.getNullableVal>(
+ PrefName.CommentNotificationStore,
+ null
+ ) ?: listOf()
+ return list
+ .sortedByDescending {(it.time / 1000L).toInt()}
+ .map {
+ Notification(
+ it.type.toString(),
+ System.currentTimeMillis().toInt(),
+ commentId = it.commentId,
+ notificationType = it.type.toString(),
+ mediaId = it.mediaId,
+ context = it.title + "\n" + it.content,
+ createdAt = (it.time / 1000L).toInt(),
+ )
+ }
+ }
+
+ private fun shouldLoadMore(): Boolean {
+ val layoutManager = binding.listRecyclerView.layoutManager as LinearLayoutManager
+ val adapter = binding.listRecyclerView.adapter
+
+ return hasNextPage && !binding.followRefresh.isVisible && adapter?.itemCount != 0 &&
+ layoutManager.findLastVisibleItemPosition() == (adapter!!.itemCount - 1) &&
+ !binding.listRecyclerView.canScrollVertically(1)
+ }
+
+ fun onClick(
+ id: Int,
+ optional: Int?,
+ type: NotificationClickType
+ ) {
+ when (type) {
+ NotificationClickType.USER -> {
+ ContextCompat.startActivity(
+ requireContext(), Intent( requireContext(), ProfileActivity::class.java)
+ .putExtra("userId", id), null
+ )
+ }
+
+ NotificationClickType.MEDIA -> {
+ ContextCompat.startActivity(
+ requireContext(), Intent( requireContext(), MediaDetailsActivity::class.java)
+ .putExtra("mediaId", id), null
+ )
+ }
+
+ NotificationClickType.ACTIVITY -> {
+ ContextCompat.startActivity(
+ requireContext(), Intent( requireContext(), FeedActivity::class.java)
+ .putExtra("activityId", id), null
+ )
+ }
+
+ NotificationClickType.COMMENT -> {
+ ContextCompat.startActivity(
+ requireContext(), Intent( requireContext(), MediaDetailsActivity::class.java)
+ .putExtra("FRAGMENT_TO_LOAD", "COMMENTS")
+ .putExtra("mediaId", id)
+ .putExtra("commentId", optional ?: -1),
+ null
+ )
+
+ }
+ NotificationClickType.UNDEFINED -> {
+ // Do nothing
+ }
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ if (this::binding.isInitialized) {
+ binding.root.requestLayout()
+ binding.root.setBaseline((activity as NotificationActivity).navBar)
+ }
+ }
+ companion object {
+ enum class NotificationClickType {
+ USER, MEDIA, ACTIVITY, COMMENT, 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/notification/NotificationItem.kt
similarity index 98%
rename from app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt
rename to app/src/main/java/ani/dantotsu/profile/notification/NotificationItem.kt
index d0e932d9..f51225ea 100644
--- a/app/src/main/java/ani/dantotsu/profile/activity/NotificationItem.kt
+++ b/app/src/main/java/ani/dantotsu/profile/notification/NotificationItem.kt
@@ -1,4 +1,4 @@
-package ani.dantotsu.profile.activity
+package ani.dantotsu.profile.notification
import android.view.View
import android.view.ViewGroup
@@ -8,7 +8,8 @@ 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.profile.activity.NotificationActivity.Companion.NotificationClickType
+import ani.dantotsu.profile.notification.NotificationFragment.Companion.NotificationClickType
+import ani.dantotsu.profile.activity.ActivityItemBuilder
import ani.dantotsu.setAnimation
import ani.dantotsu.toPx
import com.xwray.groupie.viewbinding.BindableItem
diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsDialogFragment.kt b/app/src/main/java/ani/dantotsu/settings/SettingsDialogFragment.kt
index 70da38d4..1072d742 100644
--- a/app/src/main/java/ani/dantotsu/settings/SettingsDialogFragment.kt
+++ b/app/src/main/java/ani/dantotsu/settings/SettingsDialogFragment.kt
@@ -1,6 +1,5 @@
package ani.dantotsu.settings
-import android.app.AlertDialog
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
@@ -16,7 +15,6 @@ import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.databinding.BottomSheetSettingsBinding
import ani.dantotsu.download.anime.OfflineAnimeFragment
import ani.dantotsu.download.manga.OfflineMangaFragment
-import ani.dantotsu.getAppString
import ani.dantotsu.getThemeColor
import ani.dantotsu.home.AnimeFragment
import ani.dantotsu.home.HomeFragment
@@ -28,7 +26,7 @@ import ani.dantotsu.loadImage
import ani.dantotsu.offline.OfflineFragment
import ani.dantotsu.profile.ProfileActivity
import ani.dantotsu.profile.activity.FeedActivity
-import ani.dantotsu.profile.activity.NotificationActivity
+import ani.dantotsu.profile.notification.NotificationActivity
import ani.dantotsu.setSafeOnClickListener
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
diff --git a/app/src/main/java/ani/dantotsu/util/AlertDialogBuilder.kt b/app/src/main/java/ani/dantotsu/util/AlertDialogBuilder.kt
index d2ab6601..14e71432 100644
--- a/app/src/main/java/ani/dantotsu/util/AlertDialogBuilder.kt
+++ b/app/src/main/java/ani/dantotsu/util/AlertDialogBuilder.kt
@@ -135,6 +135,7 @@ class AlertDialogBuilder(private val context: Context) {
} else if (checkedItems != null && onItemsSelected != null) {
builder.setMultiChoiceItems(items, checkedItems) { _, which, isChecked ->
checkedItems?.set(which, isChecked)
+ onItemsSelected?.invoke(checkedItems!!)
}
}
}
diff --git a/app/src/main/res/layout/activity_follow.xml b/app/src/main/res/layout/activity_follow.xml
index 9ec387c4..ded5b53f 100644
--- a/app/src/main/res/layout/activity_follow.xml
+++ b/app/src/main/res/layout/activity_follow.xml
@@ -103,15 +103,18 @@
-
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center_horizontal">
@@ -132,8 +135,8 @@
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="32dp"
- android:visibility="gone" />
-
+ android:visibility="gone"
+ android:layout_gravity="center_horizontal" />
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_notification.xml b/app/src/main/res/layout/activity_notification.xml
new file mode 100644
index 00000000..d920c307
--- /dev/null
+++ b/app/src/main/res/layout/activity_notification.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_notifications.xml b/app/src/main/res/layout/fragment_notifications.xml
new file mode 100644
index 00000000..10fc1bef
--- /dev/null
+++ b/app/src/main/res/layout/fragment_notifications.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file