mirror of
https://github.com/rebelonion/Dantotsu.git
synced 2026-01-20 23:53:55 +00:00
Merge branch 'rebelonion:dev' into dev
This commit is contained in:
@@ -28,6 +28,7 @@ import android.telephony.TelephonyManager
|
||||
import android.text.InputFilter
|
||||
import android.text.Spanned
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.util.TypedValue
|
||||
import android.view.*
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
@@ -129,7 +130,8 @@ var loadIsMAL = false
|
||||
|
||||
fun logger(e: Any?, print: Boolean = true) {
|
||||
if (print)
|
||||
println(e)
|
||||
//println(e)
|
||||
Log.d("Logger", e.toString())
|
||||
}
|
||||
|
||||
|
||||
@@ -902,16 +904,16 @@ fun toast(string: String?) {
|
||||
}
|
||||
}
|
||||
|
||||
fun snackString(s: String?, activity: Activity? = null, clipboard: String? = null) {
|
||||
fun snackString(s: String?, activity: Activity? = null, clipboard: String? = null) : Snackbar? {
|
||||
try { //I have no idea why this sometimes crashes for some people...
|
||||
if (s != null) {
|
||||
(activity ?: currActivity())?.apply {
|
||||
val snackBar = Snackbar.make(
|
||||
window.decorView.findViewById(android.R.id.content),
|
||||
s,
|
||||
Snackbar.LENGTH_SHORT
|
||||
)
|
||||
runOnUiThread {
|
||||
val snackBar = Snackbar.make(
|
||||
window.decorView.findViewById(android.R.id.content),
|
||||
s,
|
||||
Snackbar.LENGTH_SHORT
|
||||
)
|
||||
snackBar.view.apply {
|
||||
updateLayoutParams<FrameLayout.LayoutParams> {
|
||||
gravity = (Gravity.CENTER_HORIZONTAL or Gravity.BOTTOM)
|
||||
@@ -931,6 +933,7 @@ fun snackString(s: String?, activity: Activity? = null, clipboard: String? = nul
|
||||
}
|
||||
snackBar.show()
|
||||
}
|
||||
return snackBar
|
||||
}
|
||||
logger(s)
|
||||
}
|
||||
@@ -938,6 +941,7 @@ fun snackString(s: String?, activity: Activity? = null, clipboard: String? = nul
|
||||
logger(e.stackTraceToString())
|
||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
open class NoPaddingArrayAdapter<T>(context: Context, layoutId: Int, items: List<T>) :
|
||||
|
||||
@@ -22,6 +22,9 @@ import androidx.annotation.OptIn
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.animation.doOnEnd
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.core.view.doOnAttach
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.fragment.app.Fragment
|
||||
@@ -49,6 +52,8 @@ import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.SharedPreferenceBooleanLiveData
|
||||
import ani.dantotsu.subcriptions.Subscription.Companion.startSubscription
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.google.android.material.snackbar.BaseTransientBottomBar
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import io.noties.markwon.Markwon
|
||||
import io.noties.markwon.SoftBreakAddsNewLinePlugin
|
||||
@@ -141,7 +146,20 @@ class MainActivity : AppCompatActivity() {
|
||||
finish()
|
||||
}
|
||||
doubleBackToExitPressedOnce = true
|
||||
snackString(this@MainActivity.getString(R.string.back_to_exit))
|
||||
WindowInsetsControllerCompat(window, window.decorView)
|
||||
.show(WindowInsetsCompat.Type.navigationBars())
|
||||
snackString(this@MainActivity.getString(R.string.back_to_exit)).apply {
|
||||
this?.addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
|
||||
override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
|
||||
super.onDismissed(transientBottomBar, event)
|
||||
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
|
||||
controller.systemBarsBehavior =
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
controller.hide(WindowInsetsCompat.Type.navigationBars())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
Handler(Looper.getMainLooper()).postDelayed(
|
||||
{ doubleBackToExitPressedOnce = false },
|
||||
2000
|
||||
@@ -349,6 +367,16 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
|
||||
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
|
||||
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
controller.hide(WindowInsetsCompat.Type.navigationBars())
|
||||
}
|
||||
}
|
||||
|
||||
//ViewPager
|
||||
private class ViewPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) :
|
||||
|
||||
@@ -8,10 +8,10 @@ import ani.dantotsu.connections.anilist.Anilist.authorRoles
|
||||
import ani.dantotsu.connections.anilist.Anilist.executeQuery
|
||||
import ani.dantotsu.connections.anilist.api.FeedResponse
|
||||
import ani.dantotsu.connections.anilist.api.FuzzyDate
|
||||
import ani.dantotsu.connections.anilist.api.Notification
|
||||
import ani.dantotsu.connections.anilist.api.NotificationResponse
|
||||
import ani.dantotsu.connections.anilist.api.Page
|
||||
import ani.dantotsu.connections.anilist.api.Query
|
||||
import ani.dantotsu.connections.anilist.api.ToggleLike
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.isOnline
|
||||
import ani.dantotsu.logError
|
||||
@@ -281,7 +281,7 @@ class AnilistQueries {
|
||||
} else {
|
||||
if (currContext()?.let { isOnline(it) } == true) {
|
||||
snackString(currContext()?.getString(R.string.error_getting_data))
|
||||
}
|
||||
} else { }
|
||||
}
|
||||
}
|
||||
val mal = async {
|
||||
@@ -1265,10 +1265,15 @@ Page(page:$page,perPage:50) {
|
||||
}
|
||||
|
||||
suspend fun toggleFollow(id: Int): Query.ToggleFollow? {
|
||||
val response = executeQuery<Query.ToggleFollow>(
|
||||
return executeQuery<Query.ToggleFollow>(
|
||||
"""mutation{ToggleFollow(userId:$id){id, isFollowing, isFollower}}"""
|
||||
)
|
||||
return response
|
||||
}
|
||||
|
||||
suspend fun toggleLike(id: Int, type: String): ToggleLike? {
|
||||
return executeQuery<ToggleLike>(
|
||||
"""mutation Like{ToggleLikeV2(id:$id,type:$type){__typename}}"""
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getUserProfile(id: Int): Query.UserProfileResponse? {
|
||||
@@ -1342,8 +1347,8 @@ Page(page:$page,perPage:50) {
|
||||
return default
|
||||
}
|
||||
|
||||
suspend fun getNotifications(id: Int): NotificationResponse? {
|
||||
val res = executeQuery<NotificationResponse>("""{User(id:$id){unreadNotificationCount}Page{notifications(resetNotificationCount:true){__typename...on AiringNotification{id,type,animeId,episode,contexts,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}},}...on FollowingNotification{id,userId,type,context,createdAt,user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityMessageNotification{id,userId,type,activityId,context,createdAt,message{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityMentionNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplyNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplySubscribedNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityLikeNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplyLikeNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentMentionNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentReplyNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentSubscribedNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentLikeNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadLikeNotification{id,userId,type,threadId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on RelatedMediaAdditionNotification{id,type,context,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaDataChangeNotification{id,type,mediaId,context,reason,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaMergeNotification{id,type,mediaId,deletedMediaTitles,context,reason,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaDeletionNotification{id,type,deletedMediaTitle,context,reason,createdAt,}}}}""", force = true)
|
||||
suspend fun getNotifications(id: Int, page: Int = 1): NotificationResponse? {
|
||||
val res = executeQuery<NotificationResponse>("""{User(id:$id){unreadNotificationCount}Page(page:$page,perPage:$ITEMS_PER_PAGE){notifications(resetNotificationCount:true){__typename...on AiringNotification{id,type,animeId,episode,contexts,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}},}...on FollowingNotification{id,userId,type,context,createdAt,user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityMessageNotification{id,userId,type,activityId,context,createdAt,message{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityMentionNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplyNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplySubscribedNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityLikeNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ActivityReplyLikeNotification{id,userId,type,activityId,context,createdAt,activity{__typename}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentMentionNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentReplyNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentSubscribedNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadCommentLikeNotification{id,userId,type,commentId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on ThreadLikeNotification{id,userId,type,threadId,context,createdAt,thread{id}comment{id}user{id,name,bannerImage,avatar{medium,large,}}}...on RelatedMediaAdditionNotification{id,type,context,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaDataChangeNotification{id,type,mediaId,context,reason,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaMergeNotification{id,type,mediaId,deletedMediaTitles,context,reason,createdAt,media{id,title{romaji,english,native,userPreferred}bannerImage,coverImage{medium,large}}}...on MediaDeletionNotification{id,type,deletedMediaTitle,context,reason,createdAt,}}}}""", force = true)
|
||||
if (res != null) {
|
||||
Anilist.unreadNotificationCount = 0
|
||||
}
|
||||
@@ -1354,7 +1359,11 @@ Page(page:$page,perPage:50) {
|
||||
val filter = if (userId != null) "userId:$userId,"
|
||||
else if (global) "isFollowing:false,"
|
||||
else "isFollowing:true,"
|
||||
val res = executeQuery<FeedResponse>("""{Page(page:$page,perPage:25){activities(${filter}sort:ID_DESC){__typename ... on TextActivity{id userId type replyCount text(asHtml:true)siteUrl isLocked isSubscribed likeCount isLiked isPinned createdAt user{id name bannerImage avatar{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}... on ListActivity{id userId type replyCount status progress siteUrl isLocked isSubscribed likeCount isLiked isPinned createdAt user{id name bannerImage avatar{medium large}}media{id title{english romaji native userPreferred}bannerImage coverImage{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}... on MessageActivity{id recipientId messengerId type replyCount message(asHtml:true)isLocked isSubscribed isLiked isPrivate siteUrl createdAt recipient{id name bannerImage avatar{medium large}}messenger{id name bannerImage avatar{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}}}}""")
|
||||
val res = executeQuery<FeedResponse>("""{Page(page:$page,perPage:$ITEMS_PER_PAGE){activities(${filter}sort:ID_DESC){__typename ... on TextActivity{id userId type replyCount text(asHtml:true)siteUrl isLocked isSubscribed likeCount isLiked isPinned createdAt user{id name bannerImage avatar{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}... on ListActivity{id userId type replyCount status progress siteUrl isLocked isSubscribed likeCount isLiked isPinned createdAt user{id name bannerImage avatar{medium large}}media{id title{english romaji native userPreferred}bannerImage coverImage{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}... on MessageActivity{id recipientId messengerId type replyCount message(asHtml:true)isLocked isSubscribed isLiked isPrivate siteUrl createdAt recipient{id name bannerImage avatar{medium large}}messenger{id name bannerImage avatar{medium large}}replies{id userId activityId text(asHtml:true)likeCount isLiked createdAt user{id name bannerImage avatar{medium large}}likes{id name bannerImage avatar{medium large}}}likes{id name bannerImage avatar{medium large}}}}}}""")
|
||||
return res
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ITEMS_PER_PAGE = 25
|
||||
}
|
||||
}
|
||||
@@ -7,19 +7,19 @@ import kotlinx.serialization.Serializable
|
||||
data class FeedResponse(
|
||||
@SerialName("data")
|
||||
val data: Data
|
||||
) {
|
||||
) : java.io.Serializable {
|
||||
@Serializable
|
||||
data class Data(
|
||||
@SerialName("Page")
|
||||
val page: ActivityPage
|
||||
)
|
||||
) : java.io.Serializable
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ActivityPage(
|
||||
@SerialName("activities")
|
||||
val activities: List<Activity>
|
||||
)
|
||||
) : java.io.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Activity(
|
||||
@@ -52,9 +52,9 @@ data class Activity(
|
||||
@SerialName("isSubscribed")
|
||||
val isSubscribed: Boolean,
|
||||
@SerialName("likeCount")
|
||||
val likeCount: Int?,
|
||||
var likeCount: Int?,
|
||||
@SerialName("isLiked")
|
||||
val isLiked: Boolean?,
|
||||
var isLiked: Boolean?,
|
||||
@SerialName("isPinned")
|
||||
val isPinned: Boolean?,
|
||||
@SerialName("isPrivate")
|
||||
@@ -69,7 +69,7 @@ data class Activity(
|
||||
val replies: List<Reply>?,
|
||||
@SerialName("likes")
|
||||
val likes: List<User>?,
|
||||
)
|
||||
) : java.io.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Reply(
|
||||
@@ -89,4 +89,22 @@ data class Reply(
|
||||
val user: User,
|
||||
@SerialName("likes")
|
||||
val likes: List<User>?,
|
||||
)
|
||||
) : java.io.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ToggleLike(
|
||||
@SerialName("data")
|
||||
val data: Data
|
||||
) : java.io.Serializable {
|
||||
@Serializable
|
||||
data class Data(
|
||||
@SerialName("ToggleLikeV2")
|
||||
val toggleLike: LikeData
|
||||
) : java.io.Serializable
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class LikeData(
|
||||
@SerialName("__typename")
|
||||
val typename: String
|
||||
) : java.io.Serializable
|
||||
@@ -26,6 +26,7 @@ import ani.dantotsu.media.CalendarActivity
|
||||
import ani.dantotsu.media.GenreActivity
|
||||
import ani.dantotsu.media.MediaAdaptor
|
||||
import ani.dantotsu.media.SearchActivity
|
||||
import ani.dantotsu.profile.ProfileActivity
|
||||
import ani.dantotsu.px
|
||||
import ani.dantotsu.setSafeOnClickListener
|
||||
import ani.dantotsu.setSlideIn
|
||||
@@ -94,6 +95,15 @@ class AnimePageAdapter : RecyclerView.Adapter<AnimePageAdapter.AnimePageViewHold
|
||||
SettingsDialogFragment.newInstance(SettingsDialogFragment.Companion.PageType.ANIME)
|
||||
dialogFragment.show((it.context as AppCompatActivity).supportFragmentManager, "dialog")
|
||||
}
|
||||
binding.animeUserAvatar.setOnLongClickListener { view ->
|
||||
ContextCompat.startActivity(
|
||||
view.context,
|
||||
Intent(view.context, ProfileActivity::class.java)
|
||||
.putExtra("userId", Anilist.userid),null
|
||||
)
|
||||
false
|
||||
}
|
||||
|
||||
binding.animeNotificationCount.visibility = if (Anilist.unreadNotificationCount > 0) View.VISIBLE else View.GONE
|
||||
binding.animeNotificationCount.text = Anilist.unreadNotificationCount.toString()
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ class HomeFragment : Fragment() {
|
||||
binding.homeUserAvatarContainer.setOnLongClickListener {
|
||||
ContextCompat.startActivity(
|
||||
requireContext(), Intent(requireContext(), ProfileActivity::class.java)
|
||||
.putExtra("userId", Anilist.userid), null
|
||||
.putExtra("userId", Anilist.userid),null
|
||||
)
|
||||
false
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import ani.dantotsu.loadImage
|
||||
import ani.dantotsu.media.GenreActivity
|
||||
import ani.dantotsu.media.MediaAdaptor
|
||||
import ani.dantotsu.media.SearchActivity
|
||||
import ani.dantotsu.profile.ProfileActivity
|
||||
import ani.dantotsu.px
|
||||
import ani.dantotsu.setSafeOnClickListener
|
||||
import ani.dantotsu.setSlideIn
|
||||
@@ -90,6 +91,14 @@ class MangaPageAdapter : RecyclerView.Adapter<MangaPageAdapter.MangaPageViewHold
|
||||
SettingsDialogFragment.newInstance(SettingsDialogFragment.Companion.PageType.MANGA)
|
||||
dialogFragment.show((it.context as AppCompatActivity).supportFragmentManager, "dialog")
|
||||
}
|
||||
binding.mangaUserAvatar.setOnLongClickListener { view ->
|
||||
ContextCompat.startActivity(
|
||||
view.context,
|
||||
Intent(view.context, ProfileActivity::class.java)
|
||||
.putExtra("userId", Anilist.userid),null
|
||||
)
|
||||
false
|
||||
}
|
||||
|
||||
binding.mangaSearchBar.setEndIconOnClickListener {
|
||||
binding.mangaSearchBarText.performClick()
|
||||
|
||||
@@ -58,6 +58,32 @@ class MediaListDialogSmallFragment : BottomSheetDialogFragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.mediaListContainer.updateLayoutParams<ViewGroup.MarginLayoutParams> { bottomMargin += navBarHeight }
|
||||
val scope = viewLifecycleOwner.lifecycleScope
|
||||
binding.mediaListDelete.setOnClickListener {
|
||||
val id = media.userListId
|
||||
if (id != null) {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
try {
|
||||
Anilist.mutation.deleteList(id)
|
||||
MAL.query.deleteList(media.anime != null, media.idMAL)
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
snackString("Failed to delete because of... ${e.message}")
|
||||
}
|
||||
return@withContext
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
Refresh.all()
|
||||
snackString(getString(R.string.deleted_from_list))
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
snackString(getString(R.string.no_list_id))
|
||||
Refresh.all()
|
||||
}
|
||||
}
|
||||
|
||||
binding.mediaListProgressBar.visibility = View.GONE
|
||||
binding.mediaListLayout.visibility = View.VISIBLE
|
||||
|
||||
@@ -285,16 +285,26 @@ class MangaReaderActivity : AppCompatActivity() {
|
||||
binding.mangaReaderNextChapter.performClick()
|
||||
}
|
||||
binding.mangaReaderNextChapter.setOnClickListener {
|
||||
if (chaptersArr.size > currentChapterIndex + 1) progress { change(currentChapterIndex + 1) }
|
||||
else snackString(getString(R.string.next_chapter_not_found))
|
||||
if (defaultSettings.direction == RIGHT_TO_LEFT) {
|
||||
if (currentChapterIndex > 0) change(currentChapterIndex - 1)
|
||||
else snackString(getString(R.string.first_chapter))
|
||||
} else {
|
||||
if (chaptersArr.size > currentChapterIndex + 1) progress { change(currentChapterIndex + 1) }
|
||||
else snackString(getString(R.string.next_chapter_not_found))
|
||||
}
|
||||
}
|
||||
//Prev Chapter
|
||||
binding.mangaReaderPrevChap.setOnClickListener {
|
||||
binding.mangaReaderPreviousChapter.performClick()
|
||||
}
|
||||
binding.mangaReaderPreviousChapter.setOnClickListener {
|
||||
if (currentChapterIndex > 0) change(currentChapterIndex - 1)
|
||||
else snackString(getString(R.string.first_chapter))
|
||||
if (defaultSettings.direction == RIGHT_TO_LEFT) {
|
||||
if (chaptersArr.size > currentChapterIndex + 1) progress { change(currentChapterIndex + 1) }
|
||||
else snackString(getString(R.string.next_chapter_not_found))
|
||||
} else {
|
||||
if (currentChapterIndex > 0) change(currentChapterIndex - 1)
|
||||
else snackString(getString(R.string.first_chapter))
|
||||
}
|
||||
}
|
||||
|
||||
model.getMangaChapter().observe(this) { chap ->
|
||||
@@ -305,10 +315,17 @@ class MangaReaderActivity : AppCompatActivity() {
|
||||
PrefManager.setCustomVal("${media.id}_current_chp", chap.number)
|
||||
currentChapterIndex = chaptersArr.indexOf(chap.number)
|
||||
binding.mangaReaderChapterSelect.setSelection(currentChapterIndex)
|
||||
binding.mangaReaderNextChap.text =
|
||||
chaptersTitleArr.getOrNull(currentChapterIndex + 1) ?: ""
|
||||
binding.mangaReaderPrevChap.text =
|
||||
chaptersTitleArr.getOrNull(currentChapterIndex - 1) ?: ""
|
||||
if (defaultSettings.direction == RIGHT_TO_LEFT) {
|
||||
binding.mangaReaderNextChap.text =
|
||||
chaptersTitleArr.getOrNull(currentChapterIndex - 1) ?: ""
|
||||
binding.mangaReaderPrevChap.text =
|
||||
chaptersTitleArr.getOrNull(currentChapterIndex + 1) ?: ""
|
||||
} else {
|
||||
binding.mangaReaderNextChap.text =
|
||||
chaptersTitleArr.getOrNull(currentChapterIndex + 1) ?: ""
|
||||
binding.mangaReaderPrevChap.text =
|
||||
chaptersTitleArr.getOrNull(currentChapterIndex - 1) ?: ""
|
||||
}
|
||||
applySettings()
|
||||
val context = this
|
||||
val offline: Boolean = PrefManager.getVal(PrefName.OfflineMode)
|
||||
@@ -459,27 +476,26 @@ class MangaReaderActivity : AppCompatActivity() {
|
||||
} else {
|
||||
binding.mangaReaderSwipy.vertical = false
|
||||
if (defaultSettings.direction == RIGHT_TO_LEFT) {
|
||||
binding.mangaReaderNextChap.text =
|
||||
chaptersTitleArr.getOrNull(currentChapterIndex - 1) ?: ""
|
||||
binding.mangaReaderPrevChap.text =
|
||||
chaptersTitleArr.getOrNull(currentChapterIndex + 1) ?: ""
|
||||
binding.LeftSwipeText.text = chaptersTitleArr.getOrNull(currentChapterIndex + 1)
|
||||
?: getString(R.string.no_chapter)
|
||||
binding.RightSwipeText.text = chaptersTitleArr.getOrNull(currentChapterIndex - 1)
|
||||
?: getString(R.string.no_chapter)
|
||||
binding.mangaReaderSwipy.onLeftSwiped = {
|
||||
binding.mangaReaderNextChapter.performClick()
|
||||
}
|
||||
binding.mangaReaderSwipy.onRightSwiped = {
|
||||
binding.mangaReaderPreviousChapter.performClick()
|
||||
}
|
||||
} else {
|
||||
binding.mangaReaderNextChap.text =
|
||||
chaptersTitleArr.getOrNull(currentChapterIndex + 1) ?: ""
|
||||
binding.mangaReaderPrevChap.text =
|
||||
chaptersTitleArr.getOrNull(currentChapterIndex - 1) ?: ""
|
||||
binding.LeftSwipeText.text = chaptersTitleArr.getOrNull(currentChapterIndex - 1)
|
||||
?: getString(R.string.no_chapter)
|
||||
binding.RightSwipeText.text = chaptersTitleArr.getOrNull(currentChapterIndex + 1)
|
||||
?: getString(R.string.no_chapter)
|
||||
binding.mangaReaderSwipy.onLeftSwiped = {
|
||||
binding.mangaReaderPreviousChapter.performClick()
|
||||
}
|
||||
binding.mangaReaderSwipy.onRightSwiped = {
|
||||
binding.mangaReaderNextChapter.performClick()
|
||||
}
|
||||
}
|
||||
binding.mangaReaderSwipy.onLeftSwiped = {
|
||||
binding.mangaReaderPreviousChapter.performClick()
|
||||
}
|
||||
binding.mangaReaderSwipy.leftBeingSwiped = { value ->
|
||||
binding.LeftSwipeContainer.apply {
|
||||
@@ -487,6 +503,9 @@ class MangaReaderActivity : AppCompatActivity() {
|
||||
translationX = -width.dp * (1 - min(value, 1f))
|
||||
}
|
||||
}
|
||||
binding.mangaReaderSwipy.onRightSwiped = {
|
||||
binding.mangaReaderNextChapter.performClick()
|
||||
}
|
||||
binding.mangaReaderSwipy.rightBeingSwiped = { value ->
|
||||
binding.RightSwipeContainer.apply {
|
||||
alpha = value
|
||||
|
||||
@@ -14,6 +14,7 @@ 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,6 +37,7 @@ class FollowActivity : AppCompatActivity(){
|
||||
initActivity(this)
|
||||
binding = ActivityFollowBinding.inflate(layoutInflater)
|
||||
binding.listToolbar.updateLayoutParams<MarginLayoutParams> { topMargin = statusBarHeight }
|
||||
binding.listFrameLayout.updateLayoutParams<MarginLayoutParams> { bottomMargin = navBarHeight }
|
||||
setContentView(binding.root)
|
||||
val layoutType = PrefManager.getVal<Int>(PrefName.FollowerLayout)
|
||||
selected = getSelected(layoutType)
|
||||
|
||||
@@ -22,7 +22,7 @@ import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.loadImage
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.others.ImageViewDialog
|
||||
import ani.dantotsu.profile.activity.ActivityActivity
|
||||
import ani.dantotsu.profile.activity.FeedFragment
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.snackString
|
||||
@@ -36,8 +36,8 @@ import nl.joery.animatedbottombar.AnimatedBottomBar
|
||||
|
||||
|
||||
class ProfileActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityProfileBinding
|
||||
private var selected: Int = 0
|
||||
lateinit var binding: ActivityProfileBinding
|
||||
private var selected: Int = 1
|
||||
private lateinit var navBar: AnimatedBottomBar
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@@ -49,8 +49,10 @@ class ProfileActivity : AppCompatActivity() {
|
||||
setContentView(binding.root)
|
||||
navBar = binding.profileNavBar
|
||||
navBar.updateLayoutParams<ViewGroup.MarginLayoutParams> { bottomMargin = navBarHeight }
|
||||
val feedTab = navBar.createTab(R.drawable.ic_round_filter_24, "Feed")
|
||||
val profileTab = navBar.createTab(R.drawable.ic_round_person_24, "Profile")
|
||||
val statsTab = navBar.createTab(R.drawable.ic_stats_24, "Stats")
|
||||
navBar.addTab(feedTab)
|
||||
navBar.addTab(profileTab)
|
||||
navBar.addTab(statsTab)
|
||||
navBar.visibility = View.GONE
|
||||
@@ -70,6 +72,7 @@ class ProfileActivity : AppCompatActivity() {
|
||||
}
|
||||
binding.profileViewPager.adapter =
|
||||
ViewPagerAdapter(supportFragmentManager, lifecycle, user)
|
||||
binding.profileViewPager.setCurrentItem(selected, false)
|
||||
navBar.visibility = View.VISIBLE
|
||||
navBar.selectTabAt(selected)
|
||||
navBar.setOnTabSelectListener(object : AnimatedBottomBar.OnTabSelectListener {
|
||||
@@ -106,15 +109,6 @@ class ProfileActivity : AppCompatActivity() {
|
||||
}
|
||||
binding.profileProgressBar.visibility = View.GONE
|
||||
binding.profileTopContainer.visibility = View.VISIBLE
|
||||
binding.profileActivityButton.setOnClickListener {
|
||||
ContextCompat.startActivity(
|
||||
this@ProfileActivity,
|
||||
Intent(this@ProfileActivity, ActivityActivity::class.java)
|
||||
.putExtra("userId", user.id)
|
||||
.putExtra("username", user.name),
|
||||
null
|
||||
)
|
||||
}
|
||||
binding.profileMenuButton.setOnClickListener {
|
||||
val popup = PopupMenu(this@ProfileActivity, binding.profileMenuButton)
|
||||
popup.menuInflater.inflate(R.menu.menu_profile, popup.menu)
|
||||
@@ -161,7 +155,6 @@ class ProfileActivity : AppCompatActivity() {
|
||||
binding.profileBannerImage.updateLayoutParams { height += statusBarHeight }
|
||||
binding.profileBannerGradient.updateLayoutParams { height += statusBarHeight }
|
||||
binding.profileMenuButton.updateLayoutParams<ViewGroup.MarginLayoutParams> { topMargin += statusBarHeight }
|
||||
binding.profileActivityButton.updateLayoutParams<ViewGroup.MarginLayoutParams> { topMargin += statusBarHeight }
|
||||
binding.profileBannerImage.setOnLongClickListener {
|
||||
ImageViewDialog.newInstance(
|
||||
this@ProfileActivity,
|
||||
@@ -188,10 +181,11 @@ class ProfileActivity : AppCompatActivity() {
|
||||
) :
|
||||
FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||
|
||||
override fun getItemCount(): Int = 2
|
||||
override fun getItemCount(): Int = 3
|
||||
override fun createFragment(position: Int): Fragment = when (position) {
|
||||
0 -> ProfileFragment.newInstance(user)
|
||||
1 -> StatsFragment.newInstance(user)
|
||||
0 -> FeedFragment.newInstance(user.id, false)
|
||||
1 -> ProfileFragment.newInstance(user)
|
||||
2 -> StatsFragment.newInstance(user)
|
||||
else -> ProfileFragment.newInstance(user)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class ProfileFragment() : Fragment() {
|
||||
class ProfileFragment : Fragment() {
|
||||
lateinit var binding: FragmentProfileBinding
|
||||
private lateinit var activity: ProfileActivity
|
||||
private lateinit var user: Query.UserProfile
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
package ani.dantotsu.profile.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import ani.dantotsu.connections.anilist.Anilist
|
||||
import ani.dantotsu.connections.anilist.api.Activity
|
||||
import ani.dantotsu.databinding.ActivityFollowBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ActivityActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityFollowBinding
|
||||
private var adapter: GroupieAdapter = GroupieAdapter()
|
||||
private var activityList: List<Activity> = 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 = "Activity"
|
||||
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()
|
||||
}
|
||||
binding.listProgressBar.visibility = ViewGroup.VISIBLE
|
||||
var userId: Int? = intent.getIntExtra("userId", -1)
|
||||
if (userId == -1) userId = null
|
||||
val global = intent.getBooleanExtra("global", false)
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val res = Anilist.query.getFeed(userId, global)
|
||||
|
||||
withContext(Dispatchers.Main){
|
||||
res?.data?.page?.activities?.let { activities ->
|
||||
activityList = activities
|
||||
adapter.update(activityList.map { ActivityItem(it){} })
|
||||
}
|
||||
binding.listProgressBar.visibility = ViewGroup.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,40 +5,79 @@ import android.content.Context
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.buildMarkwon
|
||||
import ani.dantotsu.connections.anilist.Anilist
|
||||
import ani.dantotsu.connections.anilist.api.Activity
|
||||
import ani.dantotsu.databinding.ItemActivityBinding
|
||||
import ani.dantotsu.loadImage
|
||||
import ani.dantotsu.snackString
|
||||
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
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ActivityItem(
|
||||
private val activity: Activity,
|
||||
val clickCallback: (Int) -> Unit
|
||||
): BindableItem<ItemActivityBinding>() {
|
||||
val clickCallback: (Int, type: String) -> Unit
|
||||
) : BindableItem<ItemActivityBinding>() {
|
||||
private lateinit var binding: ItemActivityBinding
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun bind(viewBinding: ItemActivityBinding, position: Int) {
|
||||
binding = viewBinding
|
||||
|
||||
binding.activityUserName.text = activity.user?.name
|
||||
binding.activityUserAvatar.loadImage(activity.user?.avatar?.medium)
|
||||
binding.activityTime.text = ActivityItemBuilder.getDateTime(activity.createdAt)
|
||||
val likeColor = ContextCompat.getColor(binding.root.context, R.color.yt_red)
|
||||
val notLikeColor = ContextCompat.getColor(binding.root.context, R.color.bg_opp)
|
||||
binding.activityLike.setColorFilter(if (activity.isLiked == true) likeColor else notLikeColor)
|
||||
binding.commentRepliesContainer.visibility =
|
||||
if (activity.replyCount > 0) View.VISIBLE else View.GONE
|
||||
binding.activityLikeCount.text = activity.likeCount.toString()
|
||||
|
||||
binding.activityLike.setOnClickListener {
|
||||
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
scope.launch {
|
||||
val res = Anilist.query.toggleLike(activity.id, "ACTIVITY")
|
||||
withContext(Dispatchers.Main) {
|
||||
if (res != null) {
|
||||
|
||||
if (activity.isLiked == true) {
|
||||
activity.likeCount = activity.likeCount?.minus(1)
|
||||
} else {
|
||||
activity.likeCount = activity.likeCount?.plus(1)
|
||||
}
|
||||
binding.activityLikeCount.text = activity.likeCount.toString()
|
||||
activity.isLiked = !activity.isLiked!!
|
||||
binding.activityLike.setColorFilter(if (activity.isLiked == true) likeColor else notLikeColor)
|
||||
|
||||
} else {
|
||||
snackString("Failed to like activity")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val context = binding.root.context
|
||||
|
||||
when (activity.typename) {
|
||||
"ListActivity" ->{
|
||||
binding.activityUserName.text = activity.user?.name
|
||||
binding.activityUserAvatar.loadImage(activity.user?.avatar?.medium)
|
||||
binding.activityTime.text = ActivityItemBuilder.getDateTime(activity.createdAt)
|
||||
val color = if (activity.isLiked == true)
|
||||
ContextCompat.getColor(binding.root.context, R.color.yt_red)
|
||||
else
|
||||
ContextCompat.getColor(binding.root.context, R.color.bg_opp)
|
||||
binding.activityFavorite.setColorFilter(color)
|
||||
binding.activityFavoriteCount.text = activity.likeCount.toString()
|
||||
"ListActivity" -> {
|
||||
binding.activityContent.visibility = View.GONE
|
||||
binding.activityBannerContainer.visibility = View.VISIBLE
|
||||
|
||||
binding.activityMediaName.text = activity.media?.title?.userPreferred
|
||||
binding.activityText.text = "${activity.user!!.name} ${activity.status} ${activity.progress ?: ""}"
|
||||
binding.activityCover.loadImage(activity.media?.coverImage?.large)
|
||||
val context = binding.root.context
|
||||
val banner = activity.media?.bannerImage ?: activity.media?.coverImage?.large
|
||||
binding.activityText.text =
|
||||
"""${activity.user!!.name} ${activity.status} ${activity.progress ?: ""}"""
|
||||
binding.activityCover.loadImage(activity.media?.coverImage?.medium)
|
||||
val banner = activity.media?.bannerImage
|
||||
if (banner != null) {
|
||||
if (!(context as android.app.Activity).isDestroyed) {
|
||||
Glide.with(context as Context)
|
||||
@@ -51,6 +90,15 @@ class ActivityItem(
|
||||
binding.activityBannerImage.setImageResource(R.drawable.linear_gradient_bg)
|
||||
}
|
||||
}
|
||||
|
||||
"TextActivity" -> {
|
||||
binding.activityBannerContainer.visibility = View.GONE
|
||||
binding.activityContent.visibility = View.VISIBLE
|
||||
if (!(context as android.app.Activity).isDestroyed) {
|
||||
val markwon = buildMarkwon(context, false)
|
||||
markwon.setMarkdown(binding.activityContent, activity.text ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package ani.dantotsu.profile.activity
|
||||
|
||||
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 ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.ActivityFeedBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import nl.joery.animatedbottombar.AnimatedBottomBar
|
||||
|
||||
class FeedActivity: AppCompatActivity() {
|
||||
private lateinit var binding: ActivityFeedBinding
|
||||
private var selected: Int = 0
|
||||
private lateinit var navBar: AnimatedBottomBar
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
initActivity(this)
|
||||
binding = ActivityFeedBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
navBar = binding.feedNavBar
|
||||
navBar.updateLayoutParams<ViewGroup.MarginLayoutParams> { bottomMargin += navBarHeight }
|
||||
val personalTab = navBar.createTab(R.drawable.ic_round_person_24, "Personal")
|
||||
val globalTab = navBar.createTab(R.drawable.ic_globe_24, "Global")
|
||||
navBar.addTab(personalTab)
|
||||
navBar.addTab(globalTab)
|
||||
binding.listTitle.text = "Activities"
|
||||
binding.feedViewPager.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin += navBarHeight
|
||||
topMargin += statusBarHeight
|
||||
}
|
||||
binding.listToolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> { topMargin += statusBarHeight }
|
||||
binding.feedViewPager.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle)
|
||||
binding.feedViewPager.setCurrentItem(selected, false)
|
||||
binding.feedViewPager.isUserInputEnabled = false
|
||||
navBar.selectTabAt(selected)
|
||||
navBar.setOnTabSelectListener(object : AnimatedBottomBar.OnTabSelectListener {
|
||||
override fun onTabSelected(
|
||||
lastIndex: Int,
|
||||
lastTab: AnimatedBottomBar.Tab?,
|
||||
newIndex: Int,
|
||||
newTab: AnimatedBottomBar.Tab
|
||||
) {
|
||||
selected = newIndex
|
||||
binding.feedViewPager.setCurrentItem(selected, true)
|
||||
}
|
||||
})
|
||||
binding.listBack.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
navBar.selectTabAt(selected)
|
||||
}
|
||||
|
||||
|
||||
private class ViewPagerAdapter(
|
||||
fragmentManager: FragmentManager,
|
||||
lifecycle: Lifecycle
|
||||
) : FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||
override fun getItemCount(): Int = 2
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return when (position) {
|
||||
0 -> FeedFragment.newInstance(null, false)
|
||||
else -> FeedFragment.newInstance(null, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
111
app/src/main/java/ani/dantotsu/profile/activity/FeedFragment.kt
Normal file
111
app/src/main/java/ani/dantotsu/profile/activity/FeedFragment.kt
Normal file
@@ -0,0 +1,111 @@
|
||||
package ani.dantotsu.profile.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import ani.dantotsu.connections.anilist.Anilist
|
||||
import ani.dantotsu.connections.anilist.AnilistQueries
|
||||
import ani.dantotsu.connections.anilist.api.Activity
|
||||
import ani.dantotsu.databinding.FragmentFeedBinding
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.profile.ProfileActivity
|
||||
import ani.dantotsu.snackString
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class FeedFragment : Fragment() {
|
||||
private lateinit var binding: FragmentFeedBinding
|
||||
private var adapter: GroupieAdapter = GroupieAdapter()
|
||||
private var activityList: List<Activity> = emptyList()
|
||||
private lateinit var activity: androidx.activity.ComponentActivity
|
||||
private var page: Int = 1
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = FragmentFeedBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
activity = requireActivity()
|
||||
binding.listRecyclerView.adapter = adapter
|
||||
binding.listRecyclerView.layoutManager =
|
||||
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
|
||||
binding.listProgressBar.visibility = ViewGroup.VISIBLE
|
||||
var userId: Int? = arguments?.getInt("userId", -1)
|
||||
if (userId == -1) userId = null
|
||||
val global = arguments?.getBoolean("global", false) ?: false
|
||||
|
||||
activity.lifecycleScope.launch(Dispatchers.IO) {
|
||||
val res = Anilist.query.getFeed(userId, global)
|
||||
withContext(Dispatchers.Main) {
|
||||
res?.data?.page?.activities?.let { activities ->
|
||||
activityList = activities
|
||||
adapter.update(activityList.map { ActivityItem(it) { _, _ -> } })
|
||||
}
|
||||
binding.listProgressBar.visibility = ViewGroup.GONE
|
||||
val scrollView = if (activity is ProfileActivity) {
|
||||
(activity as ProfileActivity).binding.profileScrollView
|
||||
} else {
|
||||
binding.listRecyclerView
|
||||
}
|
||||
binding.listRecyclerView.setOnTouchListener { _, event ->
|
||||
if (event?.action == MotionEvent.ACTION_UP) {
|
||||
if (adapter.itemCount % AnilistQueries.ITEMS_PER_PAGE != 0) {
|
||||
snackString("No more activities")
|
||||
} else if (!scrollView.canScrollVertically(1) && !binding.feedRefresh.isVisible
|
||||
&& binding.listRecyclerView.adapter!!.itemCount != 0 &&
|
||||
(binding.listRecyclerView.layoutManager as LinearLayoutManager).findLastVisibleItemPosition() == (binding.listRecyclerView.adapter!!.itemCount - 1)
|
||||
) {
|
||||
page++
|
||||
binding.feedRefresh.visibility = ViewGroup.VISIBLE
|
||||
activity.lifecycleScope.launch(Dispatchers.IO) {
|
||||
val res = Anilist.query.getFeed(userId, global, page)
|
||||
withContext(Dispatchers.Main) {
|
||||
res?.data?.page?.activities?.let { activities ->
|
||||
activityList += activities
|
||||
adapter.addAll(activities.map { ActivityItem(it) { _, _ -> } })
|
||||
}
|
||||
binding.feedRefresh.visibility = ViewGroup.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (this::binding.isInitialized) {
|
||||
binding.root.requestLayout()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(userId: Int?, global: Boolean): FeedFragment {
|
||||
val fragment = FeedFragment()
|
||||
val args = Bundle()
|
||||
args.putInt("userId", userId ?: -1)
|
||||
args.putBoolean("global", global)
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,18 +3,23 @@ package ani.dantotsu.profile.activity
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
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.AnilistQueries
|
||||
import ani.dantotsu.connections.anilist.api.Notification
|
||||
import ani.dantotsu.databinding.ActivityFollowBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.media.MediaDetailsActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.profile.ProfileActivity
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
@@ -26,8 +31,9 @@ class NotificationActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityFollowBinding
|
||||
private var adapter: GroupieAdapter = GroupieAdapter()
|
||||
private var notificationList: List<Notification> = emptyList()
|
||||
private var page: Int = 1
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@SuppressLint("SetTextI18n", "ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
@@ -36,6 +42,7 @@ class NotificationActivity : AppCompatActivity() {
|
||||
setContentView(binding.root)
|
||||
binding.listTitle.text = "Notifications"
|
||||
binding.listToolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> { topMargin = statusBarHeight }
|
||||
binding.listFrameLayout.updateLayoutParams<ViewGroup.MarginLayoutParams> { bottomMargin = navBarHeight }
|
||||
binding.listRecyclerView.adapter = adapter
|
||||
binding.listRecyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
||||
binding.followerGrid.visibility = ViewGroup.GONE
|
||||
@@ -52,6 +59,30 @@ class NotificationActivity : AppCompatActivity() {
|
||||
}
|
||||
withContext(Dispatchers.Main){
|
||||
binding.listProgressBar.visibility = ViewGroup.GONE
|
||||
binding.listRecyclerView.setOnTouchListener { _, event ->
|
||||
if (event?.action == MotionEvent.ACTION_UP) {
|
||||
if (adapter.itemCount % AnilistQueries.ITEMS_PER_PAGE != 0) {
|
||||
snackString("No more notifications")
|
||||
} else if (!binding.listRecyclerView.canScrollVertically(1) && !binding.followRefresh.isVisible
|
||||
&& binding.listRecyclerView.adapter!!.itemCount != 0 &&
|
||||
(binding.listRecyclerView.layoutManager as LinearLayoutManager).findLastVisibleItemPosition() == (binding.listRecyclerView.adapter!!.itemCount - 1)
|
||||
) {
|
||||
page++
|
||||
binding.followRefresh.visibility = ViewGroup.VISIBLE
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val res = Anilist.query.getNotifications(Anilist.userid?:0, page)
|
||||
withContext(Dispatchers.Main) {
|
||||
res?.data?.page?.notifications?.let { notifications ->
|
||||
notificationList += notifications
|
||||
adapter.addAll(notifications.map { NotificationItem(it, ::onNotificationClick) })
|
||||
}
|
||||
binding.followRefresh.visibility = ViewGroup.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import ani.dantotsu.incognitoNotification
|
||||
import ani.dantotsu.loadImage
|
||||
import ani.dantotsu.profile.activity.NotificationActivity
|
||||
import ani.dantotsu.offline.OfflineFragment
|
||||
import ani.dantotsu.profile.activity.FeedActivity
|
||||
import ani.dantotsu.setSafeOnClickListener
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
@@ -108,6 +109,11 @@ class SettingsDialogFragment : BottomSheetDialogFragment() {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.settingsActivity.setSafeOnClickListener {
|
||||
startActivity(Intent(activity, FeedActivity::class.java))
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.settingsNotification.setOnClickListener {
|
||||
startActivity(Intent(activity, NotificationActivity::class.java))
|
||||
dismiss()
|
||||
|
||||
Reference in New Issue
Block a user