Merge branch 'dev' into custom-download-location

This commit is contained in:
rebel onion
2024-04-04 04:03:34 -05:00
committed by GitHub
31 changed files with 544 additions and 306 deletions

View File

@@ -214,7 +214,8 @@ fun initActivity(a: Activity) {
window,
window.decorView
).hide(WindowInsetsCompat.Type.statusBars())
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && statusBarHeight == 0 && a.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && statusBarHeight == 0
&& a.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
window.decorView.rootWindowInsets?.displayCutout?.apply {
if (boundingRects.size > 0) {
statusBarHeight = min(boundingRects[0].width(), boundingRects[0].height())

View File

@@ -898,6 +898,7 @@ class AnilistQueries {
season: String? = null,
id: Int? = null,
hd: Boolean = false,
adultOnly: Boolean = false
): SearchResults? {
val query = """
query (${"$"}page: Int = 1, ${"$"}id: Int, ${"$"}type: MediaType, ${"$"}isAdult: Boolean = false, ${"$"}search: String, ${"$"}format: [MediaFormat], ${"$"}status: MediaStatus, ${"$"}countryOfOrigin: CountryCode, ${"$"}source: MediaSource, ${"$"}season: MediaSeason, ${"$"}seasonYear: Int, ${"$"}year: String, ${"$"}onList: Boolean, ${"$"}yearLesser: FuzzyDateInt, ${"$"}yearGreater: FuzzyDateInt, ${"$"}episodeLesser: Int, ${"$"}episodeGreater: Int, ${"$"}durationLesser: Int, ${"$"}durationGreater: Int, ${"$"}chapterLesser: Int, ${"$"}chapterGreater: Int, ${"$"}volumeLesser: Int, ${"$"}volumeGreater: Int, ${"$"}licensedBy: [String], ${"$"}isLicensed: Boolean, ${"$"}genres: [String], ${"$"}excludedGenres: [String], ${"$"}tags: [String], ${"$"}excludedTags: [String], ${"$"}minimumTagRank: Int, ${"$"}sort: [MediaSort] = [POPULARITY_DESC, SCORE_DESC, START_DATE_DESC]) {
@@ -945,6 +946,7 @@ query (${"$"}page: Int = 1, ${"$"}id: Int, ${"$"}type: MediaType, ${"$"}isAdult:
}
""".replace("\n", " ").replace(""" """, "")
val variables = """{"type":"$type","isAdult":$isAdult
${if (adultOnly) ""","isAdult":true""" else ""}
${if (onList != null) ""","onList":$onList""" else ""}
${if (page != null) ""","page":"$page"""" else ""}
${if (id != null) ""","id":"$id"""" else ""}

View File

@@ -137,7 +137,8 @@ class AnilistAnimeViewModel : ViewModel() {
sort = Anilist.sortBy[2],
season = season,
seasonYear = year,
hd = true
hd = true,
adultOnly = PrefManager.getVal(PrefName.AdultOnly)
)?.results
)
}
@@ -159,7 +160,8 @@ class AnilistAnimeViewModel : ViewModel() {
search = searchVal,
onList = if (onList) null else false,
sort = sort,
genres = genres
genres = genres,
adultOnly = PrefManager.getVal(PrefName.AdultOnly)
)
)
}
@@ -179,7 +181,8 @@ class AnilistAnimeViewModel : ViewModel() {
r.format,
r.countryOfOrigin,
r.isAdult,
r.onList
r.onList,
adultOnly = PrefManager.getVal(PrefName.AdultOnly),
)
)
@@ -244,7 +247,8 @@ class AnilistMangaViewModel : ViewModel() {
type,
perPage = 10,
sort = Anilist.sortBy[2],
hd = true
hd = true,
adultOnly = PrefManager.getVal(PrefName.AdultOnly)
)?.results
)
@@ -264,7 +268,8 @@ class AnilistMangaViewModel : ViewModel() {
search = searchVal,
onList = if (onList) null else false,
sort = sort,
genres = genres
genres = genres,
adultOnly = PrefManager.getVal(PrefName.AdultOnly)
)
)
}
@@ -289,7 +294,8 @@ class AnilistMangaViewModel : ViewModel() {
r.excludedTags,
r.startYear,
r.seasonYear,
r.season
r.season,
adultOnly = PrefManager.getVal(PrefName.AdultOnly)
)
)
@@ -353,7 +359,7 @@ class AnilistSearch : ViewModel() {
r.excludedTags,
r.startYear,
r.seasonYear,
r.season
r.season,
)
)

View File

@@ -0,0 +1,84 @@
package ani.dantotsu.connections.github
import ani.dantotsu.Mapper
import ani.dantotsu.R
import ani.dantotsu.client
import ani.dantotsu.getAppString
import ani.dantotsu.settings.Developer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.decodeFromJsonElement
class Contributors {
fun getContributors(): Array<Developer> {
var developers = arrayOf<Developer>()
runBlocking(Dispatchers.IO) {
val repo = getAppString(R.string.repo)
val res = client.get("https://api.github.com/repos/$repo/contributors")
.parsed<JsonArray>().map {
Mapper.json.decodeFromJsonElement<GithubResponse>(it)
}
res.find { it.login == "rebelonion"}?.let { first ->
developers = developers.plus(
Developer(
first.login,
first.avatarUrl,
"Owner and Maintainer",
first.htmlUrl
)
).plus(arrayOf(
Developer(
"Wai What",
"https://avatars.githubusercontent.com/u/149729762?v=4",
"Icon Designer",
"https://github.com/WaiWhat"
),
Developer(
"MarshMeadow",
"https://avatars.githubusercontent.com/u/88599122?v=4",
"Beta Icon Designer",
"https://github.com/MarshMeadow?tab=repositories"
),
Developer(
"Zaxx69",
"https://avatars.githubusercontent.com/u/138523882?v=4",
"Telegram Admin",
"https://github.com/Zaxx69"
),
Developer(
"Arif Alam",
"https://avatars.githubusercontent.com/u/70383209?v=4",
"Head Discord Moderator",
"https://youtube.com/watch?v=dQw4w9WgXcQ"
)
))
}
res.filter {it.login != "rebelonion"}.forEach {
developers = developers.plus(
Developer(
it.login,
it.avatarUrl,
"Contributor",
it.htmlUrl
)
)
}
}
return developers
}
@Serializable
data class GithubResponse(
@SerialName("login")
val login: String,
@SerialName("avatar_url")
val avatarUrl: String,
@SerialName("html_url")
val htmlUrl: String
)
}

View File

@@ -0,0 +1,55 @@
package ani.dantotsu.connections.github
import ani.dantotsu.Mapper
import ani.dantotsu.R
import ani.dantotsu.client
import ani.dantotsu.getAppString
import ani.dantotsu.settings.Developer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.decodeFromJsonElement
class Forks {
fun getForks(): Array<Developer> {
var forks = arrayOf<Developer>()
runBlocking(Dispatchers.IO) {
val res = client.get("https://api.github.com/repos/rebelonion/Dantotsu/forks")
.parsed<JsonArray>().map {
Mapper.json.decodeFromJsonElement<GithubResponse>(it)
}
res.forEach {
forks = forks.plus(
Developer(
it.name,
it.owner.avatarUrl,
it.owner.login,
it.htmlUrl
)
)
}
}
return forks
}
@Serializable
data class GithubResponse(
@SerialName("name")
val name: String,
val owner: Owner,
@SerialName("html_url")
val htmlUrl: String,
) {
@Serializable
data class Owner(
@SerialName("login")
val login: String,
@SerialName("avatar_url")
val avatarUrl: String
)
}
}

View File

@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.view.View
import android.widget.PopupMenu
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.R
@@ -34,13 +35,15 @@ import java.util.TimeZone
import kotlin.math.abs
import kotlin.math.sqrt
class CommentItem(val comment: Comment,
private val markwon: Markwon,
val parentSection: Section,
private val commentsFragment: CommentsFragment,
private val backgroundColor: Int,
val commentDepth: Int
) : BindableItem<ItemCommentsBinding>() {
class CommentItem(
val comment: Comment,
private val markwon: Markwon,
val parentSection: Section,
private val commentsFragment: CommentsFragment,
private val backgroundColor: Int,
val commentDepth: Int
) :
BindableItem<ItemCommentsBinding>() {
lateinit var binding: ItemCommentsBinding
val adapter = GroupieAdapter()
private var subCommentIds: MutableList<Int> = mutableListOf()
@@ -62,9 +65,6 @@ class CommentItem(val comment: Comment,
val isUserComment = CommentsAPI.userId == comment.userId
val levelColor = getAvatarColor(comment.totalVotes, backgroundColor)
markwon.setMarkdown(viewBinding.commentText, comment.content)
viewBinding.commentDelete.visibility = if (isUserComment || CommentsAPI.isAdmin || CommentsAPI.isMod) View.VISIBLE else View.GONE
viewBinding.commentBanUser.visibility = if ((CommentsAPI.isAdmin || CommentsAPI.isMod) && !isUserComment) View.VISIBLE else View.GONE
viewBinding.commentReport.visibility = if (!isUserComment) View.VISIBLE else View.GONE
viewBinding.commentEdit.visibility = if (isUserComment) View.VISIBLE else View.GONE
if (comment.tag == null) {
viewBinding.commentUserTagLayout.visibility = View.GONE
@@ -140,41 +140,71 @@ class CommentItem(val comment: Comment,
}
viewBinding.modBadge.visibility = if (comment.isMod == true) View.VISIBLE else View.GONE
viewBinding.adminBadge.visibility = if (comment.isAdmin == true) View.VISIBLE else View.GONE
viewBinding.commentDelete.setOnClickListener {
dialogBuilder(getAppString(R.string.delete_comment), getAppString(R.string.delete_comment_confirm)) {
CoroutineScope(Dispatchers.Main + SupervisorJob()).launch {
val success = CommentsAPI.deleteComment(comment.commentId)
if (success) {
snackString(R.string.comment_deleted)
parentSection.remove(this@CommentItem)
}
}
}
}
viewBinding.commentBanUser.setOnClickListener {
dialogBuilder(getAppString(R.string.ban_user), getAppString(R.string.ban_user_confirm)) {
CoroutineScope(Dispatchers.Main + SupervisorJob()).launch {
val success = CommentsAPI.banUser(comment.userId)
if (success) {
snackString(R.string.user_banned)
}
}
}
}
viewBinding.commentReport.setOnClickListener {
dialogBuilder(getAppString(R.string.report_comment), getAppString(R.string.report_comment_confirm)) {
CoroutineScope(Dispatchers.Main + SupervisorJob()).launch {
val success = CommentsAPI.reportComment(
comment.commentId,
comment.username,
commentsFragment.mediaName,
comment.userId
)
if (success) {
snackString(R.string.comment_reported)
viewBinding.commentInfo.setOnClickListener {
val popup = PopupMenu(commentsFragment.requireContext(), viewBinding.commentInfo)
popup.menuInflater.inflate(R.menu.profile_details_menu, popup.menu)
popup.menu.findItem(R.id.commentDelete)?.isVisible = isUserComment || CommentsAPI.isAdmin || CommentsAPI.isMod
popup.menu.findItem(R.id.commentBanUser)?.isVisible = (CommentsAPI.isAdmin || CommentsAPI.isMod) && !isUserComment
popup.menu.findItem(R.id.commentReport)?.isVisible = !isUserComment
popup.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.commentReport -> {
dialogBuilder(
getAppString(R.string.report_comment),
getAppString(R.string.report_comment_confirm)
) {
CoroutineScope(Dispatchers.Main + SupervisorJob()).launch {
val success = CommentsAPI.reportComment(
comment.commentId,
comment.username,
commentsFragment.mediaName,
comment.userId
)
if (success) {
snackString(R.string.comment_reported)
}
}
}
true
}
R.id.commentDelete -> {
dialogBuilder(
getAppString(R.string.delete_comment),
getAppString(R.string.delete_comment_confirm)
) {
CoroutineScope(Dispatchers.Main + SupervisorJob()).launch {
val success = CommentsAPI.deleteComment(comment.commentId)
if (success) {
snackString(R.string.comment_deleted)
parentSection.remove(this@CommentItem)
}
}
}
true
}
R.id.commentBanUser -> {
dialogBuilder(
getAppString(R.string.ban_user),
getAppString(R.string.ban_user_confirm)
) {
CoroutineScope(Dispatchers.Main + SupervisorJob()).launch {
val success = CommentsAPI.banUser(comment.userId)
if (success) {
snackString(R.string.user_banned)
}
}
}
true
}
else -> {
false
}
}
}
popup.show()
}
//fill the icon if the user has liked the comment
setVoteButtons(viewBinding)
@@ -210,7 +240,6 @@ class CommentItem(val comment: Comment,
comment.upvotes -= 1
}
comment.downvotes += if (voteType == -1) 1 else -1
notifyChanged()
}
}

View File

@@ -37,7 +37,18 @@ abstract class BaseImageAdapter(
chapter: MangaChapter
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
val settings = activity.defaultSettings
val images = chapter.images()
private val chapterImages = chapter.images()
var images = chapterImages
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
images = if (settings.layout == CurrentReaderSettings.Layouts.PAGED
&& settings.direction == CurrentReaderSettings.Directions.BOTTOM_TO_TOP) {
chapterImages.reversed()
} else {
chapterImages
}
super.onAttachedToRecyclerView(recyclerView)
}
@SuppressLint("ClickableViewAccessibility")
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
@@ -213,5 +224,4 @@ abstract class BaseImageAdapter(
return newBitmap
}
}
}

View File

@@ -129,6 +129,11 @@ class MangaReaderActivity : AppCompatActivity() {
var sliding = false
var isAnimating = false
private val directionRLBT get() = defaultSettings.direction == RIGHT_TO_LEFT
|| defaultSettings.direction == BOTTOM_TO_TOP
private val directionPagedBT get() = defaultSettings.layout == CurrentReaderSettings.Layouts.PAGED
&& defaultSettings.direction == CurrentReaderSettings.Directions.BOTTOM_TO_TOP
override fun onAttachedToWindow() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && !PrefManager.getVal<Boolean>(PrefName.ShowSystemBars)) {
val displayCutout = window.decorView.rootWindowInsets.displayCutout
@@ -224,8 +229,13 @@ class MangaReaderActivity : AppCompatActivity() {
binding.mangaReaderRecycler.scrollToPosition((value.toInt() - 1) / (dualPage { 2 }
?: 1))
else
binding.mangaReaderPager.currentItem =
(value.toInt() - 1) / (dualPage { 2 } ?: 1)
if (defaultSettings.direction == CurrentReaderSettings.Directions.BOTTOM_TO_TOP ) {
binding.mangaReaderPager.currentItem =
(maxChapterPage.toInt() - value.toInt()) / (dualPage { 2 } ?: 1)
} else {
binding.mangaReaderPager.currentItem =
(value.toInt() - 1) / (dualPage { 2 } ?: 1)
}
pageSliderHide()
}
}
@@ -331,7 +341,7 @@ class MangaReaderActivity : AppCompatActivity() {
binding.mangaReaderNextChapter.performClick()
}
binding.mangaReaderNextChapter.setOnClickListener {
if (defaultSettings.direction == RIGHT_TO_LEFT || defaultSettings.direction == BOTTOM_TO_TOP) {
if (directionRLBT) {
if (currentChapterIndex > 0) change(currentChapterIndex - 1)
else snackString(getString(R.string.first_chapter))
} else {
@@ -344,7 +354,7 @@ class MangaReaderActivity : AppCompatActivity() {
binding.mangaReaderPreviousChapter.performClick()
}
binding.mangaReaderPreviousChapter.setOnClickListener {
if (defaultSettings.direction == RIGHT_TO_LEFT || defaultSettings.direction == BOTTOM_TO_TOP) {
if (directionRLBT) {
if (chaptersArr.size > currentChapterIndex + 1) progress { change(currentChapterIndex + 1) }
else snackString(getString(R.string.next_chapter_not_found))
} else {
@@ -361,7 +371,7 @@ class MangaReaderActivity : AppCompatActivity() {
PrefManager.setCustomVal("${media.id}_current_chp", chap.number)
currentChapterIndex = chaptersArr.indexOf(chap.number)
binding.mangaReaderChapterSelect.setSelection(currentChapterIndex)
if (defaultSettings.direction == RIGHT_TO_LEFT || defaultSettings.direction == BOTTOM_TO_TOP) {
if (directionRLBT) {
binding.mangaReaderNextChap.text = chaptersTitleArr.getOrNull(currentChapterIndex - 1) ?: ""
binding.mangaReaderPrevChap.text = chaptersTitleArr.getOrNull(currentChapterIndex + 1) ?: ""
} else {
@@ -459,7 +469,11 @@ class MangaReaderActivity : AppCompatActivity() {
currentChapterPage = PrefManager.getCustomVal("${media.id}_${chapter.number}", 1L)
val chapImages = chapter.images()
val chapImages = if (directionPagedBT) {
chapter.images().reversed()
} else {
chapter.images()
}
maxChapterPage = 0
if (chapImages.isNotEmpty()) {
@@ -483,7 +497,11 @@ class MangaReaderActivity : AppCompatActivity() {
}
val currentPage = currentChapterPage.toInt()
val currentPage = if (directionPagedBT) {
maxChapterPage - currentChapterPage + 1
} else {
currentChapterPage
}.toInt()
if ((defaultSettings.direction == TOP_TO_BOTTOM || defaultSettings.direction == BOTTOM_TO_TOP)) {
binding.mangaReaderSwipy.vertical = true
@@ -512,10 +530,10 @@ class MangaReaderActivity : AppCompatActivity() {
binding.TopSwipeText.text = chaptersTitleArr.getOrNull(currentChapterIndex + 1)
?: getString(R.string.no_chapter)
binding.mangaReaderSwipy.onTopSwiped = {
binding.mangaReaderNextChapter.performClick()
binding.mangaReaderPreviousChapter.performClick()
}
binding.mangaReaderSwipy.onBottomSwiped = {
binding.mangaReaderPreviousChapter.performClick()
binding.mangaReaderNextChapter.performClick()
}
}
binding.mangaReaderSwipy.topBeingSwiped = { value ->
@@ -624,7 +642,7 @@ class MangaReaderActivity : AppCompatActivity() {
RecyclerView.VERTICAL
else
RecyclerView.HORIZONTAL,
!(defaultSettings.direction == TOP_TO_BOTTOM || defaultSettings.direction == LEFT_TO_RIGHT)
directionRLBT
)
manager.preloadItemCount = 5
@@ -641,6 +659,8 @@ class MangaReaderActivity : AppCompatActivity() {
else false
}
manager.setStackFromEnd(defaultSettings.direction == BOTTOM_TO_TOP)
addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(v: RecyclerView, dx: Int, dy: Int) {
defaultSettings.apply {
@@ -695,9 +715,7 @@ class MangaReaderActivity : AppCompatActivity() {
visibility = View.VISIBLE
adapter = imageAdapter
layoutDirection =
if (defaultSettings.direction == BOTTOM_TO_TOP || defaultSettings.direction == RIGHT_TO_LEFT)
View.LAYOUT_DIRECTION_RTL
else View.LAYOUT_DIRECTION_LTR
if (directionRLBT) View.LAYOUT_DIRECTION_RTL else View.LAYOUT_DIRECTION_LTR
orientation =
if (defaultSettings.direction == LEFT_TO_RIGHT || defaultSettings.direction == RIGHT_TO_LEFT)
ViewPager2.ORIENTATION_HORIZONTAL
@@ -786,7 +804,7 @@ class MangaReaderActivity : AppCompatActivity() {
val screenWidth = Resources.getSystem().displayMetrics.widthPixels
//if in the 1st 1/5th of the screen width, left and lower than 1/5th of the screen height, left
if (screenWidth / 5 in x + 1..<y) {
pressLocation = if (defaultSettings.direction == RIGHT_TO_LEFT || defaultSettings.direction == BOTTOM_TO_TOP) {
pressLocation = if (defaultSettings.direction == RIGHT_TO_LEFT) {
PressPos.RIGHT
} else {
PressPos.LEFT
@@ -794,7 +812,7 @@ class MangaReaderActivity : AppCompatActivity() {
}
//if in the last 1/5th of the screen width, right and lower than 1/5th of the screen height, right
else if (x > screenWidth - screenWidth / 5 && y > screenWidth / 5) {
pressLocation = if (defaultSettings.direction == RIGHT_TO_LEFT || defaultSettings.direction == BOTTOM_TO_TOP) {
pressLocation = if (defaultSettings.direction == RIGHT_TO_LEFT) {
PressPos.LEFT
} else {
PressPos.RIGHT
@@ -890,9 +908,10 @@ class MangaReaderActivity : AppCompatActivity() {
}
}
binding.mangaReaderSlider.layoutDirection =
if (defaultSettings.direction == RIGHT_TO_LEFT || defaultSettings.direction == BOTTOM_TO_TOP)
if (directionRLBT)
View.LAYOUT_DIRECTION_RTL
else View.LAYOUT_DIRECTION_LTR
else
View.LAYOUT_DIRECTION_LTR
shouldShow?.apply { isContVisible = !this }
if (isContVisible) {
isContVisible = false
@@ -900,12 +919,7 @@ class MangaReaderActivity : AppCompatActivity() {
isAnimating = true
ObjectAnimator.ofFloat(binding.mangaReaderCont, "alpha", 1f, 0f)
.setDuration(controllerDuration).start()
ObjectAnimator.ofFloat(
binding.mangaReaderBottomLayout,
"translationY",
0f,
128f
)
ObjectAnimator.ofFloat(binding.mangaReaderBottomLayout, "translationY", 0f, 128f)
.apply { interpolator = overshoot;duration = controllerDuration;start() }
ObjectAnimator.ofFloat(binding.mangaReaderTopLayout, "translationY", 0f, -128f)
.apply { interpolator = overshoot;duration = controllerDuration;start() }
@@ -925,7 +939,11 @@ class MangaReaderActivity : AppCompatActivity() {
}
private var loading = false
fun updatePageNumber(page: Long) {
fun updatePageNumber(pageNumber: Long) {
var page = pageNumber
if (directionPagedBT) {
page = maxChapterPage - pageNumber + 1
}
if (currentChapterPage != page) {
currentChapterPage = page
PrefManager.setCustomVal("${media.id}_${chapter.number}", page)
@@ -1090,4 +1108,4 @@ class MangaReaderActivity : AppCompatActivity() {
}
return true
}
}
}

View File

@@ -1,14 +1,13 @@
package ani.dantotsu.profile.activity
package ani.dantotsu.profile
import android.content.Intent
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import ani.dantotsu.blurImage
import ani.dantotsu.databinding.ItemFollowerBinding
import ani.dantotsu.loadImage
import ani.dantotsu.profile.ProfileActivity
import ani.dantotsu.profile.User
import ani.dantotsu.setAnimation
@@ -41,7 +40,7 @@ class UsersAdapter(private val user: ArrayList<User>) : RecyclerView.Adapter<Use
setAnimation(b.root.context, b.root)
val user = user[position]
b.profileUserAvatar.loadImage(user.pfp)
b.profileBannerImage.loadImage(user.banner)
blurImage(b.profileBannerImage, user.banner ?: user.pfp)
b.profileUserName.text = user.name
}

View File

@@ -7,8 +7,6 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.BottomSheetDialogFragment
import ani.dantotsu.databinding.BottomSheetUsersBinding
import ani.dantotsu.profile.activity.UsersAdapter
import ani.dantotsu.settings.DevelopersAdapter
class UsersDialogFragment : BottomSheetDialogFragment() {

View File

@@ -6,63 +6,13 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.BottomSheetDialogFragment
import ani.dantotsu.connections.github.Contributors
import ani.dantotsu.databinding.BottomSheetDevelopersBinding
class DevelopersDialogFragment : BottomSheetDialogFragment() {
private var _binding: BottomSheetDevelopersBinding? = null
private val binding get() = _binding!!
private val developers = arrayOf(
Developer(
"rebelonion",
"https://avatars.githubusercontent.com/u/87634197?v=4",
"Owner and Maintainer",
"https://github.com/rebelonion"
),
Developer(
"Aayush262",
"https://avatars.githubusercontent.com/u/99584765?v=4",
"Contributor",
"https://github.com/aayush2622"
),
Developer(
"AbandonedCart",
"https://avatars.githubusercontent.com/u/1173913?v=4",
"Contributor",
"https://github.com/AbandonedCart"
),
Developer(
"Sadwhy",
"https://avatars.githubusercontent.com/u/99601717?v=4",
"Contributor",
"https://github.com/Sadwhy"
),
Developer(
"Wai What",
"https://avatars.githubusercontent.com/u/149729762?v=4",
"Icon Designer",
"https://github.com/WaiWhat"
),
Developer(
"MarshMeadow",
"https://avatars.githubusercontent.com/u/88599122?v=4",
"Beta Icon Designer",
"https://github.com/MarshMeadow?tab=repositories"
),
Developer(
"Zaxx69",
"https://avatars.githubusercontent.com/u/138523882?v=4",
"Telegram Admin",
"https://github.com/Zaxx69"
),
Developer(
"Arif Alam",
"https://avatars.githubusercontent.com/u/70383209?v=4",
"Head Discord Moderator",
"https://youtube.com/watch?v=dQw4w9WgXcQ"
),
)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -74,7 +24,7 @@ class DevelopersDialogFragment : BottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.devsRecyclerView.adapter = DevelopersAdapter(developers)
binding.devsRecyclerView.adapter = DevelopersAdapter(Contributors().getContributors())
binding.devsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
}

View File

@@ -1,22 +1,14 @@
package ani.dantotsu.settings
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.BottomSheetDialogFragment
import ani.dantotsu.R
import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.databinding.BottomSheetDiscordRpcBinding
import ani.dantotsu.profile.activity.UsersAdapter
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
import com.google.android.material.bottomsheet.BottomSheetDialog
class DiscordDialogFragment: BottomSheetDialogFragment() {
private var _binding: BottomSheetDiscordRpcBinding? = null

View File

@@ -7,21 +7,13 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.BottomSheetDialogFragment
import ani.dantotsu.R
import ani.dantotsu.connections.github.Forks
import ani.dantotsu.databinding.BottomSheetDevelopersBinding
class ForksDialogFragment : BottomSheetDialogFragment() {
private var _binding: BottomSheetDevelopersBinding? = null
private val binding get() = _binding!!
private val developers = arrayOf(
Developer(
"Dantotsu",
"https://avatars.githubusercontent.com/u/87634197?v=4",
"rebelonion",
"https://github.com/rebelonion/Dantotsu"
),
)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -34,7 +26,7 @@ class ForksDialogFragment : BottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.devsTitle.setText(R.string.forks)
binding.devsRecyclerView.adapter = DevelopersAdapter(developers)
binding.devsRecyclerView.adapter = DevelopersAdapter(Forks().getForks())
binding.devsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
}

View File

@@ -29,6 +29,7 @@ import androidx.annotation.OptIn
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import android.view.HapticFeedbackConstants
import androidx.core.view.ViewCompat.performHapticFeedback
import androidx.core.view.updateLayoutParams
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.lifecycleScope
@@ -219,6 +220,12 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
settingsAnilistUsername.visibility = View.VISIBLE
settingsAnilistUsername.text = Anilist.username
settingsAnilistAvatar.loadImage(Anilist.avatar)
settingsAnilistAvatar.setOnClickListener {
it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
val anilistLink = getString(R.string.anilist_link, PrefManager.getVal<String>(PrefName.AnilistUserName))
openLinkInBrowser(anilistLink)
true
}
settingsMALLoginRequired.visibility = View.GONE
settingsMALLogin.visibility = View.VISIBLE
@@ -234,6 +241,12 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
settingsMALUsername.visibility = View.VISIBLE
settingsMALUsername.text = MAL.username
settingsMALAvatar.loadImage(MAL.avatar)
settingsMALAvatar.setOnClickListener {
it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
val myanilistLink = getString(R.string.myanilist_link, MAL.username)
openLinkInBrowser(myanilistLink)
true
}
} else {
settingsMALAvatar.setImageResource(R.drawable.ic_round_person_24)
settingsMALUsername.visibility = View.GONE
@@ -260,6 +273,12 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
val username = PrefManager.getVal(PrefName.DiscordUserName, null as String?)
if (id != null && avatar != null) {
settingsDiscordAvatar.loadImage("https://cdn.discordapp.com/avatars/$id/$avatar.png")
settingsDiscordAvatar.setOnClickListener {
it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
val discordLink = getString(R.string.discord_link, id)
openLinkInBrowser(discordLink)
true
}
}
settingsDiscordUsername.visibility = View.VISIBLE
settingsDiscordUsername.text =
@@ -651,18 +670,18 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
val filteredLocations = Location.entries.filter { it.exportable }
selectedArray.addAll(List(filteredLocations.size - 1) { false })
val dialog = AlertDialog.Builder(this@SettingsActivity, R.style.MyPopup)
.setTitle(R.string.import_export_settings)
.setTitle(R.string.backup_restore)
.setMultiChoiceItems(
filteredLocations.map { it.name }.toTypedArray(),
selectedArray.toBooleanArray()
) { _, which, isChecked ->
selectedArray[which] = isChecked
}
.setPositiveButton(R.string.button_import) { dialog, _ ->
.setPositiveButton(R.string.button_restore) { dialog, _ ->
openDocumentLauncher.launch(arrayOf("*/*"))
dialog.dismiss()
}
.setNegativeButton(R.string.button_export) { dialog, _ ->
.setNegativeButton(R.string.button_backup) { dialog, _ ->
if (!selectedArray.contains(true)) {
toast(R.string.no_location_selected)
return@setNegativeButton