feat: optimize Alert Dialogs

This commit is contained in:
aayush262 2024-06-13 19:15:55 +05:30
parent 1670383619
commit 124c8f5ed7
31 changed files with 739 additions and 837 deletions

View file

@ -61,6 +61,7 @@ import ani.dantotsu.settings.saving.internal.PreferenceKeystore
import ani.dantotsu.settings.saving.internal.PreferencePackager import ani.dantotsu.settings.saving.internal.PreferencePackager
import ani.dantotsu.themes.ThemeManager import ani.dantotsu.themes.ThemeManager
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import ani.dantotsu.util.customAlertDialog
import com.google.android.material.snackbar.BaseTransientBottomBar import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
@ -494,36 +495,29 @@ class MainActivity : AppCompatActivity() {
val password = CharArray(16).apply { fill('0') } val password = CharArray(16).apply { fill('0') }
// Inflate the dialog layout // Inflate the dialog layout
val dialogView = DialogUserAgentBinding.inflate(layoutInflater) val dialogView = DialogUserAgentBinding.inflate(layoutInflater).apply {
dialogView.userAgentTextBox.hint = "Password" userAgentTextBox.hint = "Password"
dialogView.subtitle.visibility = View.VISIBLE subtitle.visibility = View.VISIBLE
dialogView.subtitle.text = getString(R.string.enter_password_to_decrypt_file) subtitle.text = getString(R.string.enter_password_to_decrypt_file)
val dialog = AlertDialog.Builder(this, R.style.MyPopup)
.setTitle("Enter Password")
.setView(dialogView.root)
.setPositiveButton("OK", null)
.setNegativeButton("Cancel") { dialog, _ ->
password.fill('0')
dialog.dismiss()
callback(null)
} }
.create() customAlertDialog().apply {
setTitle("Enter Password")
dialog.window?.setDimAmount(0.8f) setCustomView(dialogView.root)
dialog.show() setPosButton(R.string.yes) {
val editText = dialogView.userAgentTextBox
// Override the positive button here if (editText.text?.isNotBlank() == true) {
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
val editText = dialog.findViewById<TextInputEditText>(R.id.userAgentTextBox)
if (editText?.text?.isNotBlank() == true) {
editText.text?.toString()?.trim()?.toCharArray(password) editText.text?.toString()?.trim()?.toCharArray(password)
dialog.dismiss()
callback(password) callback(password)
} else { } else {
toast("Password cannot be empty") toast("Password cannot be empty")
} }
} }
setNegButton(R.string.cancel) {
password.fill('0')
callback(null)
}
show()
}
} }
//ViewPager //ViewPager

View file

@ -49,6 +49,7 @@ import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import ani.dantotsu.util.customAlertDialog
import com.anggrayudi.storage.file.openInputStream import com.anggrayudi.storage.file.openInputStream
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
import com.google.android.material.imageview.ShapeableImageView import com.google.android.material.imageview.ShapeableImageView
@ -203,25 +204,22 @@ class OfflineAnimeFragment : Fragment(), OfflineAnimeSearchListener {
val type: MediaType = MediaType.ANIME val type: MediaType = MediaType.ANIME
// Alert dialog to confirm deletion // Alert dialog to confirm deletion
val builder = requireContext().customAlertDialog().apply {
androidx.appcompat.app.AlertDialog.Builder(requireContext(), R.style.MyPopup) setTitle("Delete ${item.title}?")
builder.setTitle("Delete ${item.title}?") setMessage("Are you sure you want to delete ${item.title}?")
builder.setMessage("Are you sure you want to delete ${item.title}?") setPosButton(R.string.yes) {
builder.setPositiveButton("Yes") { _, _ ->
downloadManager.removeMedia(item.title, type) downloadManager.removeMedia(item.title, type)
val mediaIds = val mediaIds = PrefManager.getAnimeDownloadPreferences().all?.filter { it.key.contains(item.title) }?.values ?: emptySet()
PrefManager.getAnimeDownloadPreferences().all?.filter { it.key.contains(item.title) }?.values
?: emptySet()
if (mediaIds.isEmpty()) { if (mediaIds.isEmpty()) {
snackString("No media found") // if this happens, terrible things have happened snackString("No media found") // if this happens, terrible things have happened
} }
getDownloads() getDownloads()
} }
builder.setNegativeButton("No") { _, _ -> setNegButton(R.string.no) {
// Do nothing // Do nothing
} }
val dialog = builder.show() show()
dialog.window?.setDimAmount(0.8f) }
true true
} }
} }

View file

@ -46,6 +46,7 @@ import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import ani.dantotsu.util.customAlertDialog
import com.anggrayudi.storage.file.openInputStream import com.anggrayudi.storage.file.openInputStream
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
import com.google.android.material.imageview.ShapeableImageView import com.google.android.material.imageview.ShapeableImageView
@ -201,19 +202,15 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
MediaType.NOVEL MediaType.NOVEL
} }
// Alert dialog to confirm deletion // Alert dialog to confirm deletion
val builder = requireContext().customAlertDialog().apply {
androidx.appcompat.app.AlertDialog.Builder(requireContext(), R.style.MyPopup) setTitle("Delete ${item.title}?")
builder.setTitle("Delete ${item.title}?") setMessage("Are you sure you want to delete ${item.title}?")
builder.setMessage("Are you sure you want to delete ${item.title}?") setPosButton(R.string.yes) {
builder.setPositiveButton("Yes") { _, _ ->
downloadManager.removeMedia(item.title, type) downloadManager.removeMedia(item.title, type)
getDownloads() getDownloads()
} }
builder.setNegativeButton("No") { _, _ -> setNegButton(R.string.no)
// Do nothing }.show()
}
val dialog = builder.show()
dialog.window?.setDimAmount(0.8f)
true true
} }
} }

View file

