diff --git a/app/src/main/java/ani/dantotsu/settings/Settings.kt b/app/src/main/java/ani/dantotsu/settings/Settings.kt index 742650ff..86b8c6f0 100644 --- a/app/src/main/java/ani/dantotsu/settings/Settings.kt +++ b/app/src/main/java/ani/dantotsu/settings/Settings.kt @@ -1,10 +1,18 @@ package ani.dantotsu.settings -import android.app.Activity +import ani.dantotsu.databinding.ItemSettingsBinding +import ani.dantotsu.databinding.ItemSettingsSwitchBinding +import java.lang.reflect.Array data class Settings( + val type: Int, val name : String, - val icon : Int, val desc: String, - val activity: Class -) + val icon : Int, + val onClick: ((ItemSettingsBinding) -> Unit)? = null, + val onLongClick: (() -> Unit)? = null, + var isChecked : Boolean = false, + val switch: ((isChecked:Boolean , view: ItemSettingsSwitchBinding ) -> Unit)? = null, + val isVisible: Boolean = true, + val isActivity: Boolean = false +) \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsAboutActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsAboutActivity.kt index a99933d6..2a3617fa 100644 --- a/app/src/main/java/ani/dantotsu/settings/SettingsAboutActivity.kt +++ b/app/src/main/java/ani/dantotsu/settings/SettingsAboutActivity.kt @@ -2,28 +2,22 @@ package ani.dantotsu.settings import android.content.Intent import android.os.Bundle -import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.core.view.updateLayoutParams -import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.LinearLayoutManager import ani.dantotsu.BuildConfig import ani.dantotsu.R import ani.dantotsu.databinding.ActivitySettingsAboutBinding import ani.dantotsu.initActivity import ani.dantotsu.navBarHeight -import ani.dantotsu.others.AppUpdater import ani.dantotsu.others.CustomBottomDialog import ani.dantotsu.restartApp import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefName -import ani.dantotsu.snackString import ani.dantotsu.statusBarHeight import ani.dantotsu.themes.ThemeManager -import ani.dantotsu.util.Logger -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch class SettingsAboutActivity : AppCompatActivity() { private lateinit var binding: ActivitySettingsAboutBinding @@ -43,84 +37,91 @@ class SettingsAboutActivity : AppCompatActivity() { } aboutSettingsBack.setOnClickListener { onBackPressedDispatcher.onBackPressed() } - settingsDev.setOnClickListener { - DevelopersDialogFragment().show(supportFragmentManager, "dialog") - } - settingsForks.setOnClickListener { - ForksDialogFragment().show(supportFragmentManager, "dialog") - } - settingsDisclaimer.setOnClickListener { - val text = TextView(context) - text.setText(R.string.full_disclaimer) - - CustomBottomDialog.newInstance().apply { - setTitleText(context.getString(R.string.disclaimer)) - addView(text) - setNegativeButton(context.getString(R.string.close)) { - dismiss() - } - show(supportFragmentManager, "dialog") - } - } - - settingsFAQ.setOnClickListener { - startActivity(Intent(context, FAQActivity::class.java)) - } - - if (!BuildConfig.FLAVOR.contains("fdroid")) { - - settingsCheckUpdate.apply { - isChecked = PrefManager.getVal(PrefName.CheckUpdate) - - setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.CheckUpdate, isChecked) - if (!isChecked) { - snackString(getString(R.string.long_click_to_check_update)) + settingsRecyclerView.adapter = SettingsAdapter( + arrayListOf( + Settings( + type = 1, + name = getString(R.string.faq), + desc = getString(R.string.faq), + icon = R.drawable.ic_round_help_24, + onClick = { + startActivity(Intent(context, FAQActivity::class.java)) + }, + isActivity = true + ), + Settings( + type = 2, + name = getString(R.string.check_app_updates), + desc = getString(R.string.check_app_updates), + icon = R.drawable.ic_round_new_releases_24, + isChecked = PrefManager.getVal(PrefName.CheckUpdate), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.CheckUpdate, isChecked) + }, + isVisible = !BuildConfig.FLAVOR.contains("fdroid") + ), + Settings( + type = 2, + name = getString(R.string.share_username_in_crash_reports), + desc = getString(R.string.share_username_in_crash_reports), + icon = R.drawable.ic_round_search_24, + isChecked = PrefManager.getVal(PrefName.SharedUserID), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.SharedUserID, isChecked) + }, + isVisible = !BuildConfig.FLAVOR.contains("fdroid") + ), + Settings( + type = 2, + name = getString(R.string.log_to_file), + desc = getString(R.string.logging_warning), + icon = R.drawable.ic_round_edit_note_24, + isChecked = PrefManager.getVal(PrefName.LogToFile), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.LogToFile, isChecked) + restartApp(binding.root) + }, + ), + Settings( + type = 1, + name = getString(R.string.devs), + desc= getString(R.string.devs), + icon = R.drawable.ic_round_accessible_forward_24, + onClick = { + DevelopersDialogFragment().show(supportFragmentManager, "dialog") } - } - - setOnLongClickListener { - lifecycleScope.launch(Dispatchers.IO) { - AppUpdater.check(context, true) + ), + Settings( + type = 1, + name = getString(R.string.forks), + desc = getString(R.string.forks), + icon = R.drawable.ic_round_restaurant_24, + onClick = { + ForksDialogFragment().show(supportFragmentManager, "dialog") } - true - } + ), + Settings( + type = 1, + name = getString(R.string.disclaimer), + desc = getString(R.string.disclaimer), + icon = R.drawable.ic_round_info_24, + onClick = { + val text = TextView(context) + text.setText(R.string.full_disclaimer) - } - - settingsShareUsername.apply { - isChecked = PrefManager.getVal(PrefName.SharedUserID) - settingsShareUsername.setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.SharedUserID, isChecked) - } - } - - } else { - settingsCheckUpdate.apply{ - visibility = View.GONE - isEnabled = false - isChecked = false - } - settingsShareUsername.apply{ - visibility = View.GONE - isEnabled = false - isChecked = false - } - - } - - settingsLogToFile.apply { - isChecked = PrefManager.getVal(PrefName.LogToFile) - - setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.LogToFile, isChecked) - restartApp(binding.root) - } - } - - settingsShareLog.setOnClickListener { - Logger.shareLog(context) - } + CustomBottomDialog.newInstance().apply { + setTitleText(context.getString(R.string.disclaimer)) + addView(text) + setNegativeButton(context.getString(R.string.close)) { + dismiss() + } + show(supportFragmentManager, "dialog") + } + } + ), + ) + ) + binding.settingsRecyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) } } } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsActivity.kt index b7776ad6..7185b04e 100644 --- a/app/src/main/java/ani/dantotsu/settings/SettingsActivity.kt +++ b/app/src/main/java/ani/dantotsu/settings/SettingsActivity.kt @@ -1,5 +1,6 @@ package ani.dantotsu.settings +import android.content.Intent import android.graphics.drawable.Animatable import android.os.Build.BRAND import android.os.Build.DEVICE @@ -75,61 +76,93 @@ class SettingsActivity : AppCompatActivity() { onBackPressedDispatcher.onBackPressed() } - - val settings = arrayListOf( - Settings( - getString(R.string.accounts), - R.drawable.ic_round_person_24, - getString(R.string.accounts_desc), - SettingsAccountActivity::class.java - ), - Settings( - getString(R.string.theme), - R.drawable.ic_palette, - getString(R.string.theme_desc), - SettingsThemeActivity::class.java - ), - Settings( - getString(R.string.common), - R.drawable.ic_lightbulb_24, - getString(R.string.common_desc), - SettingsCommonActivity::class.java - ), - Settings( - getString(R.string.anime), - R.drawable.ic_round_movie_filter_24, - getString(R.string.anime_desc), - SettingsAnimeActivity::class.java - ), - Settings( - getString(R.string.manga), - R.drawable.ic_round_import_contacts_24, - getString(R.string.manga_desc), - SettingsMangaActivity::class.java - ), - Settings( - getString(R.string.extensions), - R.drawable.ic_extension, - getString(R.string.extensions_desc), - SettingsExtensionsActivity::class.java - ), - Settings( - getString(R.string.notifications), - R.drawable.ic_round_notifications_none_24, - getString(R.string.notifications_desc), - SettingsNotificationActivity::class.java - ), - Settings( - getString(R.string.about), - R.drawable.ic_round_info_24, - getString(R.string.about_desc), - SettingsAboutActivity::class.java - ), + binding.settingsRecyclerView.adapter = SettingsAdapter( + arrayListOf( + Settings( + type = 1, + name = getString(R.string.accounts), + desc = getString(R.string.accounts_desc), + icon = R.drawable.ic_round_person_24, + onClick = { + startActivity(Intent(context, SettingsAccountActivity::class.java)) + }, + isActivity = true + ), + Settings( + type = 1, + name = getString(R.string.theme), + desc = getString(R.string.theme_desc), + icon = R.drawable.ic_palette, + onClick = { + startActivity(Intent(context, SettingsThemeActivity::class.java)) + }, + isActivity = true + ), + Settings( + type = 1, + name = getString(R.string.common), + desc = getString(R.string.common_desc), + icon = R.drawable.ic_lightbulb_24, + onClick = { + startActivity(Intent(context, SettingsCommonActivity::class.java)) + }, + isActivity = true + ), + Settings( + type = 1, + name = getString(R.string.anime), + desc = getString(R.string.anime_desc), + icon = R.drawable.ic_round_movie_filter_24, + onClick = { + startActivity(Intent(context, SettingsAnimeActivity::class.java)) + }, + isActivity = true + ), + Settings( + type = 1, + name = getString(R.string.manga), + desc = getString(R.string.manga_desc), + icon = R.drawable.ic_round_import_contacts_24, + onClick = { + startActivity(Intent(context, SettingsMangaActivity::class.java)) + }, + isActivity = true + ), + Settings( + type = 1, + name = getString(R.string.extensions), + desc = getString(R.string.extensions_desc), + icon = R.drawable.ic_extension, + onClick = { + startActivity(Intent(context, SettingsExtensionsActivity::class.java)) + }, + isActivity = true + ), + Settings( + type = 1, + name = getString(R.string.notifications), + desc = getString(R.string.notifications_desc), + icon = R.drawable.ic_round_notifications_none_24, + onClick = { + startActivity(Intent(context, SettingsNotificationActivity::class.java)) + }, + isActivity = true + ), + Settings( + type = 1, + name = getString(R.string.about), + desc = getString(R.string.about_desc), + icon = R.drawable.ic_round_info_24, + onClick = { + startActivity(Intent(context, SettingsAboutActivity::class.java)) + }, + isActivity = true + ) + ) ) settingsRecyclerView.apply { layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) - adapter = SettingsAdapter(settings) setHasFixedSize(true) } diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsAdapter.kt b/app/src/main/java/ani/dantotsu/settings/SettingsAdapter.kt index bf665740..add55912 100644 --- a/app/src/main/java/ani/dantotsu/settings/SettingsAdapter.kt +++ b/app/src/main/java/ani/dantotsu/settings/SettingsAdapter.kt @@ -1,44 +1,97 @@ package ani.dantotsu.settings -import android.content.Intent import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import ani.dantotsu.databinding.ItemSettingsBinding +import ani.dantotsu.databinding.ItemSettingsSwitchBinding import ani.dantotsu.setAnimation -class SettingsAdapter(private val settings: ArrayList) : RecyclerView.Adapter(){ +class SettingsAdapter(private val settings: ArrayList) : + RecyclerView.Adapter() { inner class SettingsViewHolder(val binding: ItemSettingsBinding) : - RecyclerView.ViewHolder(binding.root) { - init { - itemView.setOnClickListener { - ContextCompat.startActivity( - binding.root.context, Intent(binding.root.context, settings[bindingAdapterPosition].activity), - null + RecyclerView.ViewHolder(binding.root) {} + + inner class SettingsSwitchViewHolder(val binding: ItemSettingsSwitchBinding) : + RecyclerView.ViewHolder(binding.root) {} + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return when (viewType) { + 1 -> SettingsViewHolder( + ItemSettingsBinding.inflate( + LayoutInflater.from(parent.context), parent, false ) + ) + + 2 -> SettingsSwitchViewHolder( + ItemSettingsSwitchBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + ) + + else -> SettingsViewHolder( + ItemSettingsBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + ) + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val settings = settings[position] + when (settings.type) { + 1 -> { + val b = (holder as SettingsViewHolder).binding + setAnimation(b.root.context, b.root) + + b.settingsTitle.text = settings.name + b.settingsDesc.text = settings.desc + b.settingsIcon.setImageDrawable( + ContextCompat.getDrawable( + b.root.context, settings.icon + ) + ) + b.settingsLayout.setOnClickListener { + settings.onClick?.invoke(b) + } + b.settingsLayout.setOnLongClickListener { + settings.onLongClick?.invoke() + true + } + b.settingsLayout.visibility = if (settings.isVisible) View.VISIBLE else View.GONE + b.settingsIconRight.visibility = + if (settings.isActivity) View.VISIBLE else View.GONE + } + + 2 -> { + val b = (holder as SettingsSwitchViewHolder).binding + setAnimation(b.root.context, b.root) + + b.settingsButton.text = settings.name + b.settingsDesc.text = settings.desc + b.settingsIcon.setImageDrawable( + ContextCompat.getDrawable( + b.root.context, settings.icon + ) + ) + b.settingsButton.isChecked = settings.isChecked + b.settingsButton.setOnCheckedChangeListener { _, isChecked -> + settings.switch?.invoke(isChecked, b) + } + b.settingsLayout.setOnLongClickListener() { + settings.onLongClick?.invoke() + true + } + b.settingsLayout.visibility = if (settings.isVisible) View.VISIBLE else View.GONE } } } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SettingsViewHolder { - return SettingsViewHolder( - ItemSettingsBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ) - ) - } - - override fun onBindViewHolder(holder: SettingsViewHolder, position: Int) { - val b = holder.binding - setAnimation(b.root.context, b.root) - val settings = settings[position] - b.settingsTitle.text = settings.name - b.settingsDesc.text = settings.desc - b.settingsIcon.setImageDrawable(ContextCompat.getDrawable(b.root.context, settings.icon)) - } - override fun getItemCount(): Int = settings.size + + override fun getItemViewType(position: Int): Int { + return settings[position].type + } } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsAnimeActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsAnimeActivity.kt index 9ea39044..7e853ed5 100644 --- a/app/src/main/java/ani/dantotsu/settings/SettingsAnimeActivity.kt +++ b/app/src/main/java/ani/dantotsu/settings/SettingsAnimeActivity.kt @@ -7,9 +7,9 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.core.view.updateLayoutParams +import androidx.recyclerview.widget.LinearLayoutManager import ani.dantotsu.R import ani.dantotsu.databinding.ActivitySettingsAnimeBinding -import ani.dantotsu.databinding.ActivitySettingsMangaBinding import ani.dantotsu.download.DownloadsManager import ani.dantotsu.initActivity import ani.dantotsu.media.MediaType @@ -37,41 +37,77 @@ class SettingsAnimeActivity: AppCompatActivity(){ topMargin = statusBarHeight bottomMargin = navBarHeight } - settingsPlayer.setOnClickListener { - startActivity(Intent(context, PlayerSettingsActivity::class.java)) - } - animeSettingsBack.setOnClickListener { - onBackPressedDispatcher.onBackPressed() - } - purgeAnimeDownloads.setOnClickListener { - val dialog = AlertDialog.Builder(context, R.style.MyPopup) - .setTitle(R.string.purge_anime_downloads) - .setMessage(getString(R.string.purge_confirm, getString(R.string.anime))) - .setPositiveButton(R.string.yes) { dialog, _ -> - val downloadsManager = Injekt.get() - downloadsManager.purgeDownloads(MediaType.ANIME) - dialog.dismiss() - }.setNegativeButton(R.string.no) { dialog, _ -> - dialog.dismiss() - }.create() - dialog.window?.setDimAmount(0.8f) - dialog.show() - } + animeSettingsBack.setOnClickListener { onBackPressedDispatcher.onBackPressed() } - settingsPreferDub.isChecked = PrefManager.getVal(PrefName.SettingsPreferDub) - settingsPreferDub.setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.SettingsPreferDub, isChecked) - } + settingsRecyclerView.adapter = SettingsAdapter( + arrayListOf( + Settings( + type = 1, + name = getString(R.string.player_settings), + desc = getString(R.string.player_settings), + icon = R.drawable.ic_round_video_settings_24, + onClick = { + startActivity(Intent(context, PlayerSettingsActivity::class.java)) + }, + isActivity = true + ), + Settings( + type = 1, + name = getString(R.string.purge_anime_downloads), + desc = getString(R.string.purge_anime_downloads), + icon = R.drawable.ic_round_delete_24, + onClick = { + val dialog = AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.purge_anime_downloads) + .setMessage(getString(R.string.purge_confirm, getString(R.string.anime))) + .setPositiveButton(R.string.yes) { dialog, _ -> + val downloadsManager = Injekt.get() + downloadsManager.purgeDownloads(MediaType.ANIME) + dialog.dismiss() + }.setNegativeButton(R.string.no) { dialog, _ -> + dialog.dismiss() + }.create() + dialog.window?.setDimAmount(0.8f) + dialog.show() + } - - settingsShowYt.isChecked = PrefManager.getVal(PrefName.ShowYtButton) - settingsShowYt.setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.ShowYtButton, isChecked) - } - settingsIncludeAnimeList.isChecked = PrefManager.getVal(PrefName.IncludeAnimeList) - settingsIncludeAnimeList.setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.IncludeAnimeList, isChecked) - restartApp(binding.root) + ), + Settings( + type = 2, + name = getString(R.string.prefer_dub), + desc = getString(R.string.prefer_dub), + icon = R.drawable.ic_round_audiotrack_24, + isChecked = PrefManager.getVal(PrefName.SettingsPreferDub), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.SettingsPreferDub, isChecked) + } + ), + Settings( + type = 2, + name = getString(R.string.show_yt), + desc = getString(R.string.show_yt), + icon = R.drawable.ic_round_play_circle_24, + isChecked = PrefManager.getVal(PrefName.ShowYtButton), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.ShowYtButton, isChecked) + } + ), + Settings( + type = 2, + name = getString(R.string.include_list), + desc = getString(R.string.include_list), + icon = R.drawable.view_list_24, + isChecked = PrefManager.getVal(PrefName.IncludeAnimeList), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.IncludeAnimeList, isChecked) + restartApp(binding.root) + } + ), + ) + ) + settingsRecyclerView.apply { + layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + setHasFixedSize(true) } var previousEp: View = when (PrefManager.getVal(PrefName.AnimeDefaultView)) { @@ -99,6 +135,7 @@ class SettingsAnimeActivity: AppCompatActivity(){ settingsEpCompact.setOnClickListener { uiEp(2, it) } + } } } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsCommonActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsCommonActivity.kt index ea24924a..5e1fc7ae 100644 --- a/app/src/main/java/ani/dantotsu/settings/SettingsCommonActivity.kt +++ b/app/src/main/java/ani/dantotsu/settings/SettingsCommonActivity.kt @@ -14,7 +14,9 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.core.view.updateLayoutParams import androidx.documentfile.provider.DocumentFile +import androidx.recyclerview.widget.LinearLayoutManager import ani.dantotsu.R +import ani.dantotsu.connections.anilist.Anilist import ani.dantotsu.databinding.ActivitySettingsCommonBinding import ani.dantotsu.download.DownloadsManager import ani.dantotsu.initActivity @@ -32,6 +34,7 @@ import ani.dantotsu.toast import ani.dantotsu.util.LauncherWrapper import ani.dantotsu.util.StoragePermissions import com.google.android.material.textfield.TextInputEditText +import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -41,6 +44,7 @@ import uy.kohesive.injekt.api.get class SettingsCommonActivity: AppCompatActivity(){ private lateinit var binding: ActivitySettingsCommonBinding private lateinit var launcher: LauncherWrapper + @OptIn(DelicateCoroutinesApi::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ThemeManager(this).applyTheme() @@ -88,10 +92,7 @@ class SettingsCommonActivity: AppCompatActivity(){ } val contract = ActivityResultContracts.OpenDocumentTree() launcher = LauncherWrapper(this, contract) - val managers = arrayOf("Default", "1DM", "ADM") - val downloadManagerDialog = - AlertDialog.Builder(this, R.style.MyPopup).setTitle(R.string.download_manager) - var downloadManager: Int = PrefManager.getVal(PrefName.DownloadManager) + binding.apply { settingsCommonLayout.updateLayoutParams { @@ -101,66 +102,6 @@ class SettingsCommonActivity: AppCompatActivity(){ commonSettingsBack.setOnClickListener { onBackPressedDispatcher.onBackPressed() } - settingsDownloadManager.setOnClickListener { - val dialog = downloadManagerDialog.setSingleChoiceItems( - managers, downloadManager - ) { dialog, count -> - downloadManager = count - PrefManager.setVal(PrefName.DownloadManager, downloadManager) - dialog.dismiss() - }.show() - dialog.window?.setDimAmount(0.8f) - } - - importExportSettings.setOnClickListener { - StoragePermissions.downloadsPermission(context) - val selectedArray = mutableListOf(false) - val filteredLocations = Location.entries.filter { it.exportable } - selectedArray.addAll(List(filteredLocations.size - 1) { false }) - val dialog = AlertDialog.Builder(context, R.style.MyPopup) - .setTitle(R.string.backup_restore).setMultiChoiceItems( - filteredLocations.map { it.name }.toTypedArray(), - selectedArray.toBooleanArray() - ) { _, which, isChecked -> - selectedArray[which] = isChecked - }.setPositiveButton(R.string.button_restore) { dialog, _ -> - openDocumentLauncher.launch(arrayOf("*/*")) - dialog.dismiss() - }.setNegativeButton(R.string.button_backup) { dialog, _ -> - if (!selectedArray.contains(true)) { - toast(R.string.no_location_selected) - return@setNegativeButton - } - dialog.dismiss() - val selected = - filteredLocations.filterIndexed { index, _ -> selectedArray[index] } - if (selected.contains(Location.Protected)) { - passwordAlertDialog(true) { password -> - if (password != null) { - savePrefsToDownloads( - "DantotsuSettings", - PrefManager.exportAllPrefs(selected), - context, - password - ) - } else { - toast(R.string.password_cannot_be_empty) - } - } - } else { - savePrefsToDownloads( - "DantotsuSettings", - PrefManager.exportAllPrefs(selected), - context, - null - ) - } - }.setNeutralButton(R.string.cancel) { dialog, _ -> - dialog.dismiss() - }.create() - dialog.window?.setDimAmount(0.8f) - dialog.show() - } val exDns = listOf( "None", "Cloudflare", @@ -189,60 +130,181 @@ class SettingsCommonActivity: AppCompatActivity(){ restartApp(binding.root) } - settingsContinueMedia.isChecked = PrefManager.getVal(PrefName.ContinueMedia) - settingsContinueMedia.setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.ContinueMedia, isChecked) - } - - settingsSearchSources.isChecked = PrefManager.getVal(PrefName.SearchSources) - settingsSearchSources.setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.SearchSources, isChecked) - } - - settingsRecentlyListOnly.isChecked = PrefManager.getVal(PrefName.RecentlyListOnly) - settingsRecentlyListOnly.setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.RecentlyListOnly, isChecked) - } - settingsAdultAnimeOnly.isChecked = PrefManager.getVal(PrefName.AdultOnly) - settingsAdultAnimeOnly.setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.AdultOnly, isChecked) - restartApp(binding.root) - } - - settingsDownloadLocation.setOnClickListener { - val dialog = AlertDialog.Builder(context, R.style.MyPopup) - .setTitle(R.string.change_download_location) - .setMessage(R.string.download_location_msg) - .setPositiveButton(R.string.ok) { dialog, _ -> - val oldUri = PrefManager.getVal(PrefName.DownloadsDir) - launcher.registerForCallback { success -> - if (success) { - toast(getString(R.string.please_wait)) - val newUri = PrefManager.getVal(PrefName.DownloadsDir) - GlobalScope.launch(Dispatchers.IO) { - Injekt.get().moveDownloadsDir( - context, Uri.parse(oldUri), Uri.parse(newUri) - ) { finished, message -> - if (finished) { - toast(getString(R.string.success)) + settingsRecyclerView.adapter = SettingsAdapter( + arrayListOf( + Settings( + type = 1, + name = getString(R.string.ui_settings), + desc = getString(R.string.ui_settings), + icon = R.drawable.ic_round_auto_awesome_24, + onClick = { + startActivity(Intent(context, UserInterfaceSettingsActivity::class.java)) + }, + isActivity = true + ), + Settings( + type = 1, + name = getString(R.string.download_manager_select), + desc = getString(R.string.download_manager_select), + icon = R.drawable.ic_download_24, + onClick = { + val managers = arrayOf("Default", "1DM", "ADM") + val downloadManagerDialog = + AlertDialog.Builder(context, R.style.MyPopup).setTitle(R.string.download_manager) + var downloadManager: Int = PrefManager.getVal(PrefName.DownloadManager) + val dialog = downloadManagerDialog.setSingleChoiceItems( + managers, downloadManager + ) { dialog, count -> + downloadManager = count + PrefManager.setVal(PrefName.DownloadManager, downloadManager) + dialog.dismiss() + }.show() + dialog.window?.setDimAmount(0.8f) + } + ), + Settings( + type = 1, + name = getString(R.string.backup_restore), + desc = getString(R.string.backup_restore), + icon = R.drawable.backup_restore, + onClick = { + StoragePermissions.downloadsPermission(context) + val selectedArray = mutableListOf(false) + val filteredLocations = Location.entries.filter { it.exportable } + selectedArray.addAll(List(filteredLocations.size - 1) { false }) + val dialog = AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.backup_restore).setMultiChoiceItems( + filteredLocations.map { it.name }.toTypedArray(), + selectedArray.toBooleanArray() + ) { _, which, isChecked -> + selectedArray[which] = isChecked + }.setPositiveButton(R.string.button_restore) { dialog, _ -> + openDocumentLauncher.launch(arrayOf("*/*")) + dialog.dismiss() + }.setNegativeButton(R.string.button_backup) { dialog, _ -> + if (!selectedArray.contains(true)) { + toast(R.string.no_location_selected) + return@setNegativeButton + } + dialog.dismiss() + val selected = + filteredLocations.filterIndexed { index, _ -> selectedArray[index] } + if (selected.contains(Location.Protected)) { + passwordAlertDialog(true) { password -> + if (password != null) { + savePrefsToDownloads( + "DantotsuSettings", + PrefManager.exportAllPrefs(selected), + context, + password + ) + } else { + toast(R.string.password_cannot_be_empty) + } + } + } else { + savePrefsToDownloads( + "DantotsuSettings", + PrefManager.exportAllPrefs(selected), + context, + null + ) + } + }.setNeutralButton(R.string.cancel) { dialog, _ -> + dialog.dismiss() + }.create() + dialog.window?.setDimAmount(0.8f) + dialog.show() + }, + ), + Settings( + type = 1, + name = getString(R.string.change_download_location), + desc = getString(R.string.change_download_location), + icon = R.drawable.ic_round_source_24, + onClick = { + val dialog = AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.change_download_location) + .setMessage(R.string.download_location_msg) + .setPositiveButton(R.string.ok) { dialog, _ -> + val oldUri = PrefManager.getVal(PrefName.DownloadsDir) + launcher.registerForCallback { success -> + if (success) { + toast(getString(R.string.please_wait)) + val newUri = PrefManager.getVal(PrefName.DownloadsDir) + GlobalScope.launch(Dispatchers.IO) { + Injekt.get().moveDownloadsDir( + context, Uri.parse(oldUri), Uri.parse(newUri) + ) { finished, message -> + if (finished) { + toast(getString(R.string.success)) + } else { + toast(message) + } + } + } } else { - toast(message) + toast(getString(R.string.error)) } } - } - } else { - toast(getString(R.string.error)) - } + launcher.launch() + dialog.dismiss() + }.setNeutralButton(R.string.cancel) { dialog, _ -> + dialog.dismiss() + }.create() + dialog.window?.setDimAmount(0.8f) + dialog.show() } - launcher.launch() - dialog.dismiss() - }.setNeutralButton(R.string.cancel) { dialog, _ -> - dialog.dismiss() - }.create() - dialog.window?.setDimAmount(0.8f) - dialog.show() - } + ), + Settings( + type = 2, + name = getString(R.string.always_continue_content), + desc = getString(R.string.always_continue_content), + icon = R.drawable.ic_round_delete_24, + isChecked = PrefManager.getVal(PrefName.ContinueMedia), + switch = {isChecked, _ -> + PrefManager.setVal(PrefName.ContinueMedia, isChecked) + } + ), + Settings( + type = 2, + name = getString(R.string.search_source_list), + desc = getString(R.string.search_source_list), + icon = R.drawable.ic_round_search_sources_24, + isChecked = PrefManager.getVal(PrefName.SearchSources), + switch = {isChecked, _ -> + PrefManager.setVal(PrefName.SearchSources, isChecked) + } + ), + Settings( + type = 2, + name = getString(R.string.recentlyListOnly), + desc = getString(R.string.recentlyListOnly), + icon = R.drawable.ic_round_new_releases_24, + isChecked = PrefManager.getVal(PrefName.RecentlyListOnly), + switch = {isChecked, _ -> + PrefManager.setVal(PrefName.RecentlyListOnly, isChecked) + } + ), + Settings( + type = 2, + name = getString(R.string.adult_only_content), + desc = getString(R.string.adult_only_content), + icon = R.drawable.ic_round_nsfw_24, + isChecked = PrefManager.getVal(PrefName.AdultOnly), + switch = {isChecked, _ -> + PrefManager.setVal(PrefName.AdultOnly, isChecked) + restartApp(binding.root) + }, + isVisible = Anilist.adult + ), + ) + ) + settingsRecyclerView.apply { + layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + setHasFixedSize(true) + } var previousStart: View = when (PrefManager.getVal(PrefName.DefaultStartUpTab)) { 0 -> uiSettingsAnime 1 -> uiSettingsHome @@ -270,13 +332,6 @@ class SettingsCommonActivity: AppCompatActivity(){ uiDefault(2, it) } - settingsUi.setOnClickListener { - startActivity( - Intent( - context, UserInterfaceSettingsActivity::class.java - ) - ) - } } } private fun passwordAlertDialog(isExporting: Boolean, callback: (CharArray?) -> Unit) { diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsExtensionsActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsExtensionsActivity.kt index b354fe98..8bb190e0 100644 --- a/app/src/main/java/ani/dantotsu/settings/SettingsExtensionsActivity.kt +++ b/app/src/main/java/ani/dantotsu/settings/SettingsExtensionsActivity.kt @@ -11,9 +11,11 @@ import android.widget.EditText import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams +import androidx.recyclerview.widget.LinearLayoutManager import ani.dantotsu.R import ani.dantotsu.copyToClipboard import ani.dantotsu.databinding.ActivitySettingsExtensionsBinding +import ani.dantotsu.databinding.DialogUserAgentBinding import ani.dantotsu.databinding.ItemRepositoryBinding import ani.dantotsu.initActivity import ani.dantotsu.media.MediaType @@ -199,48 +201,77 @@ class SettingsExtensionsActivity: AppCompatActivity() { alertDialog.show() alertDialog.window?.setDimAmount(0.8f) } + } - settingsForceLegacyInstall.isChecked = - extensionInstaller.get() == BasePreferences.ExtensionInstaller.LEGACY - settingsForceLegacyInstall.setOnCheckedChangeListener { _, isChecked -> - if (isChecked) { - extensionInstaller.set(BasePreferences.ExtensionInstaller.LEGACY) - } else { - extensionInstaller.set(BasePreferences.ExtensionInstaller.PACKAGEINSTALLER) - } - } + binding.settingsRecyclerView.adapter = SettingsAdapter( + arrayListOf( + Settings( + type = 1, + name = getString(R.string.user_agent), + desc = getString(R.string.NSFWExtention), + icon = R.drawable.ic_round_video_settings_24, + onClick = { + val dialogView = DialogUserAgentBinding.inflate(layoutInflater) + val editText = dialogView.userAgentTextBox + editText.setText(PrefManager.getVal(PrefName.DefaultUserAgent)) + val alertDialog = AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.user_agent).setView(dialogView.root) + .setPositiveButton(getString(R.string.ok)) { dialog, _ -> + PrefManager.setVal(PrefName.DefaultUserAgent, editText.text.toString()) + dialog.dismiss() + }.setNeutralButton(getString(R.string.reset)) { dialog, _ -> + PrefManager.removeVal(PrefName.DefaultUserAgent) + editText.setText("") + dialog.dismiss() + }.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> + dialog.dismiss() + }.create() - skipExtensionIcons.isChecked = PrefManager.getVal(PrefName.SkipExtensionIcons) - skipExtensionIcons.setOnCheckedChangeListener { _, isChecked -> - PrefManager.getVal(PrefName.SkipExtensionIcons, isChecked) - } - NSFWExtension.isChecked = PrefManager.getVal(PrefName.NSFWExtension) - NSFWExtension.setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.NSFWExtension, isChecked) + alertDialog.show() + alertDialog.window?.setDimAmount(0.8f) + } + ), + Settings( + type = 2, + name = getString(R.string.force_legacy_installer), + desc = getString(R.string.force_legacy_installer), + icon = R.drawable.ic_round_new_releases_24, + isChecked = extensionInstaller.get() == BasePreferences.ExtensionInstaller.LEGACY, + switch = { isChecked, _ -> + if (isChecked) { + extensionInstaller.set(BasePreferences.ExtensionInstaller.LEGACY) + } else { + extensionInstaller.set(BasePreferences.ExtensionInstaller.PACKAGEINSTALLER) + } + } - } + ), + Settings( + type = 2, + name = getString(R.string.skip_loading_extension_icons), + desc = getString(R.string.skip_loading_extension_icons), + icon = R.drawable.ic_round_no_icon_24, + isChecked = PrefManager.getVal(PrefName.SkipExtensionIcons), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.SkipExtensionIcons, isChecked) + } + ), + Settings( + type = 2, + name = getString(R.string.NSFWExtention), + desc = getString(R.string.NSFWExtention), + icon = R.drawable.ic_round_nsfw_24, + isChecked = PrefManager.getVal(PrefName.NSFWExtension), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.NSFWExtension, isChecked) + } - userAgent.setOnClickListener { - val dialogView = layoutInflater.inflate(R.layout.dialog_user_agent, null) - val editText = dialogView.findViewById(R.id.userAgentTextBox) - editText.setText(PrefManager.getVal(PrefName.DefaultUserAgent)) - val alertDialog = AlertDialog.Builder(context, R.style.MyPopup) - .setTitle(R.string.user_agent).setView(dialogView) - .setPositiveButton(getString(R.string.ok)) { dialog, _ -> - PrefManager.setVal(PrefName.DefaultUserAgent, editText.text.toString()) - dialog.dismiss() - }.setNeutralButton(getString(R.string.reset)) { dialog, _ -> - PrefManager.removeVal(PrefName.DefaultUserAgent) - editText.setText("") - dialog.dismiss() - }.setNegativeButton(getString(R.string.cancel)) { dialog, _ -> - dialog.dismiss() - }.create() - - alertDialog.show() - alertDialog.window?.setDimAmount(0.8f) - } + ) + ) + ) + binding.settingsRecyclerView.apply { + layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + setHasFixedSize(true) } } - } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsMangaActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsMangaActivity.kt index e42034a0..afa56eb8 100644 --- a/app/src/main/java/ani/dantotsu/settings/SettingsMangaActivity.kt +++ b/app/src/main/java/ani/dantotsu/settings/SettingsMangaActivity.kt @@ -7,6 +7,7 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.core.view.updateLayoutParams +import androidx.recyclerview.widget.LinearLayoutManager import ani.dantotsu.R import ani.dantotsu.databinding.ActivitySettingsMangaBinding import ani.dantotsu.download.DownloadsManager @@ -39,39 +40,6 @@ class SettingsMangaActivity: AppCompatActivity(){ mangaSettingsBack.setOnClickListener { onBackPressedDispatcher.onBackPressed() } - purgeMangaDownloads.setOnClickListener { - val dialog = AlertDialog.Builder(context, R.style.MyPopup) - .setTitle(R.string.purge_manga_downloads) - .setMessage(getString(R.string.purge_confirm, getString(R.string.manga))) - .setPositiveButton(R.string.yes) { dialog, _ -> - val downloadsManager = Injekt.get() - downloadsManager.purgeDownloads(MediaType.MANGA) - dialog.dismiss() - }.setNegativeButton(R.string.no) { dialog, _ -> - dialog.dismiss() - }.create() - dialog.window?.setDimAmount(0.8f) - dialog.show() - } - - purgeNovelDownloads.setOnClickListener { - val dialog = AlertDialog.Builder(context, R.style.MyPopup) - .setTitle(R.string.purge_novel_downloads) - .setMessage(getString(R.string.purge_confirm, getString(R.string.novels))) - .setPositiveButton(R.string.yes) { dialog, _ -> - val downloadsManager = Injekt.get() - downloadsManager.purgeDownloads(MediaType.NOVEL) - dialog.dismiss() - }.setNegativeButton(R.string.no) { dialog, _ -> - dialog.dismiss() - }.create() - dialog.window?.setDimAmount(0.8f) - dialog.show() - } - - settingsReader.setOnClickListener { - startActivity(Intent(context, ReaderSettingsActivity::class.java)) - } var previousChp: View = when (PrefManager.getVal(PrefName.MangaDefaultView)) { 0 -> settingsChpList @@ -94,10 +62,75 @@ class SettingsMangaActivity: AppCompatActivity(){ uiChp(1, it) } - settingsIncludeMangaList.isChecked = PrefManager.getVal(PrefName.IncludeMangaList) - settingsIncludeMangaList.setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.IncludeMangaList, isChecked) - restartApp(binding.root) + settingsRecyclerView.adapter = SettingsAdapter( + arrayListOf( + Settings( + type = 1, + name = getString(R.string.reader_settings), + desc = getString(R.string.reader_settings), + icon = R.drawable.ic_round_reader_settings, + onClick = { + startActivity(Intent(context, ReaderSettingsActivity::class.java)) + }, + isActivity = true + ), + Settings( + type = 1, + name = getString(R.string.purge_manga_downloads), + desc = getString(R.string.purge_manga_downloads), + icon = R.drawable.ic_round_delete_24, + onClick = { + val dialog = AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.purge_manga_downloads) + .setMessage(getString(R.string.purge_confirm, getString(R.string.manga))) + .setPositiveButton(R.string.yes) { dialog, _ -> + val downloadsManager = Injekt.get() + downloadsManager.purgeDownloads(MediaType.MANGA) + dialog.dismiss() + }.setNegativeButton(R.string.no) { dialog, _ -> + dialog.dismiss() + }.create() + dialog.window?.setDimAmount(0.8f) + dialog.show() + } + + ), + Settings( + type = 1, + name = getString(R.string.purge_novel_downloads), + desc = getString(R.string.purge_novel_downloads), + icon = R.drawable.ic_round_delete_24, + onClick = { + val dialog = AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.purge_novel_downloads) + .setMessage(getString(R.string.purge_confirm, getString(R.string.novels))) + .setPositiveButton(R.string.yes) { dialog, _ -> + val downloadsManager = Injekt.get() + downloadsManager.purgeDownloads(MediaType.NOVEL) + dialog.dismiss() + }.setNegativeButton(R.string.no) { dialog, _ -> + dialog.dismiss() + }.create() + dialog.window?.setDimAmount(0.8f) + dialog.show() + } + ), + Settings( + type = 2, + name = getString(R.string.include_list), + desc = getString(R.string.include_list), + icon = R.drawable.view_list_24, + isChecked = PrefManager.getVal(PrefName.IncludeMangaList), + switch = {isChecked, _ -> + PrefManager.setVal(PrefName.IncludeMangaList, isChecked) + restartApp(binding.root) + } + ), + ) + ) + settingsRecyclerView.apply { + layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + setHasFixedSize(true) } } } diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsNotificationActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsNotificationActivity.kt index eaf6909e..2d47a32e 100644 --- a/app/src/main/java/ani/dantotsu/settings/SettingsNotificationActivity.kt +++ b/app/src/main/java/ani/dantotsu/settings/SettingsNotificationActivity.kt @@ -9,20 +9,26 @@ import android.os.Bundle import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.core.view.updateLayoutParams +import androidx.recyclerview.widget.LinearLayoutManager import ani.dantotsu.R import ani.dantotsu.connections.anilist.api.NotificationType import ani.dantotsu.databinding.ActivitySettingsNotificationsBinding +import ani.dantotsu.download.DownloadsManager import ani.dantotsu.initActivity +import ani.dantotsu.media.MediaType import ani.dantotsu.navBarHeight import ani.dantotsu.notifications.TaskScheduler import ani.dantotsu.notifications.anilist.AnilistNotificationWorker import ani.dantotsu.notifications.comment.CommentNotificationWorker import ani.dantotsu.notifications.subscription.SubscriptionNotificationWorker import ani.dantotsu.openSettings +import ani.dantotsu.restartApp import ani.dantotsu.settings.saving.PrefManager import ani.dantotsu.settings.saving.PrefName import ani.dantotsu.statusBarHeight import ani.dantotsu.themes.ThemeManager +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get class SettingsNotificationActivity: AppCompatActivity(){ private lateinit var binding: ActivitySettingsNotificationsBinding @@ -49,31 +55,6 @@ class SettingsNotificationActivity: AppCompatActivity(){ notificationSettingsBack.setOnClickListener { onBackPressedDispatcher.onBackPressed() } - settingsSubscriptionsTime.text = - getString(R.string.subscriptions_checking_time_s, timeNames[curTime]) - val speedDialog = AlertDialog.Builder(context, R.style.MyPopup) - .setTitle(R.string.subscriptions_checking_time) - settingsSubscriptionsTime.setOnClickListener { - val dialog = speedDialog.setSingleChoiceItems(timeNames, curTime) { dialog, i -> - curTime = i - settingsSubscriptionsTime.text = - getString(R.string.subscriptions_checking_time_s, timeNames[i]) - PrefManager.setVal(PrefName.SubscriptionNotificationInterval, curTime) - dialog.dismiss() - TaskScheduler.create( - context, PrefManager.getVal(PrefName.UseAlarmManager) - ).scheduleAllTasks(context) - }.show() - dialog.window?.setDimAmount(0.8f) - } - - settingsSubscriptionsTime.setOnLongClickListener { - TaskScheduler.create( - context, PrefManager.getVal(PrefName.UseAlarmManager) - ).scheduleAllTasks(context) - true - } - val aTimeNames = AnilistNotificationWorker.checkIntervals.map { it.toInt() } val aItems = aTimeNames.map { val mins = it % 60 @@ -81,48 +62,6 @@ class SettingsNotificationActivity: AppCompatActivity(){ if (it > 0) "${if (hours > 0) "$hours hrs " else ""}${if (mins > 0) "$mins mins" else ""}" else getString(R.string.do_not_update) } - settingsAnilistSubscriptionsTime.text = getString( - R.string.anilist_notifications_checking_time, - aItems[PrefManager.getVal(PrefName.AnilistNotificationInterval)] - ) - settingsAnilistSubscriptionsTime.setOnClickListener { - - val selected = PrefManager.getVal(PrefName.AnilistNotificationInterval) - val dialog = AlertDialog.Builder(context, R.style.MyPopup) - .setTitle(R.string.subscriptions_checking_time) - .setSingleChoiceItems(aItems.toTypedArray(), selected) { dialog, i -> - PrefManager.setVal(PrefName.AnilistNotificationInterval, i) - settingsAnilistSubscriptionsTime.text = - getString(R.string.anilist_notifications_checking_time, aItems[i]) - dialog.dismiss() - TaskScheduler.create( - context, PrefManager.getVal(PrefName.UseAlarmManager) - ).scheduleAllTasks(context) - }.create() - dialog.window?.setDimAmount(0.8f) - dialog.show() - } - - settingsAnilistNotifications.setOnClickListener { - val types = NotificationType.entries.map { it.name } - val filteredTypes = - PrefManager.getVal>(PrefName.AnilistFilteredTypes).toMutableSet() - val selected = types.map { filteredTypes.contains(it) }.toBooleanArray() - val dialog = AlertDialog.Builder(context, R.style.MyPopup) - .setTitle(R.string.anilist_notification_filters) - .setMultiChoiceItems(types.toTypedArray(), selected) { _, which, isChecked -> - val type = types[which] - if (isChecked) { - filteredTypes.add(type) - } else { - filteredTypes.remove(type) - } - PrefManager.setVal(PrefName.AnilistFilteredTypes, filteredTypes) - }.create() - dialog.window?.setDimAmount(0.8f) - dialog.show() - } - val cTimeNames = CommentNotificationWorker.checkIntervals.map { it.toInt() } val cItems = cTimeNames.map { val mins = it % 60 @@ -130,70 +69,172 @@ class SettingsNotificationActivity: AppCompatActivity(){ if (it > 0) "${if (hours > 0) "$hours hrs " else ""}${if (mins > 0) "$mins mins" else ""}" else getString(R.string.do_not_update) } + settingsRecyclerView.adapter = SettingsAdapter( + arrayListOf( + Settings( + type = 1, + name = getString(R.string.subscriptions_checking_time_s, timeNames[curTime]), + desc = getString(R.string.subscriptions_info), + icon = R.drawable.ic_round_notifications_none_24, + onClick = { + val speedDialog = AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.subscriptions_checking_time) + val dialog = speedDialog.setSingleChoiceItems(timeNames, curTime) { dialog, i -> + curTime = i + it.settingsTitle.text= + getString(R.string.subscriptions_checking_time_s, timeNames[i]) + PrefManager.setVal(PrefName.SubscriptionNotificationInterval, curTime) + dialog.dismiss() + TaskScheduler.create( + context, PrefManager.getVal(PrefName.UseAlarmManager) + ).scheduleAllTasks(context) + }.show() + dialog.window?.setDimAmount(0.8f) + }, + onLongClick = { + TaskScheduler.create( + context, PrefManager.getVal(PrefName.UseAlarmManager) + ).scheduleAllTasks(context) + } + ), + Settings( + type = 1, + name = getString(R.string.anilist_notification_filters), + desc = getString(R.string.anilist_notification_filters), + icon = R.drawable.ic_anilist, + onClick = { + val types = NotificationType.entries.map { it.name } + val filteredTypes = + PrefManager.getVal>(PrefName.AnilistFilteredTypes).toMutableSet() + val selected = types.map { filteredTypes.contains(it) }.toBooleanArray() + val dialog = AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.anilist_notification_filters) + .setMultiChoiceItems(types.toTypedArray(), selected) { _, which, isChecked -> + val type = types[which] + if (isChecked) { + filteredTypes.add(type) + } else { + filteredTypes.remove(type) + } + PrefManager.setVal(PrefName.AnilistFilteredTypes, filteredTypes) + }.create() + dialog.window?.setDimAmount(0.8f) + dialog.show() + } - settingsCommentSubscriptionsTime.text = getString( - R.string.comment_notification_checking_time, - cItems[PrefManager.getVal(PrefName.CommentNotificationInterval)] - ) - settingsCommentSubscriptionsTime.setOnClickListener { - val selected = PrefManager.getVal(PrefName.CommentNotificationInterval) - val dialog = AlertDialog.Builder(context, R.style.MyPopup) - .setTitle(R.string.subscriptions_checking_time) - .setSingleChoiceItems(cItems.toTypedArray(), selected) { dialog, i -> - PrefManager.setVal(PrefName.CommentNotificationInterval, i) - settingsCommentSubscriptionsTime.text = - getString(R.string.comment_notification_checking_time, cItems[i]) - dialog.dismiss() - TaskScheduler.create( - context, PrefManager.getVal(PrefName.UseAlarmManager) - ).scheduleAllTasks(context) - }.create() - dialog.window?.setDimAmount(0.8f) - dialog.show() - } - - settingsNotificationsCheckingSubscriptions.isChecked = - PrefManager.getVal(PrefName.SubscriptionCheckingNotifications) - settingsNotificationsCheckingSubscriptions.setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.SubscriptionCheckingNotifications, isChecked) - } - - settingsNotificationsCheckingSubscriptions.setOnLongClickListener { - openSettings(context, null) - } - - settingsNotificationsUseAlarmManager.isChecked = - PrefManager.getVal(PrefName.UseAlarmManager) - - settingsNotificationsUseAlarmManager.setOnCheckedChangeListener { _, isChecked -> - if (isChecked) { - val alertDialog = AlertDialog.Builder(context, R.style.MyPopup) - .setTitle(R.string.use_alarm_manager) - .setMessage(R.string.use_alarm_manager_confirm) - .setPositiveButton(R.string.use) { dialog, _ -> - PrefManager.setVal(PrefName.UseAlarmManager, true) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - if (!(getSystemService(Context.ALARM_SERVICE) as AlarmManager).canScheduleExactAlarms()) { - val intent = - Intent("android.settings.REQUEST_SCHEDULE_EXACT_ALARM") - startActivity(intent) - settingsNotificationsCheckingSubscriptions.isChecked = true - } + ), + Settings( + type = 1, + name = getString( + R.string.anilist_notifications_checking_time, + aItems[PrefManager.getVal(PrefName.AnilistNotificationInterval)] + ), + desc = getString( + R.string.anilist_notifications_checking_time, + aItems[PrefManager.getVal(PrefName.AnilistNotificationInterval)] + ), + icon = R.drawable.ic_round_notifications_none_24, + onClick = { + val selected = PrefManager.getVal(PrefName.AnilistNotificationInterval) + val dialog = AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.subscriptions_checking_time) + .setSingleChoiceItems(aItems.toTypedArray(), selected) { dialog, i -> + PrefManager.setVal(PrefName.AnilistNotificationInterval, i) + it.settingsTitle.text = + getString(R.string.anilist_notifications_checking_time, aItems[i]) + dialog.dismiss() + TaskScheduler.create( + context, PrefManager.getVal(PrefName.UseAlarmManager) + ).scheduleAllTasks(context) + }.create() + dialog.window?.setDimAmount(0.8f) + dialog.show() + } + ), + Settings( + type = 1, + name = getString( + R.string.comment_notification_checking_time, + cItems[PrefManager.getVal(PrefName.CommentNotificationInterval)] + ), + desc = getString( + R.string.comment_notification_checking_time, + cItems[PrefManager.getVal(PrefName.CommentNotificationInterval)] + ), + icon = R.drawable.ic_round_notifications_none_24, + onClick = { + val selected = PrefManager.getVal(PrefName.CommentNotificationInterval) + val dialog = AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.subscriptions_checking_time) + .setSingleChoiceItems(cItems.toTypedArray(), selected) { dialog, i -> + PrefManager.setVal(PrefName.CommentNotificationInterval, i) + it.settingsTitle.text = + getString(R.string.comment_notification_checking_time, cItems[i]) + dialog.dismiss() + TaskScheduler.create( + context, PrefManager.getVal(PrefName.UseAlarmManager) + ).scheduleAllTasks(context) + }.create() + dialog.window?.setDimAmount(0.8f) + dialog.show() + } + ), + Settings( + type = 2, + name = getString(R.string.notification_for_checking_subscriptions), + desc = getString(R.string.notification_for_checking_subscriptions), + icon = R.drawable.ic_round_smart_button_24, + isChecked = PrefManager.getVal(PrefName.SubscriptionCheckingNotifications), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.SubscriptionCheckingNotifications, isChecked) + }, + onLongClick = { + openSettings(context, null) + } + ), + Settings( + type = 2, + name = getString(R.string.use_alarm_manager_reliable), + desc = getString(R.string.use_alarm_manager_reliable), + icon = R.drawable.ic_anilist, + isChecked = PrefManager.getVal(PrefName.UseAlarmManager), + switch = {isChecked, view -> + if (isChecked) { + val alertDialog = AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.use_alarm_manager) + .setMessage(R.string.use_alarm_manager_confirm) + .setPositiveButton(R.string.use) { dialog, _ -> + PrefManager.setVal(PrefName.UseAlarmManager, true) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + if (!(getSystemService(Context.ALARM_SERVICE) as AlarmManager).canScheduleExactAlarms()) { + val intent = + Intent("android.settings.REQUEST_SCHEDULE_EXACT_ALARM") + startActivity(intent) + view.settingsButton.isChecked = true + } + } + dialog.dismiss() + }.setNegativeButton(R.string.cancel) { dialog, _ -> + view.settingsButton.isChecked = false + PrefManager.setVal(PrefName.UseAlarmManager, false) + + dialog.dismiss() + }.create() + alertDialog.window?.setDimAmount(0.8f) + alertDialog.show() + } else { + PrefManager.setVal(PrefName.UseAlarmManager, false) + TaskScheduler.create(context, true).cancelAllTasks() + TaskScheduler.create(context, false) + .scheduleAllTasks(context) } - dialog.dismiss() - }.setNegativeButton(R.string.cancel) { dialog, _ -> - settingsNotificationsCheckingSubscriptions.isChecked = false - PrefManager.setVal(PrefName.UseAlarmManager, false) - dialog.dismiss() - }.create() - alertDialog.window?.setDimAmount(0.8f) - alertDialog.show() - } else { - PrefManager.setVal(PrefName.UseAlarmManager, false) - TaskScheduler.create(context, true).cancelAllTasks() - TaskScheduler.create(context, false) - .scheduleAllTasks(context) - } + }, + ), + ) + ) + settingsRecyclerView.apply { + layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + setHasFixedSize(true) } } } diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsThemeActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsThemeActivity.kt index 0d622f15..e1fec176 100644 --- a/app/src/main/java/ani/dantotsu/settings/SettingsThemeActivity.kt +++ b/app/src/main/java/ani/dantotsu/settings/SettingsThemeActivity.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import android.widget.ArrayAdapter import androidx.appcompat.app.AppCompatActivity import androidx.core.view.updateLayoutParams +import androidx.recyclerview.widget.LinearLayoutManager import ani.dantotsu.R import ani.dantotsu.databinding.ActivitySettingsThemeBinding import ani.dantotsu.initActivity @@ -58,7 +59,7 @@ class SettingsThemeActivity : AppCompatActivity(), SimpleDialog.OnDialogResultLi } settingsUiLight.setOnClickListener { - settingsUseOLED.isChecked = false + PrefManager.setVal(PrefName.UseOLED, false) uiTheme(1, it) } @@ -89,64 +90,85 @@ class SettingsThemeActivity : AppCompatActivity(), SimpleDialog.OnDialogResultLi restartApp(binding.root) } } - settingsUseOLED.apply { - isChecked = PrefManager.getVal(PrefName.UseOLED) - setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.UseOLED, isChecked) - restartApp(binding.root) - } - } - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) { - settingsUseMaterialYou.apply { - isChecked = PrefManager.getVal(PrefName.UseMaterialYou) - setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.UseMaterialYou, isChecked) - if (isChecked) settingsUseCustomTheme.isChecked = false - restartApp(binding.root) - } - visibility = View.VISIBLE - } - - settingsUseSourceTheme.apply { - isChecked = PrefManager.getVal(PrefName.UseSourceTheme) - setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.UseSourceTheme, isChecked) - restartApp(binding.root) - } - visibility = View.VISIBLE - } - settingsUseCustomTheme.apply { - isChecked = PrefManager.getVal(PrefName.UseCustomTheme) - setOnCheckedChangeListener { _, isChecked -> - PrefManager.setVal(PrefName.UseCustomTheme, isChecked) - if (isChecked) { - settingsUseMaterialYou.isChecked = false + settingsRecyclerView.adapter = SettingsAdapter( + arrayListOf( + Settings( + type = 2, + name = getString(R.string.oled_theme_variant), + desc = getString(R.string.oled_theme_variant), + icon = R.drawable.ic_round_brightness_4_24, + isChecked = PrefManager.getVal(PrefName.UseOLED), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.UseOLED, isChecked) + restartApp(binding.root) } - restartApp(binding.root) - } - visibility = View.VISIBLE - } - - customTheme.apply { - setOnClickListener { - val originalColor: Int = PrefManager.getVal(PrefName.CustomThemeInt) - class CustomColorDialog : SimpleColorDialog() { - override fun onPositiveButtonClick() { - restartApp(binding.root) - super.onPositiveButtonClick() + ), + Settings( + type = 2, + name = getString(R.string.use_material_you), + desc = getString(R.string.use_material_you), + icon = R.drawable.ic_round_new_releases_24, + isChecked = PrefManager.getVal(PrefName.UseMaterialYou), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.UseMaterialYou, isChecked) + if (isChecked) PrefManager.setVal(PrefName.UseCustomTheme, false) + restartApp(binding.root) + }, + isVisible = Build.VERSION.SDK_INT > Build.VERSION_CODES.R + ), + Settings( + type = 2, + name = getString(R.string.use_unique_theme_for_each_item), + desc = getString(R.string.use_unique_theme_for_each_item), + icon = R.drawable.ic_palette, + isChecked = PrefManager.getVal(PrefName.UseSourceTheme), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.UseSourceTheme, isChecked) + restartApp(binding.root) + }, + isVisible = Build.VERSION.SDK_INT > Build.VERSION_CODES.R + ), + Settings( + type = 2, + name = getString(R.string.use_custom_theme), + desc = getString(R.string.use_custom_theme), + icon = R.drawable.ic_palette, + isChecked = PrefManager.getVal(PrefName.UseCustomTheme), + switch = { isChecked, _ -> + PrefManager.setVal(PrefName.UseCustomTheme, isChecked) + if (isChecked) PrefManager.setVal(PrefName.UseMaterialYou, false) + restartApp(binding.root) + }, + isVisible = Build.VERSION.SDK_INT > Build.VERSION_CODES.R + ), + Settings( + type = 1, + name = getString(R.string.color_picker), + desc = getString(R.string.color_picker), + icon = R.drawable.ic_palette, + onClick = { + val originalColor: Int = PrefManager.getVal(PrefName.CustomThemeInt) + class CustomColorDialog : SimpleColorDialog() { + override fun onPositiveButtonClick() { + restartApp(binding.root) + super.onPositiveButtonClick() + } } - } - val tag = "colorPicker" - CustomColorDialog().title(R.string.custom_theme).colorPreset(originalColor) - .colors(context, SimpleColorDialog.MATERIAL_COLOR_PALLET) - .allowCustom(true).showOutline(0x46000000).gridNumColumn(5) - .choiceMode(SimpleColorDialog.SINGLE_CHOICE).neg() - .show(context, tag) - } - visibility = View.VISIBLE - } - customThemeTitle.visibility = View.VISIBLE + val tag = "colorPicker" + CustomColorDialog().title(R.string.custom_theme).colorPreset(originalColor) + .colors(context, SimpleColorDialog.MATERIAL_COLOR_PALLET) + .allowCustom(true).showOutline(0x46000000).gridNumColumn(5) + .choiceMode(SimpleColorDialog.SINGLE_CHOICE).neg() + .show(context, tag) + }, + isVisible = Build.VERSION.SDK_INT > Build.VERSION_CODES.R + ) + ) + ) + settingsRecyclerView.apply { + layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + setHasFixedSize(true) } } } diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 9e3a9897..c00db1c6 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -80,7 +80,7 @@ android:id="@+id/settingsRecyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" - android:nestedScrollingEnabled="true" + android:nestedScrollingEnabled="false" android:requiresFadingEdge="vertical" tools:itemCount="5" tools:listitem="@layout/item_settings" /> diff --git a/app/src/main/res/layout/activity_settings_about.xml b/app/src/main/res/layout/activity_settings_about.xml index bc2712b7..e99f61de 100644 --- a/app/src/main/res/layout/activity_settings_about.xml +++ b/app/src/main/res/layout/activity_settings_about.xml @@ -10,15 +10,12 @@ android:id="@+id/settingsAboutLayout" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" - android:paddingStart="32dp" - android:paddingEnd="32dp"> - + android:orientation="vertical"> -