feat: statistics (wip)
This commit is contained in:
parent
533148069f
commit
500de4e45e
12 changed files with 690 additions and 356 deletions
|
@ -17,6 +17,7 @@ import android.content.res.Configuration
|
||||||
import android.content.res.Resources.getSystem
|
import android.content.res.Resources.getSystem
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
import android.media.MediaScannerConnection
|
import android.media.MediaScannerConnection
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.NetworkCapabilities.*
|
import android.net.NetworkCapabilities.*
|
||||||
|
@ -59,8 +60,15 @@ import ani.dantotsu.settings.saving.internal.PreferenceKeystore
|
||||||
import ani.dantotsu.settings.saving.internal.PreferenceKeystore.Companion.generateSalt
|
import ani.dantotsu.settings.saving.internal.PreferenceKeystore.Companion.generateSalt
|
||||||
import ani.dantotsu.subcriptions.NotificationClickReceiver
|
import ani.dantotsu.subcriptions.NotificationClickReceiver
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.RequestBuilder
|
||||||
|
import com.bumptech.glide.RequestManager
|
||||||
|
import com.bumptech.glide.load.DataSource
|
||||||
|
import com.bumptech.glide.load.engine.GlideException
|
||||||
import com.bumptech.glide.load.model.GlideUrl
|
import com.bumptech.glide.load.model.GlideUrl
|
||||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade
|
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade
|
||||||
|
import com.bumptech.glide.load.resource.gif.GifDrawable
|
||||||
|
import com.bumptech.glide.request.RequestListener
|
||||||
|
import com.bumptech.glide.request.target.Target
|
||||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
|
@ -68,6 +76,17 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
import com.google.android.material.internal.ViewUtils
|
import com.google.android.material.internal.ViewUtils
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||||
|
import io.noties.markwon.AbstractMarkwonPlugin
|
||||||
|
import io.noties.markwon.Markwon
|
||||||
|
import io.noties.markwon.MarkwonConfiguration
|
||||||
|
import io.noties.markwon.SoftBreakAddsNewLinePlugin
|
||||||
|
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin
|
||||||
|
import io.noties.markwon.ext.tables.TablePlugin
|
||||||
|
import io.noties.markwon.ext.tasklist.TaskListPlugin
|
||||||
|
import io.noties.markwon.html.HtmlPlugin
|
||||||
|
import io.noties.markwon.html.TagHandlerNoOp
|
||||||
|
import io.noties.markwon.image.AsyncDrawable
|
||||||
|
import io.noties.markwon.image.glide.GlideImagesPlugin
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import nl.joery.animatedbottombar.AnimatedBottomBar
|
import nl.joery.animatedbottombar.AnimatedBottomBar
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
|
@ -1080,3 +1099,69 @@ fun logToFile(context: Context, message: String) {
|
||||||
file.appendText(message)
|
file.appendText(message)
|
||||||
file.appendText("\n")
|
file.appendText("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the markwon instance with all the plugins
|
||||||
|
* @return the markwon instance
|
||||||
|
*/
|
||||||
|
fun buildMarkwon(activity: Activity, userInputContent: Boolean = true): Markwon {
|
||||||
|
val markwon = Markwon.builder(activity)
|
||||||
|
.usePlugin(object : AbstractMarkwonPlugin() {
|
||||||
|
override fun configureConfiguration(builder: MarkwonConfiguration.Builder) {
|
||||||
|
builder.linkResolver { view, link ->
|
||||||
|
copyToClipboard(link, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
.usePlugin(SoftBreakAddsNewLinePlugin.create())
|
||||||
|
.usePlugin(StrikethroughPlugin.create())
|
||||||
|
.usePlugin(TablePlugin.create(activity))
|
||||||
|
.usePlugin(TaskListPlugin.create(activity))
|
||||||
|
.usePlugin(HtmlPlugin.create { plugin ->
|
||||||
|
if (!userInputContent) {
|
||||||
|
plugin.addHandler(
|
||||||
|
TagHandlerNoOp.create("h1", "h2", "h3", "h4", "h5", "h6", "hr", "pre", "a")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.usePlugin(GlideImagesPlugin.create(object : GlideImagesPlugin.GlideStore {
|
||||||
|
|
||||||
|
private val requestManager: RequestManager =
|
||||||
|
Glide.with(activity).apply {
|
||||||
|
addDefaultRequestListener(object : RequestListener<Any> {
|
||||||
|
override fun onResourceReady(
|
||||||
|
resource: Any,
|
||||||
|
model: Any,
|
||||||
|
target: Target<Any>,
|
||||||
|
dataSource: DataSource,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
if (resource is GifDrawable) {
|
||||||
|
resource.start()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLoadFailed(
|
||||||
|
e: GlideException?,
|
||||||
|
model: Any?,
|
||||||
|
target: Target<Any>,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun load(drawable: AsyncDrawable): RequestBuilder<Drawable> {
|
||||||
|
return requestManager.load(drawable.destination)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun cancel(target: Target<*>) {
|
||||||
|
requestManager.clear(target)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.build()
|
||||||
|
return markwon
|
||||||
|
}
|
|
@ -10,12 +10,8 @@ import ani.dantotsu.R
|
||||||
import ani.dantotsu.connections.comments.Comment
|
import ani.dantotsu.connections.comments.Comment
|
||||||
import ani.dantotsu.connections.comments.CommentsAPI
|
import ani.dantotsu.connections.comments.CommentsAPI
|
||||||
import ani.dantotsu.copyToClipboard
|
import ani.dantotsu.copyToClipboard
|
||||||
import ani.dantotsu.currActivity
|
|
||||||
import ani.dantotsu.currContext
|
|
||||||
import ani.dantotsu.databinding.ItemCommentsBinding
|
import ani.dantotsu.databinding.ItemCommentsBinding
|
||||||
import ani.dantotsu.loadImage
|
import ani.dantotsu.loadImage
|
||||||
import ani.dantotsu.media.user.ListActivity
|
|
||||||
import ani.dantotsu.openLinkInBrowser
|
|
||||||
import ani.dantotsu.profile.ProfileActivity
|
import ani.dantotsu.profile.ProfileActivity
|
||||||
import ani.dantotsu.snackString
|
import ani.dantotsu.snackString
|
||||||
import com.xwray.groupie.GroupieAdapter
|
import com.xwray.groupie.GroupieAdapter
|
||||||
|
@ -56,7 +52,7 @@ class CommentItem(val comment: Comment,
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun bind(viewBinding: ItemCommentsBinding, position: Int) {
|
override fun bind(viewBinding: ItemCommentsBinding, position: Int) {
|
||||||
binding = viewBinding
|
binding = viewBinding
|
||||||
viewBinding.commentRepliesList.layoutManager = LinearLayoutManager(currActivity())
|
viewBinding.commentRepliesList.layoutManager = LinearLayoutManager(commentsFragment.activity)
|
||||||
viewBinding.commentRepliesList.adapter = adapter
|
viewBinding.commentRepliesList.adapter = adapter
|
||||||
val isUserComment = CommentsAPI.userId == comment.userId
|
val isUserComment = CommentsAPI.userId == comment.userId
|
||||||
val node = markwon.parse(comment.content)
|
val node = markwon.parse(comment.content)
|
||||||
|
@ -101,7 +97,7 @@ class CommentItem(val comment: Comment,
|
||||||
|
|
||||||
viewBinding.commentUserName.setOnClickListener {
|
viewBinding.commentUserName.setOnClickListener {
|
||||||
ContextCompat.startActivity(
|
ContextCompat.startActivity(
|
||||||
currContext()!!, Intent(currContext()!!, ProfileActivity::class.java)
|
commentsFragment.activity, Intent(commentsFragment.activity, ProfileActivity::class.java)
|
||||||
.putExtra("userId", comment.userId.toInt())
|
.putExtra("userId", comment.userId.toInt())
|
||||||
.putExtra("username","[${levelColor.second}]"), null
|
.putExtra("username","[${levelColor.second}]"), null
|
||||||
)
|
)
|
||||||
|
@ -215,12 +211,12 @@ class CommentItem(val comment: Comment,
|
||||||
}
|
}
|
||||||
|
|
||||||
fun replying(isReplying: Boolean) {
|
fun replying(isReplying: Boolean) {
|
||||||
binding?.commentReply?.text = if (isReplying) currActivity()!!.getString(R.string.cancel) else "Reply"
|
binding?.commentReply?.text = if (isReplying) commentsFragment.activity.getString(R.string.cancel) else "Reply"
|
||||||
this.isReplying = isReplying
|
this.isReplying = isReplying
|
||||||
}
|
}
|
||||||
|
|
||||||
fun editing(isEditing: Boolean) {
|
fun editing(isEditing: Boolean) {
|
||||||
binding?.commentEdit?.text = if (isEditing) currActivity()!!.getString(R.string.cancel) else currActivity()!!.getString(R.string.edit)
|
binding?.commentEdit?.text = if (isEditing) commentsFragment.activity.getString(R.string.cancel) else commentsFragment.activity.getString(R.string.edit)
|
||||||
this.isEditing = isEditing
|
this.isEditing = isEditing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import ani.dantotsu.R
|
import ani.dantotsu.R
|
||||||
|
import ani.dantotsu.buildMarkwon
|
||||||
import ani.dantotsu.connections.anilist.Anilist
|
import ani.dantotsu.connections.anilist.Anilist
|
||||||
import ani.dantotsu.connections.comments.Comment
|
import ani.dantotsu.connections.comments.Comment
|
||||||
import ani.dantotsu.connections.comments.CommentResponse
|
import ani.dantotsu.connections.comments.CommentResponse
|
||||||
|
@ -100,7 +101,7 @@ class CommentsFragment : Fragment() {
|
||||||
this.mediaId = mediaId
|
this.mediaId = mediaId
|
||||||
backgroundColor = (binding.root.background as? ColorDrawable)?.color ?: 0
|
backgroundColor = (binding.root.background as? ColorDrawable)?.color ?: 0
|
||||||
|
|
||||||
val markwon = buildMarkwon()
|
val markwon = buildMarkwon(activity)
|
||||||
|
|
||||||
binding.commentUserAvatar.loadImage(Anilist.avatar)
|
binding.commentUserAvatar.loadImage(Anilist.avatar)
|
||||||
val markwonEditor = MarkwonEditor.create(markwon)
|
val markwonEditor = MarkwonEditor.create(markwon)
|
||||||
|
@ -235,7 +236,7 @@ class CommentsFragment : Fragment() {
|
||||||
section.add(
|
section.add(
|
||||||
CommentItem(
|
CommentItem(
|
||||||
comment,
|
comment,
|
||||||
buildMarkwon(),
|
buildMarkwon(activity),
|
||||||
section,
|
section,
|
||||||
this@CommentsFragment,
|
this@CommentsFragment,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
|
@ -386,7 +387,7 @@ class CommentsFragment : Fragment() {
|
||||||
section.add(
|
section.add(
|
||||||
CommentItem(
|
CommentItem(
|
||||||
it,
|
it,
|
||||||
buildMarkwon(),
|
buildMarkwon(activity),
|
||||||
section,
|
section,
|
||||||
this@CommentsFragment,
|
this@CommentsFragment,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
|
@ -416,7 +417,7 @@ class CommentsFragment : Fragment() {
|
||||||
section.add(
|
section.add(
|
||||||
CommentItem(
|
CommentItem(
|
||||||
comment,
|
comment,
|
||||||
buildMarkwon(),
|
buildMarkwon(activity),
|
||||||
section,
|
section,
|
||||||
this@CommentsFragment,
|
this@CommentsFragment,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
|
@ -539,7 +540,7 @@ class CommentsFragment : Fragment() {
|
||||||
if (depth >= comment.MAX_DEPTH) comment.registerSubComment(it.commentId)
|
if (depth >= comment.MAX_DEPTH) comment.registerSubComment(it.commentId)
|
||||||
val newCommentItem = CommentItem(
|
val newCommentItem = CommentItem(
|
||||||
it,
|
it,
|
||||||
buildMarkwon(),
|
buildMarkwon(activity),
|
||||||
section,
|
section,
|
||||||
this@CommentsFragment,
|
this@CommentsFragment,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
|
@ -664,7 +665,7 @@ class CommentsFragment : Fragment() {
|
||||||
if (commentWithInteraction!!.commentDepth + 1 > commentWithInteraction!!.MAX_DEPTH) 0 else section.itemCount,
|
if (commentWithInteraction!!.commentDepth + 1 > commentWithInteraction!!.MAX_DEPTH) 0 else section.itemCount,
|
||||||
CommentItem(
|
CommentItem(
|
||||||
it,
|
it,
|
||||||
buildMarkwon(),
|
buildMarkwon(activity),
|
||||||
section,
|
section,
|
||||||
this@CommentsFragment,
|
this@CommentsFragment,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
|
@ -676,7 +677,7 @@ class CommentsFragment : Fragment() {
|
||||||
0,
|
0,
|
||||||
CommentItem(
|
CommentItem(
|
||||||
it,
|
it,
|
||||||
buildMarkwon(),
|
buildMarkwon(activity),
|
||||||
section,
|
section,
|
||||||
this@CommentsFragment,
|
this@CommentsFragment,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
|
@ -686,68 +687,4 @@ class CommentsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the markwon instance with all the plugins
|
|
||||||
* @return the markwon instance
|
|
||||||
*/
|
|
||||||
private fun buildMarkwon(): Markwon {
|
|
||||||
val markwon = Markwon.builder(activity)
|
|
||||||
.usePlugin(object : AbstractMarkwonPlugin() {
|
|
||||||
override fun configureConfiguration(builder: MarkwonConfiguration.Builder) {
|
|
||||||
builder.linkResolver { view, link ->
|
|
||||||
copyToClipboard(link, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
.usePlugin(SoftBreakAddsNewLinePlugin.create())
|
|
||||||
.usePlugin(StrikethroughPlugin.create())
|
|
||||||
.usePlugin(TablePlugin.create(activity))
|
|
||||||
.usePlugin(TaskListPlugin.create(activity))
|
|
||||||
.usePlugin(HtmlPlugin.create { plugin ->
|
|
||||||
plugin.addHandler(
|
|
||||||
TagHandlerNoOp.create("h1", "h2", "h3", "h4", "h5", "h6", "hr", "pre", "a")
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.usePlugin(GlideImagesPlugin.create(object : GlideImagesPlugin.GlideStore {
|
|
||||||
|
|
||||||
private val requestManager: RequestManager =
|
|
||||||
Glide.with(this@CommentsFragment).apply {
|
|
||||||
addDefaultRequestListener(object : RequestListener<Any> {
|
|
||||||
override fun onResourceReady(
|
|
||||||
resource: Any,
|
|
||||||
model: Any,
|
|
||||||
target: Target<Any>,
|
|
||||||
dataSource: DataSource,
|
|
||||||
isFirstResource: Boolean
|
|
||||||
): Boolean {
|
|
||||||
if (resource is GifDrawable) {
|
|
||||||
resource.start()
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLoadFailed(
|
|
||||||
e: GlideException?,
|
|
||||||
model: Any?,
|
|
||||||
target: Target<Any>,
|
|
||||||
isFirstResource: Boolean
|
|
||||||
): Boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun load(drawable: AsyncDrawable): RequestBuilder<Drawable> {
|
|
||||||
return requestManager.load(drawable.destination)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun cancel(target: Target<*>) {
|
|
||||||
requestManager.clear(target)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.build()
|
|
||||||
return markwon
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -6,58 +6,123 @@ import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
|
import ani.dantotsu.R
|
||||||
import ani.dantotsu.connections.anilist.Anilist
|
import ani.dantotsu.connections.anilist.Anilist
|
||||||
|
import ani.dantotsu.connections.anilist.api.Query
|
||||||
import ani.dantotsu.databinding.ActivityProfileBinding
|
import ani.dantotsu.databinding.ActivityProfileBinding
|
||||||
|
import ani.dantotsu.initActivity
|
||||||
import ani.dantotsu.loadImage
|
import ani.dantotsu.loadImage
|
||||||
|
import ani.dantotsu.media.Media
|
||||||
|
import ani.dantotsu.media.MediaDetailsActivity
|
||||||
import ani.dantotsu.media.user.ListActivity
|
import ani.dantotsu.media.user.ListActivity
|
||||||
|
import ani.dantotsu.others.ImageViewDialog
|
||||||
|
import ani.dantotsu.snackString
|
||||||
|
import ani.dantotsu.themes.ThemeManager
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import nl.joery.animatedbottombar.AnimatedBottomBar
|
||||||
|
|
||||||
|
|
||||||
class ProfileActivity : AppCompatActivity(){
|
class ProfileActivity : AppCompatActivity(){
|
||||||
private lateinit var binding: ActivityProfileBinding
|
private lateinit var binding: ActivityProfileBinding
|
||||||
|
private var selected: Int = 0
|
||||||
|
private lateinit var tabLayout: AnimatedBottomBar
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
ThemeManager(this).applyTheme()
|
||||||
|
initActivity(this)
|
||||||
binding = ActivityProfileBinding.inflate(layoutInflater)
|
binding = ActivityProfileBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
tabLayout = binding.typeTab
|
||||||
|
val profileTab = tabLayout.createTab(R.drawable.ic_round_person_24, "Profile")
|
||||||
|
val statsTab = tabLayout.createTab(R.drawable.ic_stats_24, "Stats")
|
||||||
|
tabLayout.addTab(profileTab)
|
||||||
|
tabLayout.addTab(statsTab)
|
||||||
|
tabLayout.visibility = View.GONE
|
||||||
|
binding.mediaViewPager.isUserInputEnabled = false
|
||||||
|
|
||||||
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
val userid = intent.getIntExtra("userId", 0)
|
val userid = intent.getIntExtra("userId", 0)
|
||||||
val respond = Anilist.query.getUserProfile(userid)
|
val respond = Anilist.query.getUserProfile(userid)
|
||||||
val user = respond?.data?.user ?: return@launch
|
val user = respond?.data?.user
|
||||||
val userLevel = intent.getStringExtra("username")
|
if (user == null) {
|
||||||
|
snackString("User not found")
|
||||||
|
finish()
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
binding.mediaViewPager.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle, user, this@ProfileActivity)
|
||||||
|
tabLayout.visibility = View.VISIBLE
|
||||||
|
tabLayout.selectTabAt(selected)
|
||||||
|
tabLayout.setOnTabSelectListener(object : AnimatedBottomBar.OnTabSelectListener {
|
||||||
|
override fun onTabSelected(
|
||||||
|
lastIndex: Int,
|
||||||
|
lastTab: AnimatedBottomBar.Tab?,
|
||||||
|
newIndex: Int,
|
||||||
|
newTab: AnimatedBottomBar.Tab
|
||||||
|
) {
|
||||||
|
selected = newIndex
|
||||||
|
binding.mediaViewPager.setCurrentItem(selected, true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
val userLevel = intent.getStringExtra("username")?: ""
|
||||||
|
|
||||||
binding.profileProgressBar.visibility = View.GONE
|
binding.profileProgressBar.visibility = View.GONE
|
||||||
binding.profileBannerImage.loadImage(user.bannerImage)
|
binding.profileBannerImage.loadImage(user.bannerImage)
|
||||||
binding.profileUserAvatar.loadImage(user.avatar?.medium)
|
binding.profileUserAvatar.loadImage(user.avatar?.medium)
|
||||||
binding.profileUserName.text = "${user.name} $userLevel"
|
binding.profileUserName.text = "${user.name} $userLevel"
|
||||||
binding.profileUserInfo.text = user.about
|
|
||||||
binding.profileAnimeList.setOnClickListener {
|
|
||||||
ContextCompat.startActivity(
|
|
||||||
this@ProfileActivity, Intent(this@ProfileActivity, ListActivity::class.java)
|
|
||||||
.putExtra("anime", true)
|
|
||||||
.putExtra("userId", user.id)
|
|
||||||
.putExtra("username", user.name), null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
binding.profileMangaList.setOnClickListener {
|
|
||||||
ContextCompat.startActivity(
|
|
||||||
this@ProfileActivity, Intent(this@ProfileActivity, ListActivity::class.java)
|
|
||||||
.putExtra("anime", false)
|
|
||||||
.putExtra("userId", user.id)
|
|
||||||
.putExtra("username", user.name), null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
binding.profileUserEpisodesWatched.text = user.statistics.anime.episodesWatched.toString()
|
binding.profileUserEpisodesWatched.text = user.statistics.anime.episodesWatched.toString()
|
||||||
binding.profileUserChaptersRead.text = user.statistics.manga.chaptersRead.toString()
|
binding.profileUserChaptersRead.text = user.statistics.manga.chaptersRead.toString()
|
||||||
|
|
||||||
binding.profileAnimeListImage.loadImage("https://bit.ly/31bsIHq")
|
binding.profileBannerImage.loadImage(user.bannerImage)
|
||||||
binding.profileMangaListImage.loadImage("https://bit.ly/2ZGfcuG")
|
binding.profileBannerImage.setOnLongClickListener {
|
||||||
|
ImageViewDialog.newInstance(
|
||||||
|
this@ProfileActivity,
|
||||||
|
user.name + " [Banner]",
|
||||||
|
user.bannerImage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
binding.profileUserAvatar.loadImage(user.avatar?.medium)
|
||||||
|
binding.profileUserAvatar.setOnLongClickListener {
|
||||||
|
ImageViewDialog.newInstance(
|
||||||
|
this@ProfileActivity,
|
||||||
|
user.name + " [Avatar]",
|
||||||
|
user.avatar?.medium
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
if (this::tabLayout.isInitialized) {
|
||||||
|
tabLayout.selectTabAt(selected)
|
||||||
|
}
|
||||||
|
super.onResume()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ViewPagerAdapter(
|
||||||
|
fragmentManager: FragmentManager,
|
||||||
|
lifecycle: Lifecycle,
|
||||||
|
private val user: Query.UserProfile,
|
||||||
|
private val activity: ProfileActivity
|
||||||
|
) :
|
||||||
|
FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||||
|
|
||||||
|
override fun getItemCount(): Int = 2
|
||||||
|
override fun createFragment(position: Int): Fragment = when (position) {
|
||||||
|
0 -> ProfileFragment(user, activity)
|
||||||
|
1 -> StatsFragment(user, activity)
|
||||||
|
else -> ProfileFragment(user, activity)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
50
app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt
Normal file
50
app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package ani.dantotsu.profile
|
||||||
|
|
||||||
|
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.fragment.app.Fragment
|
||||||
|
import ani.dantotsu.buildMarkwon
|
||||||
|
import ani.dantotsu.connections.anilist.api.Query
|
||||||
|
import ani.dantotsu.databinding.FragmentProfileBinding
|
||||||
|
import ani.dantotsu.loadImage
|
||||||
|
import ani.dantotsu.media.user.ListActivity
|
||||||
|
|
||||||
|
class ProfileFragment(private val user: Query.UserProfile, private val activity: ProfileActivity): Fragment() {
|
||||||
|
lateinit var binding: FragmentProfileBinding
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
binding = FragmentProfileBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
val markwon = buildMarkwon(activity, false)
|
||||||
|
markwon.setMarkdown(binding.profileUserInfo, user.about?:"")
|
||||||
|
binding.profileAnimeList.setOnClickListener {
|
||||||
|
ContextCompat.startActivity(
|
||||||
|
activity, Intent(activity, ListActivity::class.java)
|
||||||
|
.putExtra("anime", true)
|
||||||
|
.putExtra("userId", user.id)
|
||||||
|
.putExtra("username", user.name), null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
binding.profileMangaList.setOnClickListener {
|
||||||
|
ContextCompat.startActivity(
|
||||||
|
activity, Intent(activity, ListActivity::class.java)
|
||||||
|
.putExtra("anime", false)
|
||||||
|
.putExtra("userId", user.id)
|
||||||
|
.putExtra("username", user.name), null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
binding.profileAnimeListImage.loadImage("https://bit.ly/31bsIHq")
|
||||||
|
binding.profileMangaListImage.loadImage("https://bit.ly/2ZGfcuG")
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +0,0 @@
|
||||||
package ani.dantotsu.profile
|
|
||||||
|
|
||||||
class StatisticsActivity {
|
|
||||||
}
|
|
157
app/src/main/java/ani/dantotsu/profile/StatsFragment.kt
Normal file
157
app/src/main/java/ani/dantotsu/profile/StatsFragment.kt
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
package ani.dantotsu.profile
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import ani.dantotsu.R
|
||||||
|
import ani.dantotsu.connections.anilist.Anilist
|
||||||
|
import ani.dantotsu.connections.anilist.api.Query
|
||||||
|
import ani.dantotsu.databinding.FragmentStatisticsBinding
|
||||||
|
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartAlignType
|
||||||
|
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartLayoutType
|
||||||
|
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartModel
|
||||||
|
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartStackingType
|
||||||
|
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartType
|
||||||
|
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartVerticalAlignType
|
||||||
|
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartZoomType
|
||||||
|
import com.github.aachartmodel.aainfographics.aachartcreator.AADataElement
|
||||||
|
import com.github.aachartmodel.aainfographics.aachartcreator.AAOptions
|
||||||
|
import com.github.aachartmodel.aainfographics.aachartcreator.AASeriesElement
|
||||||
|
import com.github.aachartmodel.aainfographics.aachartcreator.aa_toAAOptions
|
||||||
|
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AAChart
|
||||||
|
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AALang
|
||||||
|
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AAPosition
|
||||||
|
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AAScrollablePlotArea
|
||||||
|
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AAStyle
|
||||||
|
import com.github.aachartmodel.aainfographics.aatools.AAColor
|
||||||
|
import com.github.aachartmodel.aainfographics.aatools.AAGradientColor
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import nl.joery.animatedbottombar.AnimatedBottomBar
|
||||||
|
|
||||||
|
class StatsFragment(private val user: Query.UserProfile, private val activity: ProfileActivity) :
|
||||||
|
Fragment() {
|
||||||
|
private lateinit var binding: FragmentStatisticsBinding
|
||||||
|
private var selected: Int = 0
|
||||||
|
private lateinit var tabLayout: AnimatedBottomBar
|
||||||
|
private var stats: Query.StatisticsResponse? = null
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
binding = FragmentStatisticsBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
tabLayout = binding.typeTab
|
||||||
|
val animeTab = tabLayout.createTab(R.drawable.ic_round_movie_filter_24, "Anime")
|
||||||
|
val mangaTab = tabLayout.createTab(R.drawable.ic_round_menu_book_24, "Manga")
|
||||||
|
tabLayout.addTab(animeTab)
|
||||||
|
tabLayout.addTab(mangaTab)
|
||||||
|
|
||||||
|
tabLayout.visibility = View.GONE
|
||||||
|
activity.lifecycleScope.launch {
|
||||||
|
stats = Anilist.query.getUserStatistics(user.id)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
tabLayout.visibility = View.VISIBLE
|
||||||
|
tabLayout.setOnTabSelectListener(object : AnimatedBottomBar.OnTabSelectListener {
|
||||||
|
override fun onTabSelected(
|
||||||
|
lastIndex: Int,
|
||||||
|
lastTab: AnimatedBottomBar.Tab?,
|
||||||
|
newIndex: Int,
|
||||||
|
newTab: AnimatedBottomBar.Tab
|
||||||
|
) {
|
||||||
|
selected = newIndex
|
||||||
|
when (newIndex) {
|
||||||
|
0 -> loadAnimeStats()
|
||||||
|
1 -> loadMangaStats()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
tabLayout.selectTabAt(selected)
|
||||||
|
loadAnimeStats()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
if (this::tabLayout.isInitialized) {
|
||||||
|
tabLayout.selectTabAt(selected)
|
||||||
|
}
|
||||||
|
super.onResume()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadAnimeStats() {
|
||||||
|
val formatChartModel = getFormatChartModel(true)
|
||||||
|
if (formatChartModel != null) {
|
||||||
|
val aaOptions = buildOptions(formatChartModel)
|
||||||
|
binding.formatChartView.aa_drawChartWithChartOptions(aaOptions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadMangaStats() {
|
||||||
|
val formatChartModel = getFormatChartModel(false)
|
||||||
|
if (formatChartModel != null) {
|
||||||
|
val aaOptions = buildOptions(formatChartModel)
|
||||||
|
binding.formatChartView.aa_drawChartWithChartOptions(aaOptions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildOptions(aaChartModel: AAChartModel): AAOptions {
|
||||||
|
val aaOptions = aaChartModel.aa_toAAOptions()
|
||||||
|
aaOptions.tooltip?.apply {
|
||||||
|
backgroundColor(AAGradientColor.PurpleLake)
|
||||||
|
.style(AAStyle.style(AAColor.White))
|
||||||
|
}
|
||||||
|
aaOptions.chart?.zoomType = "xy"
|
||||||
|
aaOptions.chart?.pinchType = "xy"
|
||||||
|
aaOptions.legend?.apply {
|
||||||
|
enabled(true)
|
||||||
|
.verticalAlign(AAChartVerticalAlignType.Top)
|
||||||
|
.layout(AAChartLayoutType.Vertical)
|
||||||
|
.align(AAChartAlignType.Right)
|
||||||
|
.itemMarginTop(10f)
|
||||||
|
.labelFormat = "{name}: {y}"
|
||||||
|
}
|
||||||
|
aaOptions.plotOptions?.series?.connectNulls(true)
|
||||||
|
return aaOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFormatChartModel(anime: Boolean): AAChartModel? {
|
||||||
|
val fotmatTypes: List<String> = if (anime) {
|
||||||
|
stats?.data?.user?.statistics?.anime?.formats?.map { it.format } ?: emptyList()
|
||||||
|
} else {
|
||||||
|
stats?.data?.user?.statistics?.manga?.formats?.map { it.format } ?: emptyList()
|
||||||
|
}
|
||||||
|
val formatCount: List<Int> = if (anime) {
|
||||||
|
stats?.data?.user?.statistics?.anime?.formats?.map { it.count } ?: emptyList()
|
||||||
|
} else {
|
||||||
|
stats?.data?.user?.statistics?.manga?.formats?.map { it.count } ?: emptyList()
|
||||||
|
}
|
||||||
|
if (fotmatTypes.isEmpty() || formatCount.isEmpty())
|
||||||
|
return null
|
||||||
|
return AAChartModel()
|
||||||
|
.chartType(AAChartType.Pie)
|
||||||
|
.title("Format")
|
||||||
|
.zoomType(AAChartZoomType.XY)
|
||||||
|
.dataLabelsEnabled(true)
|
||||||
|
.series(getElements(fotmatTypes, formatCount))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getElements(types: List<String>, counts: List<Int>): Array<Any> {
|
||||||
|
val elements = AASeriesElement()
|
||||||
|
val dataElements = mutableListOf<AADataElement>()
|
||||||
|
for (i in types.indices) {
|
||||||
|
dataElements.add(AADataElement().name(types[i]).y(counts[i]))
|
||||||
|
}
|
||||||
|
return arrayOf(elements.data(dataElements.toTypedArray()))
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="32dp"
|
android:width="32dp"
|
||||||
android:height="32dp"
|
android:height="32dp"
|
||||||
android:tint="@color/bg_opp"
|
android:tint="?attr/colorControlNormal"
|
||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24">
|
android:viewportHeight="24">
|
||||||
<path
|
<path
|
||||||
|
|
10
app/src/main/res/drawable/ic_stats_24.xml
Normal file
10
app/src/main/res/drawable/ic_stats_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorControlNormal"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M160,800v-320h160v320L160,800ZM400,800v-640h160v640L400,800ZM640,800v-440h160v440L640,800Z"/>
|
||||||
|
</vector>
|
|
@ -1,10 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/profileProgressBar"
|
android:id="@+id/profileProgressBar"
|
||||||
|
@ -12,16 +12,22 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
tools:visibility="gone">
|
tools:visibility="gone">
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
style="?android:attr/progressBarStyle"
|
style="?android:attr/progressBarStyle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="72dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/profileTopContainer"
|
android:id="@+id/profileTopContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
@ -36,27 +42,27 @@
|
||||||
android:id="@+id/profileUserAvatarContainer"
|
android:id="@+id/profileUserAvatarContainer"
|
||||||
android:layout_width="82dp"
|
android:layout_width="82dp"
|
||||||
android:layout_height="82dp"
|
android:layout_height="82dp"
|
||||||
|
android:layout_gravity="end"
|
||||||
android:layout_marginTop="-52dp"
|
android:layout_marginTop="-52dp"
|
||||||
android:layout_marginEnd="32dp"
|
android:layout_marginEnd="32dp"
|
||||||
android:layout_gravity="end"
|
|
||||||
app:cardCornerRadius="40dp">
|
app:cardCornerRadius="40dp">
|
||||||
|
|
||||||
<com.google.android.material.imageview.ShapeableImageView
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
android:id="@+id/profileUserAvatar"
|
android:id="@+id/profileUserAvatar"
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_width="78dp"
|
android:layout_width="78dp"
|
||||||
android:layout_height="78dp"
|
android:layout_height="78dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
app:srcCompat="@drawable/ic_round_add_circle_24"
|
app:srcCompat="@drawable/ic_round_add_circle_24"
|
||||||
tools:ignore="ContentDescription,ImageContrastCheck" />
|
tools:ignore="ContentDescription,ImageContrastCheck" />
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/profileUserDataContainer"
|
android:id="@+id/profileUserDataContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="18dp"
|
android:layout_marginStart="18dp"
|
||||||
|
android:layout_marginTop="-32dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
@ -115,152 +121,41 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="18dp"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:fontFamily="@font/poppins_semi_bold"
|
|
||||||
android:text="List"
|
|
||||||
android:textSize="18sp"
|
|
||||||
tools:ignore="HardcodedText" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:id="@+id/profileListContainer"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:paddingStart="24dp"
|
|
||||||
android:paddingEnd="24dp">
|
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
|
||||||
android:id="@+id/profileAnimeList"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="72dp"
|
|
||||||
android:layout_margin="8dp"
|
|
||||||
app:boxStrokeColor="@color/text_input_layout_stroke_color"
|
|
||||||
app:cardCornerRadius="16dp"
|
|
||||||
app:layout_constrainedWidth="true"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/profileMangaList"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintWidth_max="256dp"
|
|
||||||
tools:visibility="visible">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/profileAnimeListImage"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
tools:ignore="ContentDescription"
|
|
||||||
tools:src="@tools:sample/backgrounds/scenic" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:alpha="0.6"
|
|
||||||
android:background="@color/bg_black" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="center"
|
android:orientation="vertical"
|
||||||
android:orientation="vertical">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
<TextView
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/mediaViewPager"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_gravity="center"
|
android:layout_height="match_parent"
|
||||||
android:fontFamily="@font/poppins_bold"
|
android:nestedScrollingEnabled="true"
|
||||||
android:text="@string/anime_list"
|
tools:ignore="SpeakableTextPresentCheck" />
|
||||||
android:textAllCaps="true"
|
|
||||||
android:textColor="@color/bg_white"
|
|
||||||
android:textSize="16sp" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="64dp"
|
|
||||||
android:layout_height="2dp"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:background="?attr/colorPrimary" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
|
||||||
android:id="@+id/profileMangaList"
|
<nl.joery.animatedbottombar.AnimatedBottomBar
|
||||||
|
android:id="@+id/typeTab"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="72dp"
|
android:layout_height="72dp"
|
||||||
android:layout_margin="8dp"
|
android:layout_gravity="center_horizontal|bottom"
|
||||||
android:layout_marginBottom="16dp"
|
android:background="?attr/colorSurface"
|
||||||
app:boxStrokeColor="@color/text_input_layout_stroke_color"
|
android:padding="0dp"
|
||||||
app:cardCornerRadius="16dp"
|
app:abb_animationInterpolator="@anim/over_shoot"
|
||||||
app:layout_constrainedWidth="true"
|
app:abb_indicatorAppearance="round"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:abb_indicatorLocation="top"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:abb_selectedTabType="text"
|
||||||
app:layout_constraintStart_toEndOf="@+id/profileAnimeList"
|
app:abb_textAppearance="@style/NavBarText"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:itemActiveIndicatorStyle="@style/BottomNavBar"
|
||||||
app:layout_constraintWidth_max="256dp"
|
app:itemIconTint="@color/tab_layout_icon"
|
||||||
tools:visibility="visible">
|
app:itemRippleColor="#00000000"
|
||||||
|
app:itemTextAppearanceActive="@style/NavBarText"
|
||||||
<ImageView
|
app:itemTextAppearanceInactive="@style/NavBarText"
|
||||||
android:id="@+id/profileMangaListImage"
|
app:itemTextColor="@color/tab_layout_icon" />
|
||||||
android:layout_width="match_parent"
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
tools:ignore="ContentDescription"
|
|
||||||
tools:src="@tools:sample/backgrounds/scenic" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:alpha="0.6"
|
|
||||||
android:background="@color/bg_black" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:fontFamily="@font/poppins_bold"
|
|
||||||
android:text="@string/manga_list"
|
|
||||||
android:textAllCaps="true"
|
|
||||||
android:textColor="@color/bg_white"
|
|
||||||
android:textSize="16sp" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="64dp"
|
|
||||||
android:layout_height="2dp"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:background="?attr/colorPrimary" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="18dp"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:fontFamily="@font/poppins_semi_bold"
|
|
||||||
android:text="Info"
|
|
||||||
android:textSize="18sp"
|
|
||||||
tools:ignore="HardcodedText" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/profileUserInfo"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:fontFamily="@font/poppins_semi_bold"
|
|
||||||
android:layout_marginStart="18dp"
|
|
||||||
android:layout_marginEnd="18dp"
|
|
||||||
android:text="info"
|
|
||||||
android:alpha="0.58"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
156
app/src/main/res/layout/fragment_profile.xml
Normal file
156
app/src/main/res/layout/fragment_profile.xml
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="18dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:fontFamily="@font/poppins_semi_bold"
|
||||||
|
android:text="List"
|
||||||
|
android:textSize="18sp"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/profileListContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingStart="24dp"
|
||||||
|
android:paddingEnd="24dp">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/profileAnimeList"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="72dp"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
app:boxStrokeColor="@color/text_input_layout_stroke_color"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:layout_constrainedWidth="true"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/profileMangaList"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintWidth_max="256dp"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/profileAnimeListImage"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:ignore="ContentDescription"
|
||||||
|
tools:src="@tools:sample/backgrounds/scenic" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:alpha="0.6"
|
||||||
|
android:background="@color/bg_black" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:fontFamily="@font/poppins_bold"
|
||||||
|
android:text="@string/anime_list"
|
||||||
|
android:textAllCaps="true"
|
||||||
|
android:textColor="@color/bg_white"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="64dp"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:background="?attr/colorPrimary" />
|
||||||
|
</LinearLayout>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/profileMangaList"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="72dp"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
app:boxStrokeColor="@color/text_input_layout_stroke_color"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:layout_constrainedWidth="true"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/profileAnimeList"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintWidth_max="256dp"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/profileMangaListImage"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:ignore="ContentDescription"
|
||||||
|
tools:src="@tools:sample/backgrounds/scenic" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:alpha="0.6"
|
||||||
|
android:background="@color/bg_black" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:fontFamily="@font/poppins_bold"
|
||||||
|
android:text="@string/manga_list"
|
||||||
|
android:textAllCaps="true"
|
||||||
|
android:textColor="@color/bg_white"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="64dp"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:background="?attr/colorPrimary" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="18dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:fontFamily="@font/poppins_semi_bold"
|
||||||
|
android:text="Info"
|
||||||
|
android:textSize="18sp"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/profileUserInfo"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/poppins_semi_bold"
|
||||||
|
android:layout_marginStart="18dp"
|
||||||
|
android:layout_marginEnd="18dp"
|
||||||
|
android:text="info"
|
||||||
|
android:alpha="0.58"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
</LinearLayout>
|
|
@ -1,12 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<nl.joery.animatedbottombar.AnimatedBottomBar
|
<nl.joery.animatedbottombar.AnimatedBottomBar
|
||||||
|
@ -28,15 +25,6 @@
|
||||||
app:itemTextAppearanceInactive="@style/NavBarText"
|
app:itemTextAppearanceInactive="@style/NavBarText"
|
||||||
app:itemTextColor="@color/tab_layout_icon" />
|
app:itemTextColor="@color/tab_layout_icon" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/selectedTabText"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="10dp"
|
|
||||||
android:text="Anime"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<com.github.aachartmodel.aainfographics.aachartcreator.AAChartView
|
<com.github.aachartmodel.aainfographics.aachartcreator.AAChartView
|
||||||
android:id="@+id/formatChartView"
|
android:id="@+id/formatChartView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -97,4 +85,3 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="250dp" />
|
android:layout_height="250dp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
Loading…
Add table
Add a link
Reference in a new issue