@ -3,7 +3,6 @@ package ani.dantotsu.download.video
import android.Manifest import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
@ -29,10 +28,10 @@ import ani.dantotsu.download.anime.AnimeDownloaderService
import ani.dantotsu.download.anime.AnimeServiceDataSingleton import ani.dantotsu.download.anime.AnimeServiceDataSingleton
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaType import ani.dantotsu.media.MediaType
import ani.dantotsu.parsers.Subtitle
import ani.dantotsu.parsers.Video import ani.dantotsu.parsers.Video
import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import ani.dantotsu.util.customAlertDialog
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -72,19 +71,19 @@ object Helper {
episodeImage episodeImage
) )
val downloadsManger = Injekt.get<DownloadsManager>() val downloadsManager = Injekt.get<DownloadsManager>()
val downloadCheck = downloadsManger val downloadCheck = downloadsManager
.queryDownload(title, episode, MediaType.ANIME) .queryDownload(title, episode, MediaType.ANIME)
if (downloadCheck) { if (downloadCheck) {
AlertDialog.Builder(context, R.style.MyPopup) context.customAlertDialog().apply {
.setTitle("Download Exists") setTitle("Download Exists")
.setMessage("A download for this episode already exists. Do you want to overwrite it?") setMessage("A download for this episode already exists. Do you want to overwrite it?")
.setPositiveButton("Yes") { _, _ -> setPosButton(R.string.yes) {
PrefManager.getAnimeDownloadPreferences().edit() PrefManager.getAnimeDownloadPreferences().edit()
.remove(animeDownloadTask.getTaskName()) .remove(animeDownloadTask.getTaskName())
.apply() .apply()
downloadsManger.removeDownload( downloadsManager.removeDownload(
DownloadedType( DownloadedType(
title, title,
episode, episode,
@ -99,8 +98,9 @@ object Helper {
} }
} }
} }
.setNegativeButton("No") { _, _ -> } setNegButton(R.string.no)
.show() show()
}
} else { } else {
AnimeServiceDataSingleton.downloadQueue.offer(animeDownloadTask) AnimeServiceDataSingleton.downloadQueue.offer(animeDownloadTask)
if (!AnimeServiceDataSingleton.isServiceRunning) { if (!AnimeServiceDataSingleton.isServiceRunning) {

View file

@ -12,12 +12,14 @@ import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.connections.anilist.Anilist import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.databinding.DialogUserAgentBinding
import ani.dantotsu.databinding.FragmentLoginBinding import ani.dantotsu.databinding.FragmentLoginBinding
import ani.dantotsu.openLinkInBrowser import ani.dantotsu.openLinkInBrowser
import ani.dantotsu.settings.saving.internal.PreferenceKeystore import ani.dantotsu.settings.saving.internal.PreferenceKeystore
import ani.dantotsu.settings.saving.internal.PreferencePackager import ani.dantotsu.settings.saving.internal.PreferencePackager
import ani.dantotsu.toast import ani.dantotsu.toast
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import ani.dantotsu.util.customAlertDialog
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
class LoginFragment : Fragment() { class LoginFragment : Fragment() {
@ -94,38 +96,31 @@ class LoginFragment : Fragment() {
val password = CharArray(16).apply { fill('0') } val password = CharArray(16).apply { fill('0') }
// Inflate the dialog layout // Inflate the dialog layout
val dialogView = val dialogView = DialogUserAgentBinding.inflate(layoutInflater).apply {
LayoutInflater.from(requireActivity()).inflate(R.layout.dialog_user_agent, null) userAgentTextBox.hint = "Password"
dialogView.findViewById<TextInputEditText>(R.id.userAgentTextBox)?.hint = "Password" subtitle.visibility = View.VISIBLE
val subtitleTextView = dialogView.findViewById<TextView>(R.id.subtitle) subtitle.text = getString(R.string.enter_password_to_decrypt_file)
subtitleTextView?.visibility = View.VISIBLE
subtitleTextView?.text = "Enter your password to decrypt the file"
val dialog = AlertDialog.Builder(requireActivity(), R.style.MyPopup)
.setTitle("Enter Password")
.setView(dialogView)
.setPositiveButton("OK", null)
.setNegativeButton("Cancel") { dialog, _ ->
password.fill('0')
dialog.dismiss()
callback(null)
} }
.create()
dialog.window?.setDimAmount(0.8f) requireActivity().customAlertDialog().apply {
dialog.show() setTitle("Enter Password")
setCustomView(dialogView.root)
// Override the positive button here setPosButton(R.string.ok){
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { val editText = dialogView.userAgentTextBox
val editText = dialog.findViewById<TextInputEditText>(R.id.userAgentTextBox) if (editText.text?.isNotBlank() == true) {
if (editText?.text?.isNotBlank() == true) {
editText.text?.toString()?.trim()?.toCharArray(password) editText.text?.toString()?.trim()?.toCharArray(password)
dialog.dismiss()
callback(password) callback(password)
} else { } else {
toast("Password cannot be empty") toast("Password cannot be empty")
} }
} }
setNegButton(R.string.cancel) {
password.fill('0')
callback(null)
}
}.show()
} }
private fun restartApp() { private fun restartApp() {

View file

@ -5,7 +5,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.util.AttributeSet import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
@ -16,7 +15,6 @@ import androidx.core.app.ActivityOptionsCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.NestedScrollView
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.blurImage import ani.dantotsu.blurImage
@ -32,6 +30,7 @@ import ani.dantotsu.profile.ProfileActivity
import ani.dantotsu.profile.User import ani.dantotsu.profile.User
import ani.dantotsu.profile.UsersDialogFragment import ani.dantotsu.profile.UsersDialogFragment
import ani.dantotsu.profile.activity.ActivityItemBuilder import ani.dantotsu.profile.activity.ActivityItemBuilder
import ani.dantotsu.profile.activity.RepliesBottomDialog
import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.snackString import ani.dantotsu.snackString

View file

@ -39,6 +39,7 @@ import ani.dantotsu.settings.FAQActivity
import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.toast import ani.dantotsu.toast
import ani.dantotsu.util.customAlertDialog
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
import eu.kanade.tachiyomi.data.notification.Notifications.CHANNEL_SUBSCRIPTION_CHECK import eu.kanade.tachiyomi.data.notification.Notifications.CHANNEL_SUBSCRIPTION_CHECK
@ -61,9 +62,6 @@ class AnimeWatchAdapter(
return ViewHolder(bind) return ViewHolder(bind)
} }
private var nestedDialog: AlertDialog? = null
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val binding = holder.binding val binding = holder.binding
_binding = binding _binding = binding
@ -201,34 +199,34 @@ class AnimeWatchAdapter(
//Nested Button //Nested Button
binding.animeNestedButton.setOnClickListener { binding.animeNestedButton.setOnClickListener {
val dialogView = val dialogBinding = DialogLayoutBinding.inflate(fragment.layoutInflater)
LayoutInflater.from(fragment.requireContext()).inflate(R.layout.dialog_layout, null) dialogBinding.apply {
val dialogBinding = DialogLayoutBinding.bind(dialogView)
var refresh = false var refresh = false
var run = false var run = false
var reversed = media.selected!!.recyclerReversed var reversed = media.selected!!.recyclerReversed
var style = var style =
media.selected!!.recyclerStyle ?: PrefManager.getVal(PrefName.AnimeDefaultView) media.selected!!.recyclerStyle ?: PrefManager.getVal(PrefName.AnimeDefaultView)
dialogBinding.animeSourceTop.rotation = if (reversed) -90f else 90f
dialogBinding.sortText.text = if (reversed) "Down to Up" else "Up to Down" animeSourceTop.rotation = if (reversed) -90f else 90f
dialogBinding.animeSourceTop.setOnClickListener { sortText.text = if (reversed) "Down to Up" else "Up to Down"
animeSourceTop.setOnClickListener {
reversed = !reversed reversed = !reversed
dialogBinding.animeSourceTop.rotation = if (reversed) -90f else 90f animeSourceTop.rotation = if (reversed) -90f else 90f
dialogBinding.sortText.text = if (reversed) "Down to Up" else "Up to Down" sortText.text = if (reversed) "Down to Up" else "Up to Down"
run = true run = true
} }
//Grids //Grids
var selected = when (style) { var selected = when (style) {
0 -> dialogBinding.animeSourceList 0 -> animeSourceList
1 -> dialogBinding.animeSourceGrid 1 -> animeSourceGrid
2 -> dialogBinding.animeSourceCompact 2 -> animeSourceCompact
else -> dialogBinding.animeSourceList else -> animeSourceList
} }
when (style) { when (style) {
0 -> dialogBinding.layoutText.setText(R.string.list) 0 -> layoutText.setText(R.string.list)
1 -> dialogBinding.layoutText.setText(R.string.grid) 1 -> layoutText.setText(R.string.grid)
2 -> dialogBinding.layoutText.setText(R.string.compact) 2 -> layoutText.setText(R.string.compact)
else -> dialogBinding.animeSourceList else -> animeSourceList
} }
selected.alpha = 1f selected.alpha = 1f
fun selected(it: ImageButton) { fun selected(it: ImageButton) {
@ -236,25 +234,25 @@ class AnimeWatchAdapter(
selected = it selected = it
selected.alpha = 1f selected.alpha = 1f
} }
dialogBinding.animeSourceList.setOnClickListener { animeSourceList.setOnClickListener {
selected(it as ImageButton) selected(it as ImageButton)
style = 0 style = 0
dialogBinding.layoutText.setText(R.string.list) layoutText.setText(R.string.list)
run = true run = true
} }
dialogBinding.animeSourceGrid.setOnClickListener { animeSourceGrid.setOnClickListener {
selected(it as ImageButton) selected(it as ImageButton)
style = 1 style = 1
dialogBinding.layoutText.setText(R.string.grid) layoutText.setText(R.string.grid)
run = true run = true
} }
dialogBinding.animeSourceCompact.setOnClickListener { animeSourceCompact.setOnClickListener {
selected(it as ImageButton) selected(it as ImageButton)
style = 2 style = 2
dialogBinding.layoutText.setText(R.string.compact) layoutText.setText(R.string.compact)
run = true run = true
} }
dialogBinding.animeWebviewContainer.setOnClickListener { animeWebviewContainer.setOnClickListener {
if (!WebViewUtil.supportsWebView(fragment.requireContext())) { if (!WebViewUtil.supportsWebView(fragment.requireContext())) {
toast(R.string.webview_not_installed) toast(R.string.webview_not_installed)
} }
@ -272,7 +270,8 @@ class AnimeWatchAdapter(
} catch (e: Exception) { } catch (e: Exception) {
emptyMap() emptyMap()
} }
val intent = Intent(fragment.requireContext(), CookieCatcher::class.java) val intent =
Intent(fragment.requireContext(), CookieCatcher::class.java)
.putExtra("url", url) .putExtra("url", url)
.putExtra("headers", headersMap as HashMap<String, String>) .putExtra("headers", headersMap as HashMap<String, String>)
startActivity(fragment.requireContext(), intent, null) startActivity(fragment.requireContext(), intent, null)
@ -281,24 +280,21 @@ class AnimeWatchAdapter(
} }
//hidden //hidden
dialogBinding.animeScanlatorContainer.visibility = View.GONE animeScanlatorContainer.visibility = View.GONE
dialogBinding.animeDownloadContainer.visibility = View.GONE animeDownloadContainer.visibility = View.GONE
fragment.requireContext().customAlertDialog().apply {
nestedDialog = AlertDialog.Builder(fragment.requireContext(), R.style.MyPopup) setTitle("Options")
.setTitle("Options") setCustomView(dialogBinding.root)
.setView(dialogView) setPosButton("OK") {
.setPositiveButton("OK") { _, _ ->
if (run) fragment.onIconPressed(style, reversed) if (run) fragment.onIconPressed(style, reversed)
if (refresh) fragment.loadEpisodes(source, true) if (refresh) fragment.loadEpisodes(source, true)
} }
.setNegativeButton("Cancel") { _, _ -> setNegButton("Cancel") {
if (refresh) fragment.loadEpisodes(source, true) if (refresh) fragment.loadEpisodes(source, true)
} }
.setOnCancelListener { show()
if (refresh) fragment.loadEpisodes(source, true) }
} }
.create()
nestedDialog?.show()
} }
//Episode Handling //Episode Handling
handleEpisodes() handleEpisodes()

View file

@ -63,6 +63,7 @@ import ani.dantotsu.toast
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import ani.dantotsu.util.StoragePermissions.Companion.accessAlertDialog import ani.dantotsu.util.StoragePermissions.Companion.accessAlertDialog
import ani.dantotsu.util.StoragePermissions.Companion.hasDirAccess import ani.dantotsu.util.StoragePermissions.Companion.hasDirAccess
import ani.dantotsu.util.customAlertDialog
import com.anggrayudi.storage.file.extension import com.anggrayudi.storage.file.extension
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
@ -396,17 +397,15 @@ class AnimeWatchFragment : Fragment() {
if (allSettings.size > 1) { if (allSettings.size > 1) {
val names = val names =
allSettings.map { LanguageMapper.getLanguageName(it.lang) }.toTypedArray() allSettings.map { LanguageMapper.getLanguageName(it.lang) }.toTypedArray()
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup) requireContext()
.setTitle("Select a Source") .customAlertDialog()
.setSingleChoiceItems(names, -1) { dialog, which -> .apply {
setTitle("Select a Source")
singleChoiceItems(names) { which ->
selectedSetting = allSettings[which] selectedSetting = allSettings[which]
itemSelected = true itemSelected = true
dialog.dismiss()
// Move the fragment transaction here
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
val fragment = val fragment = AnimeSourcePreferencesFragment().getInstance(selectedSetting.id) {
AnimeSourcePreferencesFragment().getInstance(selectedSetting.id) {
changeUIVisibility(true) changeUIVisibility(true)
loadEpisodes(media.selected!!.sourceIndex, true) loadEpisodes(media.selected!!.sourceIndex, true)
} }
@ -417,13 +416,13 @@ class AnimeWatchFragment : Fragment() {
.commit() .commit()
} }
} }
.setOnDismissListener { onDismiss {
if (!itemSelected) { if (!itemSelected) {
changeUIVisibility(true) changeUIVisibility(true)
} }
} }
.show() show()
dialog.window?.setDimAmount(0.8f) }
} else { } else {
// If there's only one setting, proceed with the fragment transaction // If there's only one setting, proceed with the fragment transaction
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
@ -432,11 +431,12 @@ class AnimeWatchFragment : Fragment() {
changeUIVisibility(true) changeUIVisibility(true)
loadEpisodes(media.selected!!.sourceIndex, true) loadEpisodes(media.selected!!.sourceIndex, true)
} }
parentFragmentManager.beginTransaction() parentFragmentManager.beginTransaction().apply {
.setCustomAnimations(R.anim.slide_up, R.anim.slide_down) setCustomAnimations(R.anim.slide_up, R.anim.slide_down)
.replace(R.id.fragmentExtensionsContainer, fragment) replace(R.id.fragmentExtensionsContainer, fragment)
.addToBackStack(null) addToBackStack(null)
.commit() commit()
}
} }
} }

View file

@ -23,6 +23,7 @@ import ani.dantotsu.media.MediaNameAdapter
import ani.dantotsu.media.MediaType import ani.dantotsu.media.MediaType
import ani.dantotsu.setAnimation import ani.dantotsu.setAnimation
import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.util.customAlertDialog
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl import com.bumptech.glide.load.model.GlideUrl
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@ -318,16 +319,14 @@ class EpisodeAdapter(
fragment.onAnimeEpisodeStopDownloadClick(episodeNumber) fragment.onAnimeEpisodeStopDownloadClick(episodeNumber)
return@setOnClickListener return@setOnClickListener
} else if (downloadedEpisodes.contains(episodeNumber)) { } else if (downloadedEpisodes.contains(episodeNumber)) {
val builder = AlertDialog.Builder(currContext(), R.style.MyPopup) binding.root.context.customAlertDialog().apply {
builder.setTitle("Delete Episode") setTitle("Delete Episode")
builder.setMessage("Are you sure you want to delete Episode ${episodeNumber}?") setMessage("Are you sure you want to delete Episode $episodeNumber?")
builder.setPositiveButton("Yes") { _, _ -> setPosButton(R.string.yes) {
fragment.onAnimeEpisodeRemoveDownloadClick(episodeNumber) fragment.onAnimeEpisodeRemoveDownloadClick(episodeNumber)
} }
builder.setNegativeButton("No") { _, _ -> setNegButton(R.string.no)
} }.show()
val dialog = builder.show()
dialog.window?.setDimAmount(0.8f)
return@setOnClickListener return@setOnClickListener
} else { } else {
fragment.onAnimeEpisodeDownloadClick(episodeNumber) fragment.onAnimeEpisodeDownloadClick(episodeNumber)

View file

@ -444,15 +444,12 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
if (subtitles.isNotEmpty()) { if (subtitles.isNotEmpty()) {
val subtitleNames = subtitles.map { it.language } val subtitleNames = subtitles.map { it.language }
var subtitleToDownload: Subtitle? = null var subtitleToDownload: Subtitle? = null
val alertDialog = AlertDialog.Builder(context, R.style.MyPopup) requireActivity().customAlertDialog().apply {
.setTitle(R.string.download_subtitle) setTitle(R.string.download_subtitle)
.setSingleChoiceItems( singleChoiceItems(subtitleNames.toTypedArray()) {which ->
subtitleNames.toTypedArray(),
-1
) { _, which ->
subtitleToDownload = subtitles[which] subtitleToDownload = subtitles[which]
} }
.setPositiveButton(R.string.download) { dialog, _ -> setPosButton(R.string.download) {
scope.launch { scope.launch {
if (subtitleToDownload != null) { if (subtitleToDownload != null) {
SubtitleDownloader.downloadSubtitle( SubtitleDownloader.downloadSubtitle(
@ -466,13 +463,9 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
) )
} }
} }
dialog.dismiss()
} }
.setNegativeButton(R.string.cancel) { dialog, _ -> setNegButton(R.string.cancel) {}
dialog.dismiss() }.show()
}
.show()
alertDialog.window?.setDimAmount(0.8f)
} else { } else {
snackString(R.string.no_subtitles_available) snackString(R.string.no_subtitles_available)
} }
@ -576,65 +569,63 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
if (audioTracks.isNotEmpty()) { if (audioTracks.isNotEmpty()) {
val audioNamesArray = audioTracks.toTypedArray() val audioNamesArray = audioTracks.toTypedArray()
val checkedItems = BooleanArray(audioNamesArray.size) { false } val checkedItems = BooleanArray(audioNamesArray.size) { false }
val alertDialog = AlertDialog.Builder(currContext, R.style.MyPopup)
.setTitle(R.string.download_audio_tracks) currContext.customAlertDialog().apply{ // ToTest
.setMultiChoiceItems(audioNamesArray, checkedItems) { _, which, isChecked -> setTitle(R.string.download_audio_tracks)
val audioPair = Pair(extractor.audioTracks[which].url, extractor.audioTracks[which].lang) multiChoiceItems(audioNamesArray, checkedItems) {
it.forEachIndexed { index, isChecked ->
val audioPair = Pair(extractor.audioTracks[index].url, extractor.audioTracks[index].lang)
if (isChecked) { if (isChecked) {
selectedAudioTracks.add(audioPair) selectedAudioTracks.add(audioPair)
} else { } else {
selectedAudioTracks.remove(audioPair) selectedAudioTracks.remove(audioPair)
} }
} }
.setPositiveButton(R.string.download) { _, _ -> }
dialog?.dismiss() setPosButton(R.string.download) {
go() go()
} }
.setNegativeButton(R.string.skip) { dialog, _ -> setNegButton(R.string.skip) {
selectedAudioTracks = mutableListOf() selectedAudioTracks = mutableListOf()
go() go()
dialog.dismiss()
} }
.setNeutralButton(R.string.cancel) { dialog, _ -> setNeutralButton(R.string.cancel) {
selectedAudioTracks = mutableListOf() selectedAudioTracks = mutableListOf()
dialog.dismiss()
} }
.show() show()
alertDialog.window?.setDimAmount(0.8f) }
} else { } else {
go() go()
} }
} }
if (subtitles.isNotEmpty()) { if (subtitles.isNotEmpty()) { // ToTest
val subtitleNamesArray = subtitleNames.toTypedArray() val subtitleNamesArray = subtitleNames.toTypedArray()
val checkedItems = BooleanArray(subtitleNamesArray.size) { false } val checkedItems = BooleanArray(subtitleNamesArray.size) { false }
val alertDialog = AlertDialog.Builder(currContext, R.style.MyPopup) currContext.customAlertDialog().apply {
.setTitle(R.string.download_subtitle) setTitle(R.string.download_subtitle)
.setMultiChoiceItems(subtitleNamesArray, checkedItems) { _, which, isChecked -> multiChoiceItems(subtitleNamesArray, checkedItems) {
val subtitlePair = Pair(subtitles[which].file.url, subtitles[which].language) it.forEachIndexed { index, isChecked ->
val subtitlePair = Pair(subtitles[index].file.url, subtitles[index].language)
if (isChecked) { if (isChecked) {
selectedSubtitles.add(subtitlePair) selectedSubtitles.add(subtitlePair)
} else { } else {
selectedSubtitles.remove(subtitlePair) selectedSubtitles.remove(subtitlePair)
} }
} }
.setPositiveButton(R.string.download) { _, _ -> }
dialog?.dismiss() setPosButton(R.string.download) {
checkAudioTracks() checkAudioTracks()
} }
.setNegativeButton(R.string.skip) { dialog, _ -> setNegButton(R.string.skip) {
selectedSubtitles = mutableListOf() selectedSubtitles = mutableListOf()
checkAudioTracks() checkAudioTracks()
dialog.dismiss()
} }
.setNeutralButton(R.string.cancel) { dialog, _ -> setNeutralButton(R.string.cancel) {
selectedSubtitles = mutableListOf() selectedSubtitles = mutableListOf()
dialog.dismiss()
} }
.show() show()
alertDialog.window?.setDimAmount(0.8f) }
} else { } else {
checkAudioTracks() checkAudioTracks()
} }

View file

@ -21,6 +21,7 @@ import ani.dantotsu.setAnimation
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.util.ColorEditor.Companion.adjustColorForContrast import ani.dantotsu.util.ColorEditor.Companion.adjustColorForContrast
import ani.dantotsu.util.ColorEditor.Companion.getContrastRatio import ani.dantotsu.util.ColorEditor.Companion.getContrastRatio
import ani.dantotsu.util.customAlertDialog
import com.xwray.groupie.GroupieAdapter import com.xwray.groupie.GroupieAdapter
import com.xwray.groupie.Section import com.xwray.groupie.Section
import com.xwray.groupie.viewbinding.BindableItem import com.xwray.groupie.viewbinding.BindableItem
@ -385,19 +386,14 @@ class CommentItem(
* @param callback the callback to call when the user clicks yes * @param callback the callback to call when the user clicks yes
*/ */
private fun dialogBuilder(title: String, message: String, callback: () -> Unit) { private fun dialogBuilder(title: String, message: String, callback: () -> Unit) {
val alertDialog = commentsFragment.activity.customAlertDialog().apply {
android.app.AlertDialog.Builder(commentsFragment.activity, R.style.MyPopup) setTitle(title)
.setTitle(title) setMessage(message)
.setMessage(message) setPosButton("Yes") {
.setPositiveButton("Yes") { dialog, _ ->
callback() callback()
dialog.dismiss()
} }
.setNegativeButton("No") { dialog, _ -> setNegButton("No") {}
dialog.dismiss() }.show()
}
val dialog = alertDialog.show()
dialog?.window?.setDimAmount(0.8f)
} }
private val usernameColors: Array<String> = arrayOf( private val usernameColors: Array<String> = arrayOf(

View file

@ -25,6 +25,7 @@ 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
import ani.dantotsu.connections.comments.CommentsAPI import ani.dantotsu.connections.comments.CommentsAPI
import ani.dantotsu.databinding.DialogEdittextBinding
import ani.dantotsu.databinding.FragmentCommentsBinding import ani.dantotsu.databinding.FragmentCommentsBinding
import ani.dantotsu.loadImage import ani.dantotsu.loadImage
import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.media.MediaDetailsActivity
@ -34,6 +35,7 @@ import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.toast import ani.dantotsu.toast
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import ani.dantotsu.util.customAlertDialog
import com.xwray.groupie.GroupieAdapter import com.xwray.groupie.GroupieAdapter
import com.xwray.groupie.Section import com.xwray.groupie.Section
import io.noties.markwon.editor.MarkwonEditor import io.noties.markwon.editor.MarkwonEditor
@ -162,33 +164,26 @@ class CommentsFragment : Fragment() {
} }
binding.commentFilter.setOnClickListener { binding.commentFilter.setOnClickListener {
val alertDialog = AlertDialog.Builder(activity, R.style.MyPopup) activity.customAlertDialog().apply {
.setTitle("Enter a chapter/episode number tag") val customView = DialogEdittextBinding.inflate(layoutInflater)
.setView(R.layout.dialog_edittext) setTitle("Enter a chapter/episode number tag")
.setPositiveButton("OK") { dialog, _ -> setCustomView(customView.root)
val editText = setPosButton("OK") {
(dialog as AlertDialog).findViewById<EditText>(R.id.dialogEditText) val text = customView.dialogEditText.text.toString()
val text = editText?.text.toString()
filterTag = text.toIntOrNull() filterTag = text.toIntOrNull()
lifecycleScope.launch { lifecycleScope.launch {
loadAndDisplayComments() loadAndDisplayComments()
} }
dialog.dismiss()
} }
.setNeutralButton("Clear") { dialog, _ -> setNeutralButton("Clear") {
filterTag = null filterTag = null
lifecycleScope.launch { lifecycleScope.launch {
loadAndDisplayComments() loadAndDisplayComments()
} }
dialog.dismiss()
} }
.setNegativeButton("Cancel") { dialog, _ -> setNegButton("Cancel") { filterTag = null }
filterTag = null show()
dialog.dismiss()
} }
val dialog = alertDialog.show()
dialog?.window?.setDimAmount(0.8f)
} }
var isFetching = false var isFetching = false
@ -303,13 +298,12 @@ class CommentsFragment : Fragment() {
activity.binding.commentLabel.setOnClickListener { activity.binding.commentLabel.setOnClickListener {
//alert dialog to enter a number, with a cancel and ok button //alert dialog to enter a number, with a cancel and ok button
val alertDialog = AlertDialog.Builder(activity, R.style.MyPopup) activity.customAlertDialog().apply {
.setTitle("Enter a chapter/episode number tag") val customView = DialogEdittextBinding.inflate(layoutInflater)
.setView(R.layout.dialog_edittext) setTitle("Enter a chapter/episode number tag")
.setPositiveButton("OK") { dialog, _ -> setCustomView(customView.root)
val editText = setPosButton("OK") {
(dialog as AlertDialog).findViewById<EditText>(R.id.dialogEditText) val text = customView.dialogEditText.text.toString()
val text = editText?.text.toString()
tag = text.toIntOrNull() tag = text.toIntOrNull()
if (tag == null) { if (tag == null) {
activity.binding.commentLabel.background = ResourcesCompat.getDrawable( activity.binding.commentLabel.background = ResourcesCompat.getDrawable(
@ -324,28 +318,25 @@ class CommentsFragment : Fragment() {
null null
) )
} }
dialog.dismiss()
} }
.setNeutralButton("Clear") { dialog, _ -> setNeutralButton("Clear") {
tag = null tag = null
activity.binding.commentLabel.background = ResourcesCompat.getDrawable( activity.binding.commentLabel.background = ResourcesCompat.getDrawable(
resources, resources,
R.drawable.ic_label_off_24, R.drawable.ic_label_off_24,
null null
) )
dialog.dismiss()
} }
.setNegativeButton("Cancel") { dialog, _ -> setNegButton("Cancel") {
tag = null tag = null
activity.binding.commentLabel.background = ResourcesCompat.getDrawable( activity.binding.commentLabel.background = ResourcesCompat.getDrawable(
resources, resources,
R.drawable.ic_label_off_24, R.drawable.ic_label_off_24,
null null
) )
dialog.dismiss()
} }
val dialog = alertDialog.show() show()
dialog?.window?.setDimAmount(0.8f) }
} }
} }
@ -362,12 +353,6 @@ class CommentsFragment : Fragment() {
} }
} }
} }
@SuppressLint("NotifyDataSetChanged")
override fun onStart() {
super.onStart()
}
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
@ -579,9 +564,9 @@ class CommentsFragment : Fragment() {
* Called when the user tries to comment for the first time * Called when the user tries to comment for the first time
*/ */
private fun showCommentRulesDialog() { private fun showCommentRulesDialog() {
val alertDialog = AlertDialog.Builder(activity, R.style.MyPopup) activity.customAlertDialog().apply{
.setTitle("Commenting Rules") setTitle("Commenting Rules")
.setMessage( setMessage(
"I WILL BAN YOU WITHOUT HESITATION\n" + "I WILL BAN YOU WITHOUT HESITATION\n" +
"1. No racism\n" + "1. No racism\n" +
"2. No hate speech\n" + "2. No hate speech\n" +
@ -594,16 +579,13 @@ class CommentsFragment : Fragment() {
"10. No illegal content\n" + "10. No illegal content\n" +
"11. Anything you know you shouldn't comment\n" "11. Anything you know you shouldn't comment\n"
) )
.setPositiveButton("I Understand") { dialog, _ -> setPosButton("I Understand") {
dialog.dismiss()
PrefManager.setVal(PrefName.FirstComment, false) PrefManager.setVal(PrefName.FirstComment, false)
processComment() processComment()
} }
.setNegativeButton("Cancel") { dialog, _ -> setNegButton(R.string.cancel)
dialog.dismiss() show()
} }
val dialog = alertDialog.show()
dialog?.window?.setDimAmount(0.8f)
} }
private fun processComment() { private fun processComment() {

View file

@ -19,6 +19,7 @@ import androidx.recyclerview.widget.RecyclerView
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.currActivity import ani.dantotsu.currActivity
import ani.dantotsu.currContext import ani.dantotsu.currContext
import ani.dantotsu.databinding.CustomDialogLayoutBinding
import ani.dantotsu.databinding.DialogLayoutBinding import ani.dantotsu.databinding.DialogLayoutBinding
import ani.dantotsu.databinding.ItemAnimeWatchBinding import ani.dantotsu.databinding.ItemAnimeWatchBinding
import ani.dantotsu.databinding.ItemChipBinding import ani.dantotsu.databinding.ItemChipBinding
@ -40,6 +41,7 @@ import ani.dantotsu.settings.FAQActivity
import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.toast import ani.dantotsu.toast
import ani.dantotsu.util.customAlertDialog
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import eu.kanade.tachiyomi.data.notification.Notifications.CHANNEL_SUBSCRIPTION_CHECK import eu.kanade.tachiyomi.data.notification.Notifications.CHANNEL_SUBSCRIPTION_CHECK
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
@ -65,8 +67,6 @@ class MangaReadAdapter(
return ViewHolder(bind) return ViewHolder(bind)
} }
private var nestedDialog: AlertDialog? = null
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val binding = holder.binding val binding = holder.binding
_binding = binding _binding = binding
@ -171,35 +171,33 @@ class MangaReadAdapter(
} }
binding.animeNestedButton.setOnClickListener { binding.animeNestedButton.setOnClickListener {
val dialogBinding = DialogLayoutBinding.inflate(fragment.layoutInflater)
val dialogView =
LayoutInflater.from(fragment.requireContext()).inflate(R.layout.dialog_layout, null)
val dialogBinding = DialogLayoutBinding.bind(dialogView)
var refresh = false var refresh = false
var run = false var run = false
var reversed = media.selected!!.recyclerReversed var reversed = media.selected!!.recyclerReversed
var style = var style =
media.selected!!.recyclerStyle ?: PrefManager.getVal(PrefName.MangaDefaultView) media.selected!!.recyclerStyle ?: PrefManager.getVal(PrefName.MangaDefaultView)
dialogBinding.animeSourceTop.rotation = if (reversed) -90f else 90f dialogBinding.apply {
dialogBinding.sortText.text = if (reversed) "Down to Up" else "Up to Down" animeSourceTop.rotation = if (reversed) -90f else 90f
dialogBinding.animeSourceTop.setOnClickListener { sortText.text = if (reversed) "Down to Up" else "Up to Down"
animeSourceTop.setOnClickListener {
reversed = !reversed reversed = !reversed
dialogBinding.animeSourceTop.rotation = if (reversed) -90f else 90f animeSourceTop.rotation = if (reversed) -90f else 90f
dialogBinding.sortText.text = if (reversed) "Down to Up" else "Up to Down" sortText.text = if (reversed) "Down to Up" else "Up to Down"
run = true run = true
} }
//Grids //Grids
dialogBinding.animeSourceGrid.visibility = View.GONE animeSourceGrid.visibility = View.GONE
var selected = when (style) { var selected = when (style) {
0 -> dialogBinding.animeSourceList 0 -> animeSourceList
1 -> dialogBinding.animeSourceCompact 1 -> animeSourceCompact
else -> dialogBinding.animeSourceList else -> animeSourceList
} }
when (style) { when (style) {
0 -> dialogBinding.layoutText.setText(R.string.list) 0 -> layoutText.setText(R.string.list)
1 -> dialogBinding.layoutText.setText(R.string.compact) 1 -> layoutText.setText(R.string.compact)
else -> dialogBinding.animeSourceList else -> animeSourceList
} }
selected.alpha = 1f selected.alpha = 1f
fun selected(it: ImageButton) { fun selected(it: ImageButton) {
@ -207,19 +205,19 @@ class MangaReadAdapter(
selected = it selected = it
selected.alpha = 1f selected.alpha = 1f
} }
dialogBinding.animeSourceList.setOnClickListener { animeSourceList.setOnClickListener {
selected(it as ImageButton) selected(it as ImageButton)
style = 0 style = 0
dialogBinding.layoutText.setText(R.string.list) layoutText.setText(R.string.list)
run = true run = true
} }
dialogBinding.animeSourceCompact.setOnClickListener { animeSourceCompact.setOnClickListener {
selected(it as ImageButton) selected(it as ImageButton)
style = 1 style = 1
dialogBinding.layoutText.setText(R.string.compact) layoutText.setText(R.string.compact)
run = true run = true
} }
dialogBinding.animeWebviewContainer.setOnClickListener { animeWebviewContainer.setOnClickListener {
if (!WebViewUtil.supportsWebView(fragment.requireContext())) { if (!WebViewUtil.supportsWebView(fragment.requireContext())) {
toast(R.string.webview_not_installed) toast(R.string.webview_not_installed)
} }
@ -230,7 +228,8 @@ class MangaReadAdapter(
val url = sourceHttp?.baseUrl val url = sourceHttp?.baseUrl
url?.let { url?.let {
refresh = true refresh = true
val intent = Intent(fragment.requireContext(), CookieCatcher::class.java) val intent =
Intent(fragment.requireContext(), CookieCatcher::class.java)
.putExtra("url", url) .putExtra("url", url)
startActivity(fragment.requireContext(), intent, null) startActivity(fragment.requireContext(), intent, null)
} }
@ -238,36 +237,34 @@ class MangaReadAdapter(
} }
//Multi download //Multi download
dialogBinding.downloadNo.text = "0" downloadNo.text = "0"
dialogBinding.animeDownloadTop.setOnClickListener { animeDownloadTop.setOnClickListener {
//Alert dialog asking for the number of chapters to download //Alert dialog asking for the number of chapters to download
val alertDialog = AlertDialog.Builder(currContext(), R.style.MyPopup) fragment.requireContext().customAlertDialog().apply {
alertDialog.setTitle("Multi Chapter Downloader") setTitle("Multi Chapter Downloader")
alertDialog.setMessage("Enter the number of chapters to download") setMessage("Enter the number of chapters to download")
val input = NumberPicker(currContext()) val input = NumberPicker(currContext())
input.minValue = 1 input.minValue = 1
input.maxValue = 20 input.maxValue = 20
input.value = 1 input.value = 1
alertDialog.setView(input) setCustomView(input)
alertDialog.setPositiveButton("OK") { _, _ -> setPosButton(R.string.ok) {
dialogBinding.downloadNo.text = "${input.value}" downloadNo.text = "${input.value}"
}
setNegButton(R.string.cancel)
show()
} }
alertDialog.setNegativeButton("Cancel") { dialog, _ -> dialog.cancel() }
val dialog = alertDialog.show()
dialog.window?.setDimAmount(0.8f)
} }
//Scanlator //Scanlator
dialogBinding.animeScanlatorContainer.isVisible = options.count() > 1 animeScanlatorContainer.isVisible = options.count() > 1
dialogBinding.scanlatorNo.text = "${options.count()}" scanlatorNo.text = "${options.count()}"
dialogBinding.animeScanlatorTop.setOnClickListener { animeScanlatorTop.setOnClickListener {
val dialogView2 = CustomDialogLayoutBinding.inflate(fragment.layoutInflater)
LayoutInflater.from(currContext()).inflate(R.layout.custom_dialog_layout, null) val dialogView = CustomDialogLayoutBinding.inflate(fragment.layoutInflater)
val checkboxContainer = val checkboxContainer = dialogView.checkboxContainer
dialogView2.findViewById<LinearLayout>(R.id.checkboxContainer) val tickAllButton = dialogView.toggleButton
val tickAllButton = dialogView2.findViewById<ImageButton>(R.id.toggleButton)
// Function to get the right image resource for the toggle button
fun getToggleImageResource(container: ViewGroup): Int { fun getToggleImageResource(container: ViewGroup): Int {
var allChecked = true var allChecked = true
var allUnchecked = true var allUnchecked = true
@ -287,17 +284,14 @@ class MangaReadAdapter(
} }
} }
// Dynamically add checkboxes
options.forEach { option -> options.forEach { option ->
val checkBox = CheckBox(currContext()).apply { val checkBox = CheckBox(currContext()).apply {
text = option text = option
setOnCheckedChangeListener { _, _ -> setOnCheckedChangeListener { _, _ ->
// Update image resource when you change a checkbox
tickAllButton.setImageResource(getToggleImageResource(checkboxContainer)) tickAllButton.setImageResource(getToggleImageResource(checkboxContainer))
} }
} }
// Set checked if its already selected
if (media.selected!!.scanlators != null) { if (media.selected!!.scanlators != null) {
checkBox.isChecked = media.selected!!.scanlators?.contains(option) != true checkBox.isChecked = media.selected!!.scanlators?.contains(option) != true
scanlatorSelectionListener?.onScanlatorsSelected() scanlatorSelectionListener?.onScanlatorsSelected()
@ -307,10 +301,9 @@ class MangaReadAdapter(
checkboxContainer.addView(checkBox) checkboxContainer.addView(checkBox)
} }
// Create AlertDialog fragment.requireContext().customAlertDialog().apply {
val dialog = AlertDialog.Builder(currContext(), R.style.MyPopup) setCustomView(dialogView.root)
.setView(dialogView2) setPosButton("OK") {
.setPositiveButton("OK") { _, _ ->
hiddenScanlators.clear() hiddenScanlators.clear()
for (i in 0 until checkboxContainer.childCount) { for (i in 0 until checkboxContainer.childCount) {
val checkBox = checkboxContainer.getChildAt(i) as CheckBox val checkBox = checkboxContainer.getChildAt(i) as CheckBox
@ -321,44 +314,36 @@ class MangaReadAdapter(
fragment.onScanlatorChange(hiddenScanlators) fragment.onScanlatorChange(hiddenScanlators)
scanlatorSelectionListener?.onScanlatorsSelected() scanlatorSelectionListener?.onScanlatorsSelected()
} }
.setNegativeButton("Cancel", null) setNegButton("Cancel")
.show() }.show()
dialog.window?.setDimAmount(0.8f)
// Standard image resource
tickAllButton.setImageResource(getToggleImageResource(checkboxContainer)) tickAllButton.setImageResource(getToggleImageResource(checkboxContainer))
// Listens to ticked checkboxes and changes image resource accordingly
tickAllButton.setOnClickListener { tickAllButton.setOnClickListener {
// Toggle checkboxes
for (i in 0 until checkboxContainer.childCount) { for (i in 0 until checkboxContainer.childCount) {
val checkBox = checkboxContainer.getChildAt(i) as CheckBox val checkBox = checkboxContainer.getChildAt(i) as CheckBox
checkBox.isChecked = !checkBox.isChecked checkBox.isChecked = !checkBox.isChecked
} }
// Update image resource
tickAllButton.setImageResource(getToggleImageResource(checkboxContainer)) tickAllButton.setImageResource(getToggleImageResource(checkboxContainer))
} }
} }
nestedDialog = AlertDialog.Builder(fragment.requireContext(), R.style.MyPopup) fragment.requireContext().customAlertDialog().apply {
.setTitle("Options") setTitle("Options")
.setView(dialogView) setCustomView(root)
.setPositiveButton("OK") { _, _ -> setPosButton("OK") {
if (run) fragment.onIconPressed(style, reversed) if (run) fragment.onIconPressed(style, reversed)
if (dialogBinding.downloadNo.text != "0") { if (downloadNo.text != "0") {
fragment.multiDownload(dialogBinding.downloadNo.text.toString().toInt()) fragment.multiDownload(downloadNo.text.toString().toInt())
} }
if (refresh) fragment.loadChapters(source, true) if (refresh) fragment.loadChapters(source, true)
} }
.setNegativeButton("Cancel") { _, _ -> setNegButton("Cancel") {
if (refresh) fragment.loadChapters(source, true) if (refresh) fragment.loadChapters(source, true)
} }
.setOnCancelListener { show()
if (refresh) fragment.loadChapters(source, true) }
} }
.create()
nestedDialog?.show()
} }
//Chapter Handling //Chapter Handling
handleChapters() handleChapters()

View file

@ -60,6 +60,7 @@ import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.util.StoragePermissions.Companion.accessAlertDialog import ani.dantotsu.util.StoragePermissions.Companion.accessAlertDialog
import ani.dantotsu.util.StoragePermissions.Companion.hasDirAccess import ani.dantotsu.util.StoragePermissions.Companion.hasDirAccess
import ani.dantotsu.util.customAlertDialog
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
@ -386,16 +387,13 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
if (allSettings.size > 1) { if (allSettings.size > 1) {
val names = val names =
allSettings.map { LanguageMapper.getLanguageName(it.lang) }.toTypedArray() allSettings.map { LanguageMapper.getLanguageName(it.lang) }.toTypedArray()
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup) requireContext().customAlertDialog().apply {
.setTitle("Select a Source") setTitle("Select a Source")
.setSingleChoiceItems(names, -1) { dialog, which -> singleChoiceItems(names) { which ->
selectedSetting = allSettings[which] selectedSetting = allSettings[which]
itemSelected = true itemSelected = true
dialog.dismiss()
// Move the fragment transaction here val fragment = MangaSourcePreferencesFragment().getInstance(selectedSetting.id) {
val fragment =
MangaSourcePreferencesFragment().getInstance(selectedSetting.id) {
changeUIVisibility(true) changeUIVisibility(true)
loadChapters(media.selected!!.sourceIndex, true) loadChapters(media.selected!!.sourceIndex, true)
} }
@ -405,13 +403,14 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
.addToBackStack(null) .addToBackStack(null)
.commit() .commit()
} }
.setOnDismissListener { onDismiss{
if (!itemSelected) { if (!itemSelected) {
changeUIVisibility(true) changeUIVisibility(true)
} }
} }
.show() show()
dialog.window?.setDimAmount(0.8f)
}
} else { } else {
// If there's only one setting, proceed with the fragment transaction // If there's only one setting, proceed with the fragment transaction
val fragment = MangaSourcePreferencesFragment().getInstance(selectedSetting.id) { val fragment = MangaSourcePreferencesFragment().getInstance(selectedSetting.id) {

View file

@ -83,6 +83,7 @@ import ani.dantotsu.showSystemBarsRetractView
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.themes.ThemeManager import ani.dantotsu.themes.ThemeManager
import ani.dantotsu.tryWith import ani.dantotsu.tryWith
import ani.dantotsu.util.customAlertDialog
import com.alexvasilkov.gestures.views.GestureFrameLayout import com.alexvasilkov.gestures.views.GestureFrameLayout
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
@ -1013,28 +1014,27 @@ class MangaReaderActivity : AppCompatActivity() {
PrefManager.setCustomVal("${media.id}_progressDialog", !isChecked) PrefManager.setCustomVal("${media.id}_progressDialog", !isChecked)
showProgressDialog = !isChecked showProgressDialog = !isChecked
} }
AlertDialog.Builder(this, R.style.MyPopup) customAlertDialog().apply {
.setTitle(getString(R.string.title_update_progress)) setTitle(R.string.title_update_progress)
.setView(dialogView) setCustomView(dialogView)
.setCancelable(false) setCancelable(false)
.setPositiveButton(getString(R.string.yes)) { dialog, _ -> setPosButton(R.string.yes) {
PrefManager.setCustomVal("${media.id}_save_progress", true) PrefManager.setCustomVal("${media.id}_save_progress", true)
updateProgress( updateProgress(
media, media,
MediaNameAdapter.findChapterNumber(media.manga!!.selectedChapter!!) MediaNameAdapter.findChapterNumber(media.manga!!.selectedChapter!!)
.toString() .toString()
) )
dialog.dismiss()
runnable.run() runnable.run()
} }
.setNegativeButton(getString(R.string.no)) { dialog, _ -> setNegButton(R.string.no) {
PrefManager.setCustomVal("${media.id}_save_progress", false) PrefManager.setCustomVal("${media.id}_save_progress", false)
dialog.dismiss()
runnable.run() runnable.run()
} }
.setOnCancelListener { hideSystemBars() } setOnCancelListener { hideSystemBars() }
.create() show()
.show()
}
} else { } else {
if (!incognito && PrefManager.getCustomVal( if (!incognito && PrefManager.getCustomVal(
"${media.id}_save_progress", "${media.id}_save_progress",

View file

@ -13,6 +13,7 @@ import ani.dantotsu.parsers.ShowResponse
import ani.dantotsu.setAnimation import ani.dantotsu.setAnimation
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import ani.dantotsu.util.customAlertDialog
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl import com.bumptech.glide.load.model.GlideUrl
@ -93,13 +94,10 @@ class NovelResponseAdapter(
} }
binding.root.setOnLongClickListener { binding.root.setOnLongClickListener {
val builder = androidx.appcompat.app.AlertDialog.Builder( it.context.customAlertDialog().apply {
fragment.requireContext(), setTitle("Delete ${novel.name}?")
R.style.MyPopup setMessage("Are you sure you want to delete ${novel.name}?")
) setPosButton(R.string.yes) {
builder.setTitle("Delete ${novel.name}?")
builder.setMessage("Are you sure you want to delete ${novel.name}?")
builder.setPositiveButton("Yes") { _, _ ->
downloadedCheckCallback.deleteDownload(novel) downloadedCheckCallback.deleteDownload(novel)
deleteDownload(novel.link) deleteDownload(novel.link)
snackString("Deleted ${novel.name}") snackString("Deleted ${novel.name}")
@ -109,11 +107,9 @@ class NovelResponseAdapter(
binding.itemEpisodeFiller.text = "" binding.itemEpisodeFiller.text = ""
} }
} }
builder.setNegativeButton("No") { _, _ -> setNegButton(R.string.no)
// Do nothing show()
} }
val dialog = builder.show()
dialog.window?.setDimAmount(0.8f)
true true
} }
} }

View file

@ -11,7 +11,6 @@ import ani.dantotsu.buildMarkwon
import ani.dantotsu.connections.anilist.Anilist import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.connections.anilist.api.Activity import ani.dantotsu.connections.anilist.api.Activity
import ani.dantotsu.databinding.ItemActivityBinding import ani.dantotsu.databinding.ItemActivityBinding
import ani.dantotsu.home.status.RepliesBottomDialog
import ani.dantotsu.loadImage import ani.dantotsu.loadImage
import ani.dantotsu.profile.User import ani.dantotsu.profile.User
import ani.dantotsu.profile.UsersDialogFragment import ani.dantotsu.profile.UsersDialogFragment

View file

@ -1,4 +1,4 @@
package ani.dantotsu.home.status package ani.dantotsu.profile.activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
@ -14,7 +14,6 @@ import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.connections.anilist.api.ActivityReply import ani.dantotsu.connections.anilist.api.ActivityReply
import ani.dantotsu.databinding.BottomSheetRecyclerBinding import ani.dantotsu.databinding.BottomSheetRecyclerBinding
import ani.dantotsu.profile.ProfileActivity import ani.dantotsu.profile.ProfileActivity
import ani.dantotsu.profile.activity.ActivityReplyItem
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.util.ActivityMarkdownCreator import ani.dantotsu.util.ActivityMarkdownCreator
import com.xwray.groupie.GroupieAdapter import com.xwray.groupie.GroupieAdapter
@ -72,14 +71,10 @@ class RepliesBottomDialog : BottomSheetDialogFragment() {
adapter.update( adapter.update(
replies.map { replies.map {
ActivityReplyItem( ActivityReplyItem(
it, it, activityId, requireActivity(), adapter,
activityId, ) { i, _ ->
requireActivity(), onClick(i)
adapter,
clickCallback = { int, _ ->
onClick(int)
} }
)
} }
) )
} else { } else {

View file

@ -35,6 +35,7 @@ import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.statusBarHeight import ani.dantotsu.statusBarHeight
import ani.dantotsu.themes.ThemeManager import ani.dantotsu.themes.ThemeManager
import ani.dantotsu.util.customAlertDialog
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
@ -178,25 +179,20 @@ class ExtensionsActivity : AppCompatActivity() {
entry.name.lowercase().replace("_", " ") entry.name.lowercase().replace("_", " ")
.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString() } .replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString() }
}.toTypedArray() }.toTypedArray()
val builder = AlertDialog.Builder(this, R.style.MyPopup)
val listOrder: String = PrefManager.getVal(PrefName.LangSort) val listOrder: String = PrefManager.getVal(PrefName.LangSort)
val index = LanguageMapper.Companion.Language.entries.toTypedArray() val index = LanguageMapper.Companion.Language.entries.toTypedArray()
.indexOfFirst { it.code == listOrder } .indexOfFirst { it.code == listOrder }
builder.setTitle("Language") customAlertDialog().apply {
builder.setSingleChoiceItems(languageOptions, index) { dialog, i -> setTitle("Language")
PrefManager.setVal( singleChoiceItems(languageOptions, index) { selected ->
PrefName.LangSort, PrefManager.setVal(PrefName.LangSort, LanguageMapper.Companion.Language.entries[selected].code)
LanguageMapper.Companion.Language.entries[i].code val currentFragment = supportFragmentManager.findFragmentByTag("f${viewPager.currentItem}")
)
val currentFragment =
supportFragmentManager.findFragmentByTag("f${viewPager.currentItem}")
if (currentFragment is SearchQueryHandler) { if (currentFragment is SearchQueryHandler) {
currentFragment.notifyDataChanged() currentFragment.notifyDataChanged()
} }
dialog.dismiss()
} }
val dialog = builder.show() show()
dialog.window?.setDimAmount(0.8f) }
} }
binding.settingsContainer.updateLayoutParams<ViewGroup.MarginLayoutParams> { binding.settingsContainer.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = statusBarHeight topMargin = statusBarHeight
@ -247,10 +243,10 @@ class ExtensionsActivity : AppCompatActivity() {
) )
view.repositoryItem.text = item.removePrefix("https://raw.githubusercontent.com") view.repositoryItem.text = item.removePrefix("https://raw.githubusercontent.com")
view.repositoryItem.setOnClickListener { view.repositoryItem.setOnClickListener {
AlertDialog.Builder(this@ExtensionsActivity, R.style.MyPopup) customAlertDialog().apply {
.setTitle(R.string.rem_repository) setTitle(R.string.rem_repository)
.setMessage(item) setMessage(item)
.setPositiveButton(getString(R.string.ok)) { dialog, _ -> setPosButton(R.string.ok) {
val repos = PrefManager.getVal<Set<String>>(prefName).minus(item) val repos = PrefManager.getVal<Set<String>>(prefName).minus(item)
PrefManager.setVal(prefName, repos) PrefManager.setVal(prefName, repos)
repoInventory.removeView(view.root) repoInventory.removeView(view.root)
@ -267,13 +263,10 @@ class ExtensionsActivity : AppCompatActivity() {
else -> {} else -> {}
} }
} }
dialog.dismiss()
} }
.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> setNegButton(R.string.cancel)
dialog.dismiss() show()
} }
.create()
.show()
} }
view.repositoryItem.setOnLongClickListener { view.repositoryItem.setOnLongClickListener {
it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
@ -324,20 +317,18 @@ class ExtensionsActivity : AppCompatActivity() {
dialogView.repoInventory.apply { dialogView.repoInventory.apply {
getSavedRepositories(this, type) getSavedRepositories(this, type)
} }
val alertDialog = AlertDialog.Builder(this@ExtensionsActivity, R.style.MyPopup) processEditorAction(dialogView.repositoryTextBox, type)
.setTitle(R.string.edit_repositories) customAlertDialog().apply {
.setView(dialogView.root) setTitle(R.string.edit_repositories)
.setPositiveButton(getString(R.string.add)) { _, _ -> setCustomView(dialogView.root)
if (!dialogView.repositoryTextBox.text.isNullOrBlank()) setPosButton(R.string.add) {
if (!dialogView.repositoryTextBox.text.isNullOrBlank()) {
processUserInput(dialogView.repositoryTextBox.text.toString(), type) processUserInput(dialogView.repositoryTextBox.text.toString(), type)
} }
.setNegativeButton(getString(R.string.close)) { dialog, _ ->
dialog.dismiss()
} }
.create() setNegButton(R.string.close)
processEditorAction(dialogView.repositoryTextBox, type) show()
alertDialog.show() }
alertDialog.window?.setDimAmount(0.8f)
} }
} }
} }

View file

@ -25,13 +25,15 @@ import androidx.viewpager2.widget.ViewPager2
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
import ani.dantotsu.databinding.FragmentExtensionsBinding import ani.dantotsu.databinding.FragmentExtensionsBinding
import ani.dantotsu.others.LanguageMapper import ani.dantotsu.others.LanguageMapper.Companion.getLanguageName
import ani.dantotsu.parsers.AnimeSources import ani.dantotsu.parsers.AnimeSources
import ani.dantotsu.settings.extensionprefs.AnimeSourcePreferencesFragment import ani.dantotsu.settings.extensionprefs.AnimeSourcePreferencesFragment
import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import ani.dantotsu.util.customAlertDialog
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
@ -72,16 +74,15 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
if (allSettings.isNotEmpty()) { if (allSettings.isNotEmpty()) {
var selectedSetting = allSettings[0] var selectedSetting = allSettings[0]
if (allSettings.size > 1) { if (allSettings.size > 1) {
val names = allSettings.map { LanguageMapper.getLanguageName(it.lang) } val names = allSettings.map { getLanguageName(it.lang) }
.toTypedArray() .toTypedArray()
var selectedIndex = 0 var selectedIndex = 0
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup) requireContext().customAlertDialog().apply {
.setTitle("Select a Source") setTitle("Select a Source")
.setSingleChoiceItems(names, selectedIndex) { dialog, which -> singleChoiceItems(names, selectedIndex) { which ->
itemSelected = true itemSelected = true
selectedIndex = which selectedIndex = which
selectedSetting = allSettings[selectedIndex] selectedSetting = allSettings[selectedIndex]
dialog.dismiss()
val fragment = val fragment =
AnimeSourcePreferencesFragment().getInstance(selectedSetting.id) { AnimeSourcePreferencesFragment().getInstance(selectedSetting.id) {
@ -93,13 +94,13 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
.addToBackStack(null) .addToBackStack(null)
.commit() .commit()
} }
.setOnDismissListener { onDismiss {
if (!itemSelected) { if (!itemSelected) {
changeUIVisibility(true) changeUIVisibility(true)
} }
} }
.show() show()
dialog.window?.setDimAmount(0.8f) }
} else { } else {
// If there's only one setting, proceed with the fragment transaction // If there's only one setting, proceed with the fragment transaction
val fragment = val fragment =
@ -295,7 +296,7 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val extension = getItem(position) val extension = getItem(position)
val nsfw = if (extension.isNsfw) "(18+)" else "" val nsfw = if (extension.isNsfw) "(18+)" else ""
val lang = LanguageMapper.getLanguageName(extension.lang) val lang = getLanguageName(extension.lang)
holder.extensionNameTextView.text = extension.name holder.extensionNameTextView.text = extension.name
val versionText = "$lang ${extension.versionName} $nsfw" val versionText = "$lang ${extension.versionName} $nsfw"
holder.extensionVersionTextView.text = versionText holder.extensionVersionTextView.text = versionText

View file

@ -34,6 +34,7 @@ import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import ani.dantotsu.util.customAlertDialog
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.notification.Notifications
@ -74,13 +75,12 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
val names = allSettings.map { LanguageMapper.getLanguageName(it.lang) } val names = allSettings.map { LanguageMapper.getLanguageName(it.lang) }
.toTypedArray() .toTypedArray()
var selectedIndex = 0 var selectedIndex = 0
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup) requireContext().customAlertDialog().apply {
.setTitle("Select a Source") setTitle("Select a Source")
.setSingleChoiceItems(names, selectedIndex) { dialog, which -> singleChoiceItems(names, selectedIndex) { which ->
itemSelected = true itemSelected = true
selectedIndex = which selectedIndex = which
selectedSetting = allSettings[selectedIndex] selectedSetting = allSettings[selectedIndex]
dialog.dismiss()
// Move the fragment transaction here // Move the fragment transaction here
val fragment = val fragment =
@ -93,13 +93,13 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
.addToBackStack(null) .addToBackStack(null)
.commit() .commit()
} }
.setOnDismissListener { onDismiss {
if (!itemSelected) { if (!itemSelected) {
changeUIVisibility(true) changeUIVisibility(true)
} }
} }
.show() show()
dialog.window?.setDimAmount(0.8f) }
} else { } else {
// If there's only one setting, proceed with the fragment transaction // If there's only one setting, proceed with the fragment transaction
val fragment = val fragment =

View file

@ -28,6 +28,7 @@ import ani.dantotsu.snackString
import ani.dantotsu.statusBarHeight import ani.dantotsu.statusBarHeight
import ani.dantotsu.themes.ThemeManager import ani.dantotsu.themes.ThemeManager
import ani.dantotsu.toast import ani.dantotsu.toast
import ani.dantotsu.util.customAlertDialog
import com.google.android.material.slider.Slider.OnChangeListener import com.google.android.material.slider.Slider.OnChangeListener
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -100,20 +101,19 @@ class PlayerSettingsActivity : AppCompatActivity() {
R.string.default_playback_speed, R.string.default_playback_speed,
speedsName[PrefManager.getVal(PrefName.DefaultSpeed)] speedsName[PrefManager.getVal(PrefName.DefaultSpeed)]
) )
val speedDialog = AlertDialog.Builder(this, R.style.MyPopup)
.setTitle(getString(R.string.default_speed))
binding.playerSettingsSpeed.setOnClickListener { binding.playerSettingsSpeed.setOnClickListener {
val dialog = customAlertDialog().apply {
speedDialog.setSingleChoiceItems( setTitle(getString(R.string.default_speed))
singleChoiceItems(
speedsName, speedsName,
PrefManager.getVal(PrefName.DefaultSpeed) PrefManager.getVal(PrefName.DefaultSpeed)
) { dialog, i -> ) { i ->
PrefManager.setVal(PrefName.DefaultSpeed, i) PrefManager.setVal(PrefName.DefaultSpeed, i)
binding.playerSettingsSpeed.text = binding.playerSettingsSpeed.text =
getString(R.string.default_playback_speed, speedsName[i]) getString(R.string.default_playback_speed, speedsName[i])
dialog.dismiss() }
}.show() show()
dialog.window?.setDimAmount(0.8f) }
} }
binding.playerSettingsCursedSpeeds.isChecked = PrefManager.getVal(PrefName.CursedSpeeds) binding.playerSettingsCursedSpeeds.isChecked = PrefManager.getVal(PrefName.CursedSpeeds)
@ -278,17 +278,17 @@ class PlayerSettingsActivity : AppCompatActivity() {
} }
val resizeModes = arrayOf("Original", "Zoom", "Stretch") val resizeModes = arrayOf("Original", "Zoom", "Stretch")
val resizeDialog = AlertDialog.Builder(this, R.style.MyPopup)
.setTitle(getString(R.string.default_resize_mode))
binding.playerResizeMode.setOnClickListener { binding.playerResizeMode.setOnClickListener {
val dialog = resizeDialog.setSingleChoiceItems( customAlertDialog().apply {
setTitle(getString(R.string.default_resize_mode))
singleChoiceItems(
resizeModes, resizeModes,
PrefManager.getVal<Int>(PrefName.Resize) PrefManager.getVal<Int>(PrefName.Resize)
) { dialog, count -> ) { count ->
PrefManager.setVal(PrefName.Resize, count) PrefManager.setVal(PrefName.Resize, count)
dialog.dismiss() }
}.show() show()
dialog.window?.setDimAmount(0.8f) }
} }
fun toggleSubOptions(isChecked: Boolean) { fun toggleSubOptions(isChecked: Boolean) {
@ -332,18 +332,18 @@ class PlayerSettingsActivity : AppCompatActivity() {
"Blue", "Blue",
"Magenta" "Magenta"
) )
val primaryColorDialog = AlertDialog.Builder(this, R.style.MyPopup)
.setTitle(getString(R.string.primary_sub_color))
binding.videoSubColorPrimary.setOnClickListener { binding.videoSubColorPrimary.setOnClickListener {
val dialog = primaryColorDialog.setSingleChoiceItems( customAlertDialog().apply {
setTitle(getString(R.string.primary_sub_color))
singleChoiceItems(
colorsPrimary, colorsPrimary,
PrefManager.getVal(PrefName.PrimaryColor) PrefManager.getVal(PrefName.PrimaryColor)
) { dialog, count -> ) { count ->
PrefManager.setVal(PrefName.PrimaryColor, count) PrefManager.setVal(PrefName.PrimaryColor, count)
dialog.dismiss()
updateSubPreview() updateSubPreview()
}.show() }
dialog.window?.setDimAmount(0.8f) show()
}
} }
val colorsSecondary = arrayOf( val colorsSecondary = arrayOf(
"Black", "Black",
@ -359,32 +359,32 @@ class PlayerSettingsActivity : AppCompatActivity() {
"Magenta", "Magenta",
"Transparent" "Transparent"
) )
val secondaryColorDialog = AlertDialog.Builder(this, R.style.MyPopup)
.setTitle(getString(R.string.outline_sub_color))
binding.videoSubColorSecondary.setOnClickListener { binding.videoSubColorSecondary.setOnClickListener {
val dialog = secondaryColorDialog.setSingleChoiceItems( customAlertDialog().apply {
setTitle(getString(R.string.outline_sub_color))
singleChoiceItems(
colorsSecondary, colorsSecondary,
PrefManager.getVal(PrefName.SecondaryColor) PrefManager.getVal(PrefName.SecondaryColor)
) { dialog, count -> ) { count ->
PrefManager.setVal(PrefName.SecondaryColor, count) PrefManager.setVal(PrefName.SecondaryColor, count)
dialog.dismiss()
updateSubPreview() updateSubPreview()
}.show() }
dialog.window?.setDimAmount(0.8f) show()
}
} }
val typesOutline = arrayOf("Outline", "Shine", "Drop Shadow", "None") val typesOutline = arrayOf("Outline", "Shine", "Drop Shadow", "None")
val outlineDialog = AlertDialog.Builder(this, R.style.MyPopup)
.setTitle(getString(R.string.outline_type))
binding.videoSubOutline.setOnClickListener { binding.videoSubOutline.setOnClickListener {
val dialog = outlineDialog.setSingleChoiceItems( customAlertDialog().apply {
setTitle(getString(R.string.outline_type))
singleChoiceItems(
typesOutline, typesOutline,
PrefManager.getVal(PrefName.Outline) PrefManager.getVal(PrefName.Outline)
) { dialog, count -> ) { count ->
PrefManager.setVal(PrefName.Outline, count) PrefManager.setVal(PrefName.Outline, count)
dialog.dismiss()
updateSubPreview() updateSubPreview()
}.show() }
dialog.window?.setDimAmount(0.8f) show()
}
} }
val colorsSubBackground = arrayOf( val colorsSubBackground = arrayOf(
"Transparent", "Transparent",
@ -400,18 +400,18 @@ class PlayerSettingsActivity : AppCompatActivity() {
"Blue", "Blue",
"Magenta" "Magenta"
) )
val subBackgroundDialog = AlertDialog.Builder(this, R.style.MyPopup)
.setTitle(getString(R.string.sub_background_color_select))
binding.videoSubColorBackground.setOnClickListener { binding.videoSubColorBackground.setOnClickListener {
val dialog = subBackgroundDialog.setSingleChoiceItems( customAlertDialog().apply {
setTitle(getString(R.string.sub_background_color_select))
singleChoiceItems(
colorsSubBackground, colorsSubBackground,
PrefManager.getVal(PrefName.SubBackground) PrefManager.getVal(PrefName.SubBackground)
) { dialog, count -> ) { count ->
PrefManager.setVal(PrefName.SubBackground, count) PrefManager.setVal(PrefName.SubBackground, count)
dialog.dismiss()
updateSubPreview() updateSubPreview()
}.show() }
dialog.window?.setDimAmount(0.8f) show()
}
} }
val colorsSubWindow = arrayOf( val colorsSubWindow = arrayOf(
@ -428,18 +428,18 @@ class PlayerSettingsActivity : AppCompatActivity() {
"Blue", "Blue",
"Magenta" "Magenta"
) )
val subWindowDialog = AlertDialog.Builder(this, R.style.MyPopup)
.setTitle(getString(R.string.sub_window_color_select))
binding.videoSubColorWindow.setOnClickListener { binding.videoSubColorWindow.setOnClickListener {
val dialog = subWindowDialog.setSingleChoiceItems( customAlertDialog().apply {
setTitle(getString(R.string.sub_window_color_select))
singleChoiceItems(
colorsSubWindow, colorsSubWindow,
PrefManager.getVal(PrefName.SubWindow) PrefManager.getVal(PrefName.SubWindow)
) { dialog, count -> ) { count ->
PrefManager.setVal(PrefName.SubWindow, count) PrefManager.setVal(PrefName.SubWindow, count)
dialog.dismiss()
updateSubPreview() updateSubPreview()
}.show() }
dialog.window?.setDimAmount(0.8f) show()
}
} }
binding.videoSubAlpha.value = PrefManager.getVal(PrefName.SubAlpha) binding.videoSubAlpha.value = PrefManager.getVal(PrefName.SubAlpha)
@ -459,18 +459,18 @@ class PlayerSettingsActivity : AppCompatActivity() {
"Levenim MT Bold", "Levenim MT Bold",
"Blocky" "Blocky"
) )
val fontDialog = AlertDialog.Builder(this, R.style.MyPopup)
.setTitle(getString(R.string.subtitle_font))
binding.videoSubFont.setOnClickListener { binding.videoSubFont.setOnClickListener {
val dialog = fontDialog.setSingleChoiceItems( customAlertDialog().apply {
setTitle(getString(R.string.subtitle_font))
singleChoiceItems(
fonts, fonts,
PrefManager.getVal(PrefName.Font) PrefManager.getVal(PrefName.Font)
) { dialog, count -> ) { count ->
PrefManager.setVal(PrefName.Font, count) PrefManager.setVal(PrefName.Font, count)
dialog.dismiss()
updateSubPreview() updateSubPreview()
}.show() }
dialog.window?.setDimAmount(0.8f) show()
}
} }
binding.subtitleFontSize.setText(PrefManager.getVal<Int>(PrefName.FontSize).toString()) binding.subtitleFontSize.setText(PrefManager.getVal<Int>(PrefName.FontSize).toString())
binding.subtitleFontSize.setOnEditorActionListener { _, actionId, _ -> binding.subtitleFontSize.setOnEditorActionListener { _, actionId, _ ->

View file

@ -20,6 +20,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.connections.anilist.Anilist import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.databinding.ActivitySettingsCommonBinding import ani.dantotsu.databinding.ActivitySettingsCommonBinding
import ani.dantotsu.databinding.DialogSetPasswordBinding
import ani.dantotsu.databinding.DialogUserAgentBinding import ani.dantotsu.databinding.DialogUserAgentBinding
import ani.dantotsu.download.DownloadsManager import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.initActivity import ani.dantotsu.initActivity
@ -37,6 +38,7 @@ import ani.dantotsu.themes.ThemeManager
import ani.dantotsu.toast import ani.dantotsu.toast
import ani.dantotsu.util.LauncherWrapper import ani.dantotsu.util.LauncherWrapper
import ani.dantotsu.util.StoragePermissions import ani.dantotsu.util.StoragePermissions
import ani.dantotsu.util.customAlertDialog
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
@ -160,18 +162,16 @@ class SettingsCommonActivity : AppCompatActivity() {
icon = R.drawable.ic_download_24, icon = R.drawable.ic_download_24,
onClick = { onClick = {
val managers = arrayOf("Default", "1DM", "ADM") val managers = arrayOf("Default", "1DM", "ADM")
val downloadManagerDialog = customAlertDialog().apply {
AlertDialog.Builder(context, R.style.MyPopup) setTitle(getString(R.string.download_manager))
.setTitle(R.string.download_manager) singleChoiceItems(
var downloadManager: Int = PrefManager.getVal(PrefName.DownloadManager) managers,
val dialog = downloadManagerDialog.setSingleChoiceItems( PrefManager.getVal(PrefName.DownloadManager)
managers, downloadManager ) { count ->
) { dialog, count -> PrefManager.setVal(PrefName.DownloadManager, count)
downloadManager = count }
PrefManager.setVal(PrefName.DownloadManager, downloadManager) show()
dialog.dismiss() }
}.show()
dialog.window?.setDimAmount(0.8f)
} }
), ),
Settings( Settings(
@ -180,90 +180,67 @@ class SettingsCommonActivity : AppCompatActivity() {
desc = getString(R.string.app_lock_desc), desc = getString(R.string.app_lock_desc),
icon = R.drawable.ic_round_lock_open_24, icon = R.drawable.ic_round_lock_open_24,
onClick = { onClick = {
val passwordDialog = AlertDialog.Builder(context, R.style.MyPopup) customAlertDialog().apply {
.setTitle(R.string.app_lock) val view = DialogSetPasswordBinding.inflate(layoutInflater)
.setView(R.layout.dialog_set_password) setTitle(R.string.app_lock)
.setPositiveButton(R.string.ok) { dialog, _ -> setCustomView(view.root)
val passwordInput = setPosButton(R.string.ok) {
(dialog as AlertDialog).findViewById<EditText>(R.id.passwordInput) if (view.forgotPasswordCheckbox.isChecked) {
val confirmPasswordInput =
dialog.findViewById<EditText>(R.id.confirmPasswordInput)
val forgotPasswordCheckbox =
dialog.findViewById<CheckBox>(R.id.forgotPasswordCheckbox)
if (forgotPasswordCheckbox?.isChecked == true) {
PrefManager.setVal(PrefName.OverridePassword, true) PrefManager.setVal(PrefName.OverridePassword, true)
} }
val password = view.passwordInput.text.toString()
val password = passwordInput?.text.toString() val confirmPassword = view.confirmPasswordInput.text.toString()
val confirmPassword = confirmPasswordInput?.text.toString()
if (password == confirmPassword && password.isNotEmpty()) { if (password == confirmPassword && password.isNotEmpty()) {
PrefManager.setVal(PrefName.AppPassword, password) PrefManager.setVal(PrefName.AppPassword, password)
if (dialog.findViewById<CheckBox>(R.id.biometricCheckbox)?.isChecked == true) { if (view.biometricCheckbox.isChecked) {
val canBiometricPrompt = val canBiometricPrompt =
BiometricManager.from(applicationContext) BiometricManager.from(applicationContext)
.canAuthenticate( .canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) == BiometricManager.BIOMETRIC_SUCCESS
BiometricManager.Authenticators.BIOMETRIC_WEAK
) == BiometricManager.BIOMETRIC_SUCCESS
if (canBiometricPrompt) { if (canBiometricPrompt) {
val biometricPrompt = val biometricPrompt =
BiometricPromptUtils.createBiometricPrompt( BiometricPromptUtils.createBiometricPrompt(this@SettingsCommonActivity) { _ ->
this@SettingsCommonActivity
) { _ ->
val token = UUID.randomUUID().toString() val token = UUID.randomUUID().toString()
PrefManager.setVal( PrefManager.setVal(
PrefName.BiometricToken, PrefName.BiometricToken,
token token
) )
toast(R.string.success) toast(R.string.success)
dialog.dismiss()
} }
val promptInfo = val promptInfo =
BiometricPromptUtils.createPromptInfo( BiometricPromptUtils.createPromptInfo(this@SettingsCommonActivity)
this@SettingsCommonActivity
)
biometricPrompt.authenticate(promptInfo) biometricPrompt.authenticate(promptInfo)
} }
} else { } else {
PrefManager.setVal(PrefName.BiometricToken, "") PrefManager.setVal(PrefName.BiometricToken, "")
toast(R.string.success) toast(R.string.success)
dialog.dismiss()
} }
} else { } else {
toast(R.string.password_mismatch) toast(R.string.password_mismatch)
} }
} }
.setNegativeButton(R.string.cancel) { dialog, _ -> setNegButton(R.string.cancel)
dialog.dismiss() setNeutralButton(R.string.remove){
}
.setNeutralButton(R.string.remove) { dialog, _ ->
PrefManager.setVal(PrefName.AppPassword, "") PrefManager.setVal(PrefName.AppPassword, "")
PrefManager.setVal(PrefName.BiometricToken, "") PrefManager.setVal(PrefName.BiometricToken, "")
PrefManager.setVal(PrefName.OverridePassword, false) PrefManager.setVal(PrefName.OverridePassword, false)
toast(R.string.success) toast(R.string.success)
dialog.dismiss()
} }
.create() setOnShowListener {
view.passwordInput.requestFocus()
passwordDialog.window?.setDimAmount(0.8f)
passwordDialog.setOnShowListener {
passwordDialog.findViewById<EditText>(R.id.passwordInput)
?.requestFocus()
val biometricCheckbox =
passwordDialog.findViewById<CheckBox>(R.id.biometricCheckbox)
val forgotPasswordCheckbox =
passwordDialog.findViewById<CheckBox>(R.id.forgotPasswordCheckbox)
val canAuthenticate = val canAuthenticate =
BiometricManager.from(applicationContext).canAuthenticate( BiometricManager.from(applicationContext).canAuthenticate(
BiometricManager.Authenticators.BIOMETRIC_WEAK BiometricManager.Authenticators.BIOMETRIC_WEAK
) == BiometricManager.BIOMETRIC_SUCCESS ) == BiometricManager.BIOMETRIC_SUCCESS
biometricCheckbox?.isVisible = canAuthenticate view.biometricCheckbox.isVisible = canAuthenticate
biometricCheckbox?.isChecked = view.biometricCheckbox.isChecked =
PrefManager.getVal(PrefName.BiometricToken, "").isNotEmpty() PrefManager.getVal(PrefName.BiometricToken, "").isNotEmpty()
forgotPasswordCheckbox?.isChecked = view.forgotPasswordCheckbox.isChecked =
PrefManager.getVal(PrefName.OverridePassword) PrefManager.getVal(PrefName.OverridePassword)
} }
passwordDialog.show() show()
}
} }
), ),

View file

@ -81,11 +81,11 @@ class SettingsExtensionsActivity : AppCompatActivity() {
view.repositoryItem.text = view.repositoryItem.text =
item.removePrefix("https://raw.githubusercontent.com/") item.removePrefix("https://raw.githubusercontent.com/")
view.repositoryItem.setOnClickListener { view.repositoryItem.setOnClickListener {
AlertDialog.Builder(context, R.style.MyPopup) context.customAlertDialog().apply {
.setTitle(R.string.rem_repository).setMessage(item) setTitle(R.string.rem_repository)
.setPositiveButton(getString(R.string.ok)) { dialog, _ -> setMessage(item)
val repos = setPosButton(R.string.ok) {
PrefManager.getVal<Set<String>>(repoList).minus(item) val repos = PrefManager.getVal<Set<String>>(repoList).minus(item)
PrefManager.setVal(repoList, repos) PrefManager.setVal(repoList, repos)
setExtensionOutput(repoInventory, type) setExtensionOutput(repoInventory, type)
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
@ -93,18 +93,16 @@ class SettingsExtensionsActivity : AppCompatActivity() {
MediaType.ANIME -> { MediaType.ANIME -> {
animeExtensionManager.findAvailableExtensions() animeExtensionManager.findAvailableExtensions()
} }
MediaType.MANGA -> { MediaType.MANGA -> {
mangaExtensionManager.findAvailableExtensions() mangaExtensionManager.findAvailableExtensions()
} }
else -> {} else -> {}
} }
} }
dialog.dismiss() }
}.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> setNegButton(R.string.cancel)
dialog.dismiss() show()
}.create().show() }
} }
view.repositoryItem.setOnLongClickListener { view.repositoryItem.setOnLongClickListener {
it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
@ -209,27 +207,27 @@ class SettingsExtensionsActivity : AppCompatActivity() {
val editText = dialogView.userAgentTextBox.apply { val editText = dialogView.userAgentTextBox.apply {
hint = getString(R.string.manga_add_repository) hint = getString(R.string.manga_add_repository)
} }
val alertDialog = AlertDialog.Builder(context, R.style.MyPopup) context.customAlertDialog().apply {
.setTitle(R.string.manga_add_repository).setView(dialogView.root) setTitle(R.string.manga_add_repository)
.setPositiveButton(getString(R.string.ok)) { dialog, _ -> setCustomView(dialogView.root)
setPosButton(R.string.ok) {
if (!editText.text.isNullOrBlank()) processUserInput( if (!editText.text.isNullOrBlank()) processUserInput(
editText.text.toString(), editText.text.toString(),
MediaType.MANGA, MediaType.MANGA,
it.attachView it.attachView
) )
dialog.dismiss() }
}.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> setNegButton(R.string.cancel)
dialog.dismiss() attach { dialog ->
}.create()
processEditorAction( processEditorAction(
alertDialog, dialog,
editText, editText,
MediaType.MANGA, MediaType.MANGA,
it.attachView it.attachView
) )
alertDialog.show() }
alertDialog.window?.setDimAmount(0.8f) }.show()
}, },
attach = { attach = {
setExtensionOutput(it.attachView, MediaType.MANGA) setExtensionOutput(it.attachView, MediaType.MANGA)
@ -258,24 +256,18 @@ class SettingsExtensionsActivity : AppCompatActivity() {
val dialogView = DialogUserAgentBinding.inflate(layoutInflater) val dialogView = DialogUserAgentBinding.inflate(layoutInflater)
val editText = dialogView.userAgentTextBox val editText = dialogView.userAgentTextBox
editText.setText(PrefManager.getVal<String>(PrefName.DefaultUserAgent)) editText.setText(PrefManager.getVal<String>(PrefName.DefaultUserAgent))
val alertDialog = AlertDialog.Builder(context, R.style.MyPopup) context.customAlertDialog().apply {
.setTitle(R.string.user_agent).setView(dialogView.root) setTitle(R.string.user_agent)
.setPositiveButton(getString(R.string.ok)) { dialog, _ -> setCustomView(dialogView.root)
PrefManager.setVal( setPosButton(R.string.ok) {
PrefName.DefaultUserAgent, PrefManager.setVal(PrefName.DefaultUserAgent, editText.text.toString())
editText.text.toString() }
) setNeutralButton(R.string.reset) {
dialog.dismiss()
}.setNeutralButton(getString(R.string.reset)) { dialog, _ ->
PrefManager.removeVal(PrefName.DefaultUserAgent) PrefManager.removeVal(PrefName.DefaultUserAgent)
editText.setText("") editText.setText("")
dialog.dismiss() }
}.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> setNegButton(R.string.cancel)
dialog.dismiss() }.show()
}.create()
alertDialog.show()
alertDialog.window?.setDimAmount(0.8f)
} }
), ),
Settings( Settings(

View file

@ -25,6 +25,7 @@ import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.statusBarHeight import ani.dantotsu.statusBarHeight
import ani.dantotsu.themes.ThemeManager import ani.dantotsu.themes.ThemeManager
import ani.dantotsu.util.customAlertDialog
import java.util.Locale import java.util.Locale
class SettingsNotificationActivity : AppCompatActivity() { class SettingsNotificationActivity : AppCompatActivity() {
@ -77,26 +78,16 @@ class SettingsNotificationActivity : AppCompatActivity() {
desc = getString(R.string.subscriptions_info), desc = getString(R.string.subscriptions_info),
icon = R.drawable.ic_round_notifications_none_24, icon = R.drawable.ic_round_notifications_none_24,
onClick = { onClick = {
val speedDialog = AlertDialog.Builder(context, R.style.MyPopup) context.customAlertDialog().apply {
.setTitle(R.string.subscriptions_checking_time) setTitle(R.string.subscriptions_checking_time)
val dialog = singleChoiceItems(timeNames, curTime) { i ->
speedDialog.setSingleChoiceItems(timeNames, curTime) { dialog, i ->
curTime = i curTime = i
it.settingsTitle.text = it.settingsTitle.text = getString(R.string.subscriptions_checking_time_s, timeNames[i])
getString( PrefManager.setVal(PrefName.SubscriptionNotificationInterval, curTime)
R.string.subscriptions_checking_time_s, TaskScheduler.create(context, PrefManager.getVal(PrefName.UseAlarmManager)).scheduleAllTasks(context)
timeNames[i] }
) show()
PrefManager.setVal( }
PrefName.SubscriptionNotificationInterval,
curTime
)
dialog.dismiss()
TaskScheduler.create(
context, PrefManager.getVal(PrefName.UseAlarmManager)
).scheduleAllTasks(context)
}.show()
dialog.window?.setDimAmount(0.8f)
}, },
onLongClick = { onLongClick = {
TaskScheduler.create( TaskScheduler.create(

View file

@ -39,9 +39,9 @@ class UserInterfaceSettingsActivity : AppCompatActivity() {
binding.uiSettingsHomeLayout.setOnClickListener { binding.uiSettingsHomeLayout.setOnClickListener {
val set = PrefManager.getVal<List<Boolean>>(PrefName.HomeLayout).toMutableList() val set = PrefManager.getVal<List<Boolean>>(PrefName.HomeLayout).toMutableList()
val views = resources.getStringArray(R.array.home_layouts) val views = resources.getStringArray(R.array.home_layouts)
customAlertDialog() customAlertDialog().apply {
.setTitle(getString(R.string.home_layout_show)) setTitle(getString(R.string.home_layout_show))
.multiChoiceItems( multiChoiceItems(
items = views, items = views,
checkedItems = PrefManager.getVal<List<Boolean>>(PrefName.HomeLayout).toBooleanArray() checkedItems = PrefManager.getVal<List<Boolean>>(PrefName.HomeLayout).toBooleanArray()
) { selectedItems -> ) { selectedItems ->
@ -49,11 +49,13 @@ class UserInterfaceSettingsActivity : AppCompatActivity() {
set[i] = selectedItems[i] set[i] = selectedItems[i]
} }
} }
.setPosButton("Done") { setPosButton(R.string.ok) {
PrefManager.setVal(PrefName.HomeLayout, set) PrefManager.setVal(PrefName.HomeLayout, set)
restartApp() restartApp()
} }
.show() show()
}
} }
binding.uiSettingsSmallView.isChecked = PrefManager.getVal(PrefName.SmallView) binding.uiSettingsSmallView.isChecked = PrefManager.getVal(PrefName.SmallView)

View file

@ -22,6 +22,7 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
CheckUpdate(Pref(Location.General, Boolean::class, true)), CheckUpdate(Pref(Location.General, Boolean::class, true)),
VerboseLogging(Pref(Location.General, Boolean::class, false)), VerboseLogging(Pref(Location.General, Boolean::class, false)),
DohProvider(Pref(Location.General, Int::class, 0)), DohProvider(Pref(Location.General, Int::class, 0)),
HidePrivate(Pref(Location.General, Boolean::class, false)),
DefaultUserAgent( DefaultUserAgent(
Pref( Pref(
Location.General, Location.General,

View file

@ -120,12 +120,11 @@ class ActivityMarkdownCreator : AppCompatActivity() {
toast(getString(R.string.cannot_be_empty)) toast(getString(R.string.cannot_be_empty))
return@setOnClickListener return@setOnClickListener
} }
AlertDialog.Builder(this, R.style.MyPopup).apply { customAlertDialog().apply {
setTitle(R.string.warning) setTitle(R.string.warning)
setMessage(R.string.post_to_anilist_warning) setMessage(R.string.post_to_anilist_warning)
setPositiveButton(R.string.ok) { _, _ -> setPosButton(R.string.ok) {
launchIO { launchIO {
val isEdit = editId != -1 val isEdit = editId != -1
val success = when (type) { val success = when (type) {
"activity" -> if (isEdit) { "activity" -> if (isEdit) {
@ -139,7 +138,6 @@ class ActivityMarkdownCreator : AppCompatActivity() {
} else { } else {
Anilist.mutation.postReply(parentId, text) Anilist.mutation.postReply(parentId, text)
} }
"message" -> if (isEdit) { "message" -> if (isEdit) {
Anilist.mutation.postMessage(userId, text, editId) Anilist.mutation.postMessage(userId, text, editId)
} else { } else {
@ -152,11 +150,12 @@ class ActivityMarkdownCreator : AppCompatActivity() {
finish() finish()
} }
} }
setNeutralButton(R.string.open_rules) { _, _ -> setNeutralButton(R.string.open_rules) {
openLinkInBrowser("https://anilist.co/forum/thread/14") openLinkInBrowser("https://anilist.co/forum/thread/14")
} }
setNegativeButton(R.string.cancel, null) setNegButton(R.string.cancel)
}.show() show()
}
} }
binding.previewCheckbox.setOnClickListener { binding.previewCheckbox.setOnClickListener {

View file

@ -21,8 +21,23 @@ class AlertDialogBuilder(private val context: Context) {
private var selectedItemIndex: Int = -1 private var selectedItemIndex: Int = -1
private var onItemSelected: ((Int) -> Unit)? = null private var onItemSelected: ((Int) -> Unit)? = null
private var customView: View? = null private var customView: View? = null
private var onShow: (() -> Unit)? = null
private var attach: ((dialog: AlertDialog) -> Unit)? = null private var attach: ((dialog: AlertDialog) -> Unit)? = null
private var onDismiss: (() -> Unit)? = null private var onDismiss: (() -> Unit)? = null
private var onCancel: (() -> Unit)? = null
private var cancelable: Boolean = true
fun setCancelable(cancelable: Boolean): AlertDialogBuilder {
this.cancelable = cancelable
return this
}
fun setOnShowListener(onShow: () -> Unit): AlertDialogBuilder {
this.onShow = onShow
return this
}
fun setOnCancelListener(onCancel: () -> Unit): AlertDialogBuilder {
this.onCancel = onCancel
return this
}
fun setTitle(title: String?): AlertDialogBuilder { fun setTitle(title: String?): AlertDialogBuilder {
this.title = title this.title = title
@ -48,6 +63,10 @@ class AlertDialogBuilder(private val context: Context) {
this.customView = view this.customView = view
return this return this
} }
fun setCustomView(layoutResId: Int): AlertDialogBuilder {
this.customView = View.inflate(context, layoutResId, null)
return this
}
fun setPosButton(title: String?, onClick: (() -> Unit)? = null): AlertDialogBuilder { fun setPosButton(title: String?, onClick: (() -> Unit)? = null): AlertDialogBuilder {
this.posButtonTitle = title this.posButtonTitle = title
@ -118,9 +137,10 @@ class AlertDialogBuilder(private val context: Context) {
if (customView != null) builder.setView(customView) if (customView != null) builder.setView(customView)
if (items != null) { if (items != null) {
if (onItemSelected != null) { if (onItemSelected != null) {
builder.setSingleChoiceItems(items, selectedItemIndex) { _, which -> builder.setSingleChoiceItems(items, selectedItemIndex) { dialog, which ->
selectedItemIndex = which selectedItemIndex = which
onItemSelected?.invoke(which) onItemSelected?.invoke(which)
dialog.dismiss()
} }
} else if (checkedItems != null && onItemsSelected != null) { } else if (checkedItems != null && onItemsSelected != null) {
builder.setMultiChoiceItems(items, checkedItems) { _, which, isChecked -> builder.setMultiChoiceItems(items, checkedItems) { _, which, isChecked ->
@ -147,12 +167,20 @@ class AlertDialogBuilder(private val context: Context) {
dialog.dismiss() dialog.dismiss()
} }
} }
builder.setCancelable(false) if (onCancel != null) {
builder.setOnCancelListener {
onCancel?.invoke()
}
}
builder.setCancelable(cancelable)
val dialog = builder.create() val dialog = builder.create()
attach?.invoke(dialog) attach?.invoke(dialog)
dialog.setOnDismissListener { dialog.setOnDismissListener {
onDismiss?.invoke() onDismiss?.invoke()
} }
dialog.setOnShowListener {
onShow?.invoke()
}
dialog.window?.setDimAmount(0.8f) dialog.window?.setDimAmount(0.8f)
dialog.show() dialog.show()
} }

View file

@ -71,20 +71,17 @@ class StoragePermissions {
complete(true) complete(true)
return return
} }
val builder = AlertDialog.Builder(this, R.style.MyPopup) customAlertDialog().apply {
builder.setTitle(getString(R.string.dir_access)) setTitle(getString(R.string.dir_access))
builder.setMessage(getString(R.string.dir_access_msg)) setMessage(getString(R.string.dir_access_msg))
builder.setPositiveButton(getString(R.string.ok)) { dialog, _ -> setPosButton(getString(R.string.ok)) {
launcher.registerForCallback(complete) launcher.registerForCallback(complete)
launcher.launch() launcher.launch()
dialog.dismiss()
} }
builder.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> setNegButton(getString(R.string.cancel)) {
dialog.dismiss()
complete(false) complete(false)
} }
val dialog = builder.show() }.show()
dialog.window?.setDimAmount(0.8f)
} }
private fun pathToUri(path: String): Uri { private fun pathToUri(path: String): Uri {

View file

@ -948,6 +948,8 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc
<string name="use_unique_theme_for_each_item_desc">Use color from media\'s banner</string> <string name="use_unique_theme_for_each_item_desc">Use color from media\'s banner</string>
<string name="use_custom_theme_desc">Use your own color for the theme</string> <string name="use_custom_theme_desc">Use your own color for the theme</string>
<string name="color_picker_desc">Choose a color</string> <string name="color_picker_desc">Choose a color</string>
<string name="hide_private">Hide private Media from home screen</string>
<string name="hide_private_desc">Long click "Continue Watching" to access</string>
<string name="torrent_addon">Torrent Add-on</string> <string name="torrent_addon">Torrent Add-on</string>
<string name="enable_torrent">Enable Torrent</string> <string name="enable_torrent">Enable Torrent</string>
<string name="anime_downloader_addon">Anime Downloader Add-on</string> <string name="anime_downloader_addon">Anime Downloader Add-on</string>