chore: code refactor
This commit is contained in:
parent
8d7b86a667
commit
a2e44da99d
334 changed files with 3550 additions and 3092 deletions
|
@ -1,14 +1,16 @@
|
|||
package ani.dantotsu.settings
|
||||
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import java.io.Serializable
|
||||
|
||||
data class CurrentNovelReaderSettings(
|
||||
var currentThemeName: String = PrefManager.getVal(PrefName.CurrentThemeName),
|
||||
var layout: Layouts = Layouts[PrefManager.getVal(PrefName.LayoutNovel)]
|
||||
?: Layouts.PAGED,
|
||||
var dualPageMode: CurrentReaderSettings.DualPageModes = CurrentReaderSettings.DualPageModes[PrefManager.getVal(PrefName.DualPageModeNovel)]
|
||||
var dualPageMode: CurrentReaderSettings.DualPageModes = CurrentReaderSettings.DualPageModes[PrefManager.getVal(
|
||||
PrefName.DualPageModeNovel
|
||||
)]
|
||||
?: CurrentReaderSettings.DualPageModes.Automatic,
|
||||
var lineHeight: Float = PrefManager.getVal(PrefName.LineHeight),
|
||||
var margin: Float = PrefManager.getVal(PrefName.Margin),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package ani.dantotsu.settings
|
||||
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import java.io.Serializable
|
||||
|
||||
data class CurrentReaderSettings(
|
||||
|
|
|
@ -18,8 +18,8 @@ import androidx.viewpager2.widget.ViewPager2
|
|||
import ani.dantotsu.*
|
||||
import ani.dantotsu.databinding.ActivityExtensionsBinding
|
||||
import ani.dantotsu.others.LanguageMapper
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
|
@ -30,7 +30,7 @@ class ExtensionsActivity : AppCompatActivity() {
|
|||
@SuppressLint("SetTextI18n")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
||||
ThemeManager(this).applyTheme()
|
||||
binding = ActivityExtensionsBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
@ -65,7 +65,8 @@ class ExtensionsActivity : AppCompatActivity() {
|
|||
searchView.setText("")
|
||||
searchView.clearFocus()
|
||||
tabLayout.clearFocus()
|
||||
if (tab.text?.contains("Installed") == true) binding.languageselect.visibility = View.GONE
|
||||
if (tab.text?.contains("Installed") == true) binding.languageselect.visibility =
|
||||
View.GONE
|
||||
else binding.languageselect.visibility = View.VISIBLE
|
||||
viewPager.updateLayoutParams<ViewGroup.LayoutParams> {
|
||||
height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
|
@ -119,13 +120,18 @@ class ExtensionsActivity : AppCompatActivity() {
|
|||
|
||||
initActivity(this)
|
||||
binding.languageselect.setOnClickListener {
|
||||
val languageOptions = LanguageMapper.Companion.Language.entries.map{ it.name }.toTypedArray()
|
||||
val languageOptions =
|
||||
LanguageMapper.Companion.Language.entries.map { it.name }.toTypedArray()
|
||||
val builder = AlertDialog.Builder(currContext(), R.style.MyPopup)
|
||||
val listOrder: String = PrefManager.getVal(PrefName.LangSort)
|
||||
val index = LanguageMapper.Companion.Language.entries.toTypedArray().indexOfFirst{it.code == listOrder}
|
||||
val index = LanguageMapper.Companion.Language.entries.toTypedArray()
|
||||
.indexOfFirst { it.code == listOrder }
|
||||
builder.setTitle("Language")
|
||||
builder.setSingleChoiceItems(languageOptions, index){ dialog, i ->
|
||||
PrefManager.setVal(PrefName.LangSort, LanguageMapper.Companion.Language.entries[i].code)
|
||||
builder.setSingleChoiceItems(languageOptions, index) { dialog, i ->
|
||||
PrefManager.setVal(
|
||||
PrefName.LangSort,
|
||||
LanguageMapper.Companion.Language.entries[i].code
|
||||
)
|
||||
val currentFragment =
|
||||
supportFragmentManager.findFragmentByTag("f${viewPager.currentItem}")
|
||||
if (currentFragment is SearchQueryHandler) {
|
||||
|
|
|
@ -100,7 +100,7 @@ class FAQActivity : AppCompatActivity() {
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
||||
ThemeManager(this).applyTheme()
|
||||
binding = ActivityFaqBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
|
|
@ -192,15 +192,20 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
extensionsRecyclerView.adapter = extensionsAdapter
|
||||
|
||||
val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(
|
||||
ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0) {
|
||||
ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0
|
||||
) {
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
extensionsAdapter.onMove(viewHolder.absoluteAdapterPosition, target.absoluteAdapterPosition)
|
||||
extensionsAdapter.onMove(
|
||||
viewHolder.absoluteAdapterPosition,
|
||||
target.absoluteAdapterPosition
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
|
||||
|
||||
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
|
||||
|
@ -211,7 +216,10 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
}
|
||||
}
|
||||
|
||||
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
|
||||
override fun clearView(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder
|
||||
) {
|
||||
super.clearView(recyclerView, viewHolder)
|
||||
viewHolder.itemView.elevation = 0f
|
||||
viewHolder.itemView.translationZ = 0f
|
||||
|
@ -243,7 +251,10 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
}
|
||||
|
||||
override fun updateContentBasedOnQuery(query: String?) {
|
||||
extensionsAdapter.filter(query ?: "", sortToAnimeSourcesList(animeExtensionManager.installedExtensionsFlow.value))
|
||||
extensionsAdapter.filter(
|
||||
query ?: "",
|
||||
sortToAnimeSourcesList(animeExtensionManager.installedExtensionsFlow.value)
|
||||
)
|
||||
}
|
||||
|
||||
override fun notifyDataChanged() { // Do nothing
|
||||
|
|
|
@ -29,8 +29,8 @@ import ani.dantotsu.databinding.FragmentMangaExtensionsBinding
|
|||
import ani.dantotsu.others.LanguageMapper
|
||||
import ani.dantotsu.parsers.MangaSources
|
||||
import ani.dantotsu.settings.extensionprefs.MangaSourcePreferencesFragment
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.snackString
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
|
@ -188,15 +188,20 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
extensionsRecyclerView.adapter = extensionsAdapter
|
||||
|
||||
val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(
|
||||
ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0) {
|
||||
ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0
|
||||
) {
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
extensionsAdapter.onMove(viewHolder.absoluteAdapterPosition, target.absoluteAdapterPosition)
|
||||
extensionsAdapter.onMove(
|
||||
viewHolder.absoluteAdapterPosition,
|
||||
target.absoluteAdapterPosition
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
|
||||
|
||||
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
|
||||
|
@ -207,7 +212,10 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
}
|
||||
}
|
||||
|
||||
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
|
||||
override fun clearView(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder
|
||||
) {
|
||||
super.clearView(recyclerView, viewHolder)
|
||||
viewHolder.itemView.elevation = 0f
|
||||
viewHolder.itemView.translationZ = 0f
|
||||
|
@ -237,7 +245,10 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
}
|
||||
|
||||
override fun updateContentBasedOnQuery(query: String?) {
|
||||
extensionsAdapter.filter(query ?: "", sortToMangaSourcesList(mangaExtensionManager.installedExtensionsFlow.value))
|
||||
extensionsAdapter.filter(
|
||||
query ?: "",
|
||||
sortToMangaSourcesList(mangaExtensionManager.installedExtensionsFlow.value)
|
||||
)
|
||||
}
|
||||
|
||||
override fun notifyDataChanged() { // Do nothing
|
||||
|
|
|
@ -27,8 +27,8 @@ import ani.dantotsu.others.LanguageMapper
|
|||
import ani.dantotsu.parsers.NovelSources
|
||||
import ani.dantotsu.parsers.novel.NovelExtension
|
||||
import ani.dantotsu.parsers.novel.NovelExtensionManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.snackString
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -117,15 +117,20 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
extensionsRecyclerView.adapter = extensionsAdapter
|
||||
|
||||
val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(
|
||||
ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0) {
|
||||
ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0
|
||||
) {
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
extensionsAdapter.onMove(viewHolder.absoluteAdapterPosition, target.absoluteAdapterPosition)
|
||||
extensionsAdapter.onMove(
|
||||
viewHolder.absoluteAdapterPosition,
|
||||
target.absoluteAdapterPosition
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
|
||||
|
||||
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
|
||||
|
@ -136,7 +141,10 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
}
|
||||
}
|
||||
|
||||
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
|
||||
override fun clearView(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder
|
||||
) {
|
||||
super.clearView(recyclerView, viewHolder)
|
||||
viewHolder.itemView.elevation = 0f
|
||||
viewHolder.itemView.translationZ = 0f
|
||||
|
@ -167,7 +175,10 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
}
|
||||
|
||||
override fun updateContentBasedOnQuery(query: String?) {
|
||||
extensionsAdapter.filter(query ?: "", sortToNovelSourcesList(novelExtensionManager.installedExtensionsFlow.value))
|
||||
extensionsAdapter.filter(
|
||||
query ?: "",
|
||||
sortToNovelSourcesList(novelExtensionManager.installedExtensionsFlow.value)
|
||||
)
|
||||
}
|
||||
|
||||
override fun notifyDataChanged() { // do nothing
|
||||
|
|
|
@ -18,8 +18,8 @@ import ani.dantotsu.media.Media
|
|||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.others.getSerialized
|
||||
import ani.dantotsu.parsers.Subtitle
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
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
|
||||
|
@ -38,7 +38,7 @@ class PlayerSettingsActivity : AppCompatActivity() {
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
||||
ThemeManager(this).applyTheme()
|
||||
binding = ActivityPlayerSettingsBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
@ -88,12 +88,18 @@ class PlayerSettingsActivity : AppCompatActivity() {
|
|||
var curSpeedArr = if (PrefManager.getVal(PrefName.CursedSpeeds)) cursedSpeeds else speeds
|
||||
var speedsName = curSpeedArr.map { "${it}x" }.toTypedArray()
|
||||
binding.playerSettingsSpeed.text =
|
||||
getString(R.string.default_playback_speed, speedsName[PrefManager.getVal(PrefName.DefaultSpeed)])
|
||||
getString(
|
||||
R.string.default_playback_speed,
|
||||
speedsName[PrefManager.getVal(PrefName.DefaultSpeed)]
|
||||
)
|
||||
val speedDialog = AlertDialog.Builder(this, R.style.MyPopup)
|
||||
.setTitle(getString(R.string.default_speed))
|
||||
binding.playerSettingsSpeed.setOnClickListener {
|
||||
val dialog =
|
||||
speedDialog.setSingleChoiceItems(speedsName, PrefManager.getVal(PrefName.DefaultSpeed)) { dialog, i ->
|
||||
speedDialog.setSingleChoiceItems(
|
||||
speedsName,
|
||||
PrefManager.getVal(PrefName.DefaultSpeed)
|
||||
) { dialog, i ->
|
||||
PrefManager.setVal(PrefName.DefaultSpeed, i)
|
||||
binding.playerSettingsSpeed.text =
|
||||
getString(R.string.default_playback_speed, speedsName[i])
|
||||
|
@ -110,7 +116,10 @@ class PlayerSettingsActivity : AppCompatActivity() {
|
|||
PrefManager.setVal(PrefName.DefaultSpeed, newDefaultSpeed)
|
||||
speedsName = curSpeedArr.map { "${it}x" }.toTypedArray()
|
||||
binding.playerSettingsSpeed.text =
|
||||
getString(R.string.default_playback_speed, speedsName[PrefManager.getVal(PrefName.DefaultSpeed)])
|
||||
getString(
|
||||
R.string.default_playback_speed,
|
||||
speedsName[PrefManager.getVal(PrefName.DefaultSpeed)]
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
@ -120,12 +129,14 @@ class PlayerSettingsActivity : AppCompatActivity() {
|
|||
PrefManager.setVal(PrefName.TimeStampsEnabled, isChecked)
|
||||
}
|
||||
|
||||
binding.playerSettingsTimeStampsProxy.isChecked = PrefManager.getVal(PrefName.UseProxyForTimeStamps)
|
||||
binding.playerSettingsTimeStampsProxy.isChecked =
|
||||
PrefManager.getVal(PrefName.UseProxyForTimeStamps)
|
||||
binding.playerSettingsTimeStampsProxy.setOnCheckedChangeListener { _, isChecked ->
|
||||
PrefManager.setVal(PrefName.UseProxyForTimeStamps, isChecked)
|
||||
}
|
||||
|
||||
binding.playerSettingsShowTimeStamp.isChecked = PrefManager.getVal(PrefName.ShowTimeStampButton)
|
||||
binding.playerSettingsShowTimeStamp.isChecked =
|
||||
PrefManager.getVal(PrefName.ShowTimeStampButton)
|
||||
binding.playerSettingsShowTimeStamp.setOnCheckedChangeListener { _, isChecked ->
|
||||
PrefManager.setVal(PrefName.ShowTimeStampButton, isChecked)
|
||||
}
|
||||
|
@ -147,16 +158,19 @@ class PlayerSettingsActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
//Update Progress
|
||||
binding.playerSettingsAskUpdateProgress.isChecked = PrefManager.getVal(PrefName.AskIndividualPlayer)
|
||||
binding.playerSettingsAskUpdateProgress.isChecked =
|
||||
PrefManager.getVal(PrefName.AskIndividualPlayer)
|
||||
binding.playerSettingsAskUpdateProgress.setOnCheckedChangeListener { _, isChecked ->
|
||||
PrefManager.setVal(PrefName.AskIndividualPlayer, isChecked)
|
||||
}
|
||||
binding.playerSettingsAskUpdateHentai.isChecked = PrefManager.getVal(PrefName.UpdateForHPlayer)
|
||||
binding.playerSettingsAskUpdateHentai.isChecked =
|
||||
PrefManager.getVal(PrefName.UpdateForHPlayer)
|
||||
binding.playerSettingsAskUpdateHentai.setOnCheckedChangeListener { _, isChecked ->
|
||||
PrefManager.setVal(PrefName.UpdateForHPlayer, isChecked)
|
||||
if (isChecked) snackString(getString(R.string.very_bold))
|
||||
}
|
||||
binding.playerSettingsCompletePercentage.value = (PrefManager.getVal<Float>(PrefName.WatchPercentage) * 100).roundToInt().toFloat()
|
||||
binding.playerSettingsCompletePercentage.value =
|
||||
(PrefManager.getVal<Float>(PrefName.WatchPercentage) * 100).roundToInt().toFloat()
|
||||
binding.playerSettingsCompletePercentage.addOnChangeListener { _, value, _ ->
|
||||
PrefManager.setVal(PrefName.WatchPercentage, value / 100)
|
||||
}
|
||||
|
@ -229,7 +243,10 @@ class PlayerSettingsActivity : AppCompatActivity() {
|
|||
val resizeDialog = AlertDialog.Builder(this, R.style.MyPopup)
|
||||
.setTitle(getString(R.string.default_resize_mode))
|
||||
binding.playerResizeMode.setOnClickListener {
|
||||
val dialog = resizeDialog.setSingleChoiceItems(resizeModes, PrefManager.getVal<Int>(PrefName.Resize)) { dialog, count ->
|
||||
val dialog = resizeDialog.setSingleChoiceItems(
|
||||
resizeModes,
|
||||
PrefManager.getVal<Int>(PrefName.Resize)
|
||||
) { dialog, count ->
|
||||
PrefManager.setVal(PrefName.Resize, count)
|
||||
dialog.dismiss()
|
||||
}.show()
|
||||
|
@ -425,7 +442,10 @@ class PlayerSettingsActivity : AppCompatActivity() {
|
|||
val fontDialog = AlertDialog.Builder(this, R.style.MyPopup)
|
||||
.setTitle(getString(R.string.subtitle_font))
|
||||
binding.videoSubFont.setOnClickListener {
|
||||
val dialog = fontDialog.setSingleChoiceItems(fonts, PrefManager.getVal(PrefName.Font)) { dialog, count ->
|
||||
val dialog = fontDialog.setSingleChoiceItems(
|
||||
fonts,
|
||||
PrefManager.getVal(PrefName.Font)
|
||||
) { dialog, count ->
|
||||
PrefManager.setVal(PrefName.Font, count)
|
||||
dialog.dismiss()
|
||||
}.show()
|
||||
|
|
|
@ -8,8 +8,8 @@ import ani.dantotsu.R
|
|||
import ani.dantotsu.databinding.ActivityReaderSettingsBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
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
|
||||
|
@ -20,7 +20,7 @@ class ReaderSettingsActivity : AppCompatActivity() {
|
|||
private var defaultSettingsLN = CurrentNovelReaderSettings()
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
||||
ThemeManager(this).applyTheme()
|
||||
binding = ActivityReaderSettingsBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
@ -107,7 +107,10 @@ class ReaderSettingsActivity : AppCompatActivity() {
|
|||
defaultSettings.dualPageMode = CurrentReaderSettings.DualPageModes[index]
|
||||
?: CurrentReaderSettings.DualPageModes.Automatic
|
||||
binding.readerSettingsDualPageText.text = defaultSettings.dualPageMode.toString()
|
||||
PrefManager.setVal(PrefName.DualPageModeReader, defaultSettings.dualPageMode.ordinal)
|
||||
PrefManager.setVal(
|
||||
PrefName.DualPageModeReader,
|
||||
defaultSettings.dualPageMode.ordinal
|
||||
)
|
||||
}
|
||||
}
|
||||
binding.readerSettingsTrueColors.isChecked = defaultSettings.trueColors
|
||||
|
@ -215,7 +218,10 @@ class ReaderSettingsActivity : AppCompatActivity() {
|
|||
defaultSettingsLN.dualPageMode = CurrentReaderSettings.DualPageModes[index]
|
||||
?: CurrentReaderSettings.DualPageModes.Automatic
|
||||
binding.LNdualPageText.text = defaultSettingsLN.dualPageMode.toString()
|
||||
PrefManager.setVal(PrefName.DualPageModeNovel, defaultSettingsLN.dualPageMode.ordinal)
|
||||
PrefManager.setVal(
|
||||
PrefName.DualPageModeNovel,
|
||||
defaultSettingsLN.dualPageMode.ordinal
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,11 +345,13 @@ class ReaderSettingsActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
//Update Progress
|
||||
binding.readerSettingsAskUpdateProgress.isChecked = PrefManager.getVal(PrefName.AskIndividualReader)
|
||||
binding.readerSettingsAskUpdateProgress.isChecked =
|
||||
PrefManager.getVal(PrefName.AskIndividualReader)
|
||||
binding.readerSettingsAskUpdateProgress.setOnCheckedChangeListener { _, isChecked ->
|
||||
PrefManager.setVal(PrefName.AskIndividualReader, isChecked)
|
||||
}
|
||||
binding.readerSettingsAskUpdateDoujins.isChecked = PrefManager.getVal(PrefName.UpdateForHReader)
|
||||
binding.readerSettingsAskUpdateDoujins.isChecked =
|
||||
PrefManager.getVal(PrefName.UpdateForHReader)
|
||||
binding.readerSettingsAskUpdateDoujins.setOnCheckedChangeListener { _, isChecked ->
|
||||
PrefManager.setVal(PrefName.UpdateForHReader, isChecked)
|
||||
if (isChecked) snackString(getString(R.string.very_bold))
|
||||
|
|
|
@ -4,8 +4,12 @@ import android.annotation.SuppressLint
|
|||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Animatable
|
||||
import android.os.Build.*
|
||||
import android.os.Build.VERSION.*
|
||||
import android.os.Build.BRAND
|
||||
import android.os.Build.DEVICE
|
||||
import android.os.Build.SUPPORTED_ABIS
|
||||
import android.os.Build.VERSION.CODENAME
|
||||
import android.os.Build.VERSION.RELEASE
|
||||
import android.os.Build.VERSION.SDK_INT
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -14,9 +18,7 @@ import android.widget.ArrayAdapter
|
|||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
|
@ -25,34 +27,45 @@ import androidx.documentfile.provider.DocumentFile
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.exoplayer.offline.DownloadService
|
||||
import ani.dantotsu.*
|
||||
import ani.dantotsu.Mapper.json
|
||||
import ani.dantotsu.BuildConfig
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.Refresh
|
||||
import ani.dantotsu.connections.anilist.Anilist
|
||||
import ani.dantotsu.connections.discord.Discord
|
||||
import ani.dantotsu.connections.mal.MAL
|
||||
import ani.dantotsu.copyToClipboard
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.databinding.ActivitySettingsBinding
|
||||
import ani.dantotsu.download.DownloadedType
|
||||
import ani.dantotsu.download.DownloadsManager
|
||||
import ani.dantotsu.download.video.ExoplayerDownloadService
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.loadImage
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.openLinkInBrowser
|
||||
import ani.dantotsu.others.AppUpdater
|
||||
import ani.dantotsu.others.CustomBottomDialog
|
||||
import ani.dantotsu.parsers.AnimeSources
|
||||
import ani.dantotsu.parsers.MangaSources
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.pop
|
||||
import ani.dantotsu.savePrefsToDownloads
|
||||
import ani.dantotsu.setSafeOnClickListener
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.internal.Location
|
||||
import ani.dantotsu.settings.saving.internal.PreferenceKeystore
|
||||
import ani.dantotsu.settings.saving.internal.PreferencePackager
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.startMainActivity
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.subcriptions.Notifications
|
||||
import ani.dantotsu.subcriptions.Notifications.Companion.openSettings
|
||||
import ani.dantotsu.subcriptions.Subscription.Companion.defaultTime
|
||||
import ani.dantotsu.subcriptions.Subscription.Companion.startSubscription
|
||||
import ani.dantotsu.subcriptions.Subscription.Companion.timeMinutes
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import ani.dantotsu.toast
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import eltos.simpledialogfragment.SimpleDialog
|
||||
import eltos.simpledialogfragment.SimpleDialog.OnDialogResultListener.BUTTON_POSITIVE
|
||||
import eltos.simpledialogfragment.color.SimpleColorDialog
|
||||
|
@ -85,47 +98,48 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
|
|||
|
||||
initActivity(this)
|
||||
|
||||
val openDocumentLauncher = registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
|
||||
if (uri != null) {
|
||||
try {
|
||||
val jsonString = contentResolver.openInputStream(uri)?.readBytes()
|
||||
?: throw Exception("Error reading file")
|
||||
val name = DocumentFile.fromSingleUri(this, uri)?.name ?: "settings"
|
||||
//.sani is encrypted, .ani is not
|
||||
if (name.endsWith(".sani")) {
|
||||
passwordAlertDialog(false) { password ->
|
||||
if (password != null) {
|
||||
val salt = jsonString.copyOfRange(0, 16)
|
||||
val encrypted = jsonString.copyOfRange(16, jsonString.size)
|
||||
val decryptedJson = try {
|
||||
PreferenceKeystore.decryptWithPassword(
|
||||
password,
|
||||
encrypted,
|
||||
salt
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
toast("Incorrect password")
|
||||
return@passwordAlertDialog
|
||||
val openDocumentLauncher =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
|
||||
if (uri != null) {
|
||||
try {
|
||||
val jsonString = contentResolver.openInputStream(uri)?.readBytes()
|
||||
?: throw Exception("Error reading file")
|
||||
val name = DocumentFile.fromSingleUri(this, uri)?.name ?: "settings"
|
||||
//.sani is encrypted, .ani is not
|
||||
if (name.endsWith(".sani")) {
|
||||
passwordAlertDialog(false) { password ->
|
||||
if (password != null) {
|
||||
val salt = jsonString.copyOfRange(0, 16)
|
||||
val encrypted = jsonString.copyOfRange(16, jsonString.size)
|
||||
val decryptedJson = try {
|
||||
PreferenceKeystore.decryptWithPassword(
|
||||
password,
|
||||
encrypted,
|
||||
salt
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
toast("Incorrect password")
|
||||
return@passwordAlertDialog
|
||||
}
|
||||
if (PreferencePackager.unpack(decryptedJson))
|
||||
restartApp()
|
||||
} else {
|
||||
toast("Password cannot be empty")
|
||||
}
|
||||
if(PreferencePackager.unpack(decryptedJson))
|
||||
restartApp()
|
||||
} else {
|
||||
toast("Password cannot be empty")
|
||||
}
|
||||
} else if (name.endsWith(".ani")) {
|
||||
val decryptedJson = jsonString.toString(Charsets.UTF_8)
|
||||
if (PreferencePackager.unpack(decryptedJson))
|
||||
restartApp()
|
||||
} else {
|
||||
toast("Unknown file type")
|
||||
}
|
||||
} else if (name.endsWith(".ani")) {
|
||||
val decryptedJson = jsonString.toString(Charsets.UTF_8)
|
||||
if(PreferencePackager.unpack(decryptedJson))
|
||||
restartApp()
|
||||
} else {
|
||||
toast("Unknown file type")
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
toast("Error importing settings")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
toast("Error importing settings")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binding.settingsVersion.text = getString(R.string.version_current, BuildConfig.VERSION_NAME)
|
||||
binding.settingsVersion.setOnLongClickListener {
|
||||
|
@ -244,7 +258,10 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
|
|||
selectedArray.addAll(List(filteredLocations.size - 1) { false })
|
||||
val dialog = AlertDialog.Builder(this, R.style.MyPopup)
|
||||
.setTitle("Import/Export Settings")
|
||||
.setMultiChoiceItems( filteredLocations.map { it.name }.toTypedArray(), selectedArray.toBooleanArray()) { _, which, isChecked ->
|
||||
.setMultiChoiceItems(
|
||||
filteredLocations.map { it.name }.toTypedArray(),
|
||||
selectedArray.toBooleanArray()
|
||||
) { _, which, isChecked ->
|
||||
selectedArray[which] = isChecked
|
||||
}
|
||||
.setPositiveButton("Import...") { dialog, _ ->
|
||||
|
@ -257,7 +274,8 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
|
|||
return@setNegativeButton
|
||||
}
|
||||
dialog.dismiss()
|
||||
val selected = filteredLocations.filterIndexed { index, _ -> selectedArray[index] }
|
||||
val selected =
|
||||
filteredLocations.filterIndexed { index, _ -> selectedArray[index] }
|
||||
if (selected.contains(Location.Protected)) {
|
||||
passwordAlertDialog(true) { password ->
|
||||
if (password != null) {
|
||||
|
@ -360,7 +378,7 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
|
|||
}
|
||||
binding.NSFWExtension.isChecked = PrefManager.getVal(PrefName.NSFWExtension)
|
||||
binding.NSFWExtension.setOnCheckedChangeListener { _, isChecked ->
|
||||
PrefManager.setVal(PrefName.NSFWExtension,isChecked)
|
||||
PrefManager.setVal(PrefName.NSFWExtension, isChecked)
|
||||
|
||||
}
|
||||
|
||||
|
@ -847,7 +865,8 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
|
|||
show()
|
||||
}
|
||||
}
|
||||
private fun passwordAlertDialog(isExporting:Boolean, callback: (CharArray?) -> Unit) {
|
||||
|
||||
private fun passwordAlertDialog(isExporting: Boolean, callback: (CharArray?) -> Unit) {
|
||||
val password = CharArray(16).apply { fill('0') }
|
||||
|
||||
// Inflate the dialog layout
|
||||
|
|
|
@ -3,8 +3,6 @@ package ani.dantotsu.settings
|
|||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import java.util.*
|
||||
import kotlin.concurrent.schedule
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -27,9 +25,11 @@ import ani.dantotsu.offline.OfflineFragment
|
|||
import ani.dantotsu.openLinkInBrowser
|
||||
import ani.dantotsu.others.imagesearch.ImageSearchActivity
|
||||
import ani.dantotsu.setSafeOnClickListener
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.startMainActivity
|
||||
import java.util.Timer
|
||||
import kotlin.concurrent.schedule
|
||||
|
||||
class SettingsDialogFragment : BottomSheetDialogFragment() {
|
||||
private var _binding: BottomSheetSettingsBinding? = null
|
||||
|
@ -103,58 +103,58 @@ class SettingsDialogFragment : BottomSheetDialogFragment() {
|
|||
|
||||
binding.settingsDownloads.isChecked = PrefManager.getVal(PrefName.OfflineMode)
|
||||
binding.settingsDownloads.setOnCheckedChangeListener { _, isChecked ->
|
||||
Timer().schedule(300){
|
||||
when (pageType) {
|
||||
PageType.MANGA -> {
|
||||
val intent = Intent(activity, NoInternet::class.java)
|
||||
intent.putExtra(
|
||||
"FRAGMENT_CLASS_NAME",
|
||||
OfflineMangaFragment::class.java.name
|
||||
)
|
||||
startActivity(intent)
|
||||
Timer().schedule(300) {
|
||||
when (pageType) {
|
||||
PageType.MANGA -> {
|
||||
val intent = Intent(activity, NoInternet::class.java)
|
||||
intent.putExtra(
|
||||
"FRAGMENT_CLASS_NAME",
|
||||
OfflineMangaFragment::class.java.name
|
||||
)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
PageType.ANIME -> {
|
||||
val intent = Intent(activity, NoInternet::class.java)
|
||||
intent.putExtra(
|
||||
"FRAGMENT_CLASS_NAME",
|
||||
OfflineAnimeFragment::class.java.name
|
||||
)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
PageType.HOME -> {
|
||||
val intent = Intent(activity, NoInternet::class.java)
|
||||
intent.putExtra("FRAGMENT_CLASS_NAME", OfflineFragment::class.java.name)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
PageType.OfflineMANGA -> {
|
||||
val intent = Intent(activity, MainActivity::class.java)
|
||||
intent.putExtra("FRAGMENT_CLASS_NAME", MangaFragment::class.java.name)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
PageType.OfflineHOME -> {
|
||||
val intent = Intent(activity, MainActivity::class.java)
|
||||
intent.putExtra(
|
||||
"FRAGMENT_CLASS_NAME",
|
||||
if (Anilist.token != null) HomeFragment::class.java.name else LoginFragment::class.java.name
|
||||
)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
PageType.OfflineANIME -> {
|
||||
val intent = Intent(activity, MainActivity::class.java)
|
||||
intent.putExtra("FRAGMENT_CLASS_NAME", AnimeFragment::class.java.name)
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
PageType.ANIME -> {
|
||||
val intent = Intent(activity, NoInternet::class.java)
|
||||
intent.putExtra(
|
||||
"FRAGMENT_CLASS_NAME",
|
||||
OfflineAnimeFragment::class.java.name
|
||||
)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
PageType.HOME -> {
|
||||
val intent = Intent(activity, NoInternet::class.java)
|
||||
intent.putExtra("FRAGMENT_CLASS_NAME", OfflineFragment::class.java.name)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
PageType.OfflineMANGA -> {
|
||||
val intent = Intent(activity, MainActivity::class.java)
|
||||
intent.putExtra("FRAGMENT_CLASS_NAME", MangaFragment::class.java.name)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
PageType.OfflineHOME -> {
|
||||
val intent = Intent(activity, MainActivity::class.java)
|
||||
intent.putExtra(
|
||||
"FRAGMENT_CLASS_NAME",
|
||||
if (Anilist.token != null) HomeFragment::class.java.name else LoginFragment::class.java.name
|
||||
)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
PageType.OfflineANIME -> {
|
||||
val intent = Intent(activity, MainActivity::class.java)
|
||||
intent.putExtra("FRAGMENT_CLASS_NAME", AnimeFragment::class.java.name)
|
||||
startActivity(intent)
|
||||
}
|
||||
dismiss()
|
||||
PrefManager.setVal(PrefName.OfflineMode, isChecked)
|
||||
}
|
||||
|
||||
dismiss()
|
||||
PrefManager.setVal(PrefName.OfflineMode, isChecked)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
|
|
@ -10,8 +10,8 @@ import ani.dantotsu.R
|
|||
import ani.dantotsu.databinding.ActivityUserInterfaceSettingsBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
|
@ -21,7 +21,7 @@ class UserInterfaceSettingsActivity : AppCompatActivity() {
|
|||
private val ui = "ui_settings"
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
||||
ThemeManager(this).applyTheme()
|
||||
binding = ActivityUserInterfaceSettingsBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
@ -44,7 +44,8 @@ class UserInterfaceSettingsActivity : AppCompatActivity() {
|
|||
views,
|
||||
PrefManager.getVal<List<Boolean>>(PrefName.HomeLayoutShow).toBooleanArray()
|
||||
) { _, i, value ->
|
||||
val set = PrefManager.getVal<List<Boolean>>(PrefName.HomeLayoutShow).toMutableList()
|
||||
val set = PrefManager.getVal<List<Boolean>>(PrefName.HomeLayoutShow)
|
||||
.toMutableList()
|
||||
set[i] = value
|
||||
PrefManager.setVal(PrefName.HomeLayoutShow, set)
|
||||
}
|
||||
|
@ -87,7 +88,8 @@ class UserInterfaceSettingsActivity : AppCompatActivity() {
|
|||
0f to 0f
|
||||
)
|
||||
val mapReverse = map.map { it.value to it.key }.toMap()
|
||||
binding.uiSettingsAnimationSpeed.value = mapReverse[PrefManager.getVal(PrefName.AnimationSpeed)] ?: 1f
|
||||
binding.uiSettingsAnimationSpeed.value =
|
||||
mapReverse[PrefManager.getVal(PrefName.AnimationSpeed)] ?: 1f
|
||||
binding.uiSettingsAnimationSpeed.addOnChangeListener { _, value, _ ->
|
||||
PrefManager.setVal(PrefName.AnimationSpeed, map[value] ?: 1f)
|
||||
restartApp()
|
||||
|
|
|
@ -20,8 +20,8 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.ItemExtensionAllBinding
|
||||
import ani.dantotsu.others.LanguageMapper
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import com.bumptech.glide.Glide
|
||||
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||
|
@ -103,7 +103,8 @@ class AnimeExtensionPagingSource(
|
|||
availableExtensions.filter { it.name.contains(query, ignoreCase = true) }
|
||||
}
|
||||
val lang: String = PrefManager.getVal(PrefName.LangSort)
|
||||
val langFilter = if (lang != "all") filteredExtensions.filter { it.lang == lang } else filteredExtensions
|
||||
val langFilter =
|
||||
if (lang != "all") filteredExtensions.filter { it.lang == lang } else filteredExtensions
|
||||
val filternfsw = if (isNsfwEnabled) langFilter else langFilter.filterNot { it.isNsfw }
|
||||
return try {
|
||||
val sublist = filternfsw.subList(
|
||||
|
|
|
@ -20,8 +20,8 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.ItemExtensionAllBinding
|
||||
import ani.dantotsu.others.LanguageMapper
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import com.bumptech.glide.Glide
|
||||
import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
||||
|
@ -102,7 +102,8 @@ class MangaExtensionPagingSource(
|
|||
availableExtensions.filter { it.name.contains(query, ignoreCase = true) }
|
||||
}
|
||||
val lang: String = PrefManager.getVal(PrefName.LangSort)
|
||||
val langFilter = if (lang != "all") filteredExtensions.filter { it.lang == lang } else filteredExtensions
|
||||
val langFilter =
|
||||
if (lang != "all") filteredExtensions.filter { it.lang == lang } else filteredExtensions
|
||||
val filternfsw = if (isNsfwEnabled) langFilter else langFilter.filterNot { it.isNsfw }
|
||||
return try {
|
||||
val sublist = filternfsw.subList(
|
||||
|
|
|
@ -21,8 +21,8 @@ import ani.dantotsu.databinding.ItemExtensionAllBinding
|
|||
import ani.dantotsu.others.LanguageMapper
|
||||
import ani.dantotsu.parsers.novel.NovelExtension
|
||||
import ani.dantotsu.parsers.novel.NovelExtensionManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import com.bumptech.glide.Glide
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
|
@ -22,12 +22,18 @@ object PrefManager {
|
|||
private var protectedPreferences: SharedPreferences? = null
|
||||
|
||||
fun init(context: Context) { //must be called in Application class or will crash
|
||||
generalPreferences = context.getSharedPreferences(Location.General.location, Context.MODE_PRIVATE)
|
||||
playerPreferences = context.getSharedPreferences(Location.Player.location, Context.MODE_PRIVATE)
|
||||
readerPreferences = context.getSharedPreferences(Location.Reader.location, Context.MODE_PRIVATE)
|
||||
irrelevantPreferences = context.getSharedPreferences(Location.Irrelevant.location, Context.MODE_PRIVATE)
|
||||
animeDownloadsPreferences = context.getSharedPreferences(Location.AnimeDownloads.location, Context.MODE_PRIVATE)
|
||||
protectedPreferences = context.getSharedPreferences(Location.Protected.location, Context.MODE_PRIVATE)
|
||||
generalPreferences =
|
||||
context.getSharedPreferences(Location.General.location, Context.MODE_PRIVATE)
|
||||
playerPreferences =
|
||||
context.getSharedPreferences(Location.Player.location, Context.MODE_PRIVATE)
|
||||
readerPreferences =
|
||||
context.getSharedPreferences(Location.Reader.location, Context.MODE_PRIVATE)
|
||||
irrelevantPreferences =
|
||||
context.getSharedPreferences(Location.Irrelevant.location, Context.MODE_PRIVATE)
|
||||
animeDownloadsPreferences =
|
||||
context.getSharedPreferences(Location.AnimeDownloads.location, Context.MODE_PRIVATE)
|
||||
protectedPreferences =
|
||||
context.getSharedPreferences(Location.Protected.location, Context.MODE_PRIVATE)
|
||||
Compat.importOldPrefs(context)
|
||||
}
|
||||
|
||||
|
@ -49,7 +55,7 @@ object PrefManager {
|
|||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getVal(prefName: PrefName, default: T) : T {
|
||||
fun <T> getVal(prefName: PrefName, default: T): T {
|
||||
return try {
|
||||
val pref = getPrefLocation(prefName.data.prefLocation)
|
||||
when (prefName.data.type) {
|
||||
|
@ -58,8 +64,17 @@ object PrefManager {
|
|||
Float::class -> pref.getFloat(prefName.name, default as Float) as T
|
||||
Long::class -> pref.getLong(prefName.name, default as Long) as T
|
||||
String::class -> pref.getString(prefName.name, default as String?) as T
|
||||
Set::class -> convertFromStringSet(pref.getStringSet(prefName.name, null), default) as T
|
||||
List::class -> deserializeClass(prefName.name, default, prefName.data.prefLocation) as T
|
||||
Set::class -> convertFromStringSet(
|
||||
pref.getStringSet(prefName.name, null),
|
||||
default
|
||||
) as T
|
||||
|
||||
List::class -> deserializeClass(
|
||||
prefName.name,
|
||||
default,
|
||||
prefName.data.prefLocation
|
||||
) as T
|
||||
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -68,17 +83,34 @@ object PrefManager {
|
|||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getVal(prefName: PrefName) : T {
|
||||
fun <T> getVal(prefName: PrefName): T {
|
||||
return try {
|
||||
val pref = getPrefLocation(prefName.data.prefLocation)
|
||||
when (prefName.data.type) {
|
||||
Boolean::class -> pref.getBoolean(prefName.name, prefName.data.default as Boolean) as T
|
||||
Boolean::class -> pref.getBoolean(
|
||||
prefName.name,
|
||||
prefName.data.default as Boolean
|
||||
) as T
|
||||
|
||||
Int::class -> pref.getInt(prefName.name, prefName.data.default as Int) as T
|
||||
Float::class -> pref.getFloat(prefName.name, prefName.data.default as Float) as T
|
||||
Long::class -> pref.getLong(prefName.name, prefName.data.default as Long) as T
|
||||
String::class -> pref.getString(prefName.name, prefName.data.default as String?) as T
|
||||
Set::class -> convertFromStringSet(pref.getStringSet(prefName.name, null), prefName.data.default) as T
|
||||
List::class -> deserializeClass(prefName.name, prefName.data.default, prefName.data.prefLocation) as T
|
||||
String::class -> pref.getString(
|
||||
prefName.name,
|
||||
prefName.data.default as String?
|
||||
) as T
|
||||
|
||||
Set::class -> convertFromStringSet(
|
||||
pref.getStringSet(prefName.name, null),
|
||||
prefName.data.default
|
||||
) as T
|
||||
|
||||
List::class -> deserializeClass(
|
||||
prefName.name,
|
||||
prefName.data.default,
|
||||
prefName.data.prefLocation
|
||||
) as T
|
||||
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -87,7 +119,10 @@ object PrefManager {
|
|||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getNullableVal(prefName: PrefName, default: T?) : T? { //Strings don't necessarily need to use this one
|
||||
fun <T> getNullableVal(
|
||||
prefName: PrefName,
|
||||
default: T?
|
||||
): T? { //Strings don't necessarily need to use this one
|
||||
return try {
|
||||
val pref = getPrefLocation(prefName.data.prefLocation)
|
||||
when (prefName.data.type) {
|
||||
|
@ -96,7 +131,11 @@ object PrefManager {
|
|||
Float::class -> pref.getFloat(prefName.name, default as Float) as T?
|
||||
Long::class -> pref.getLong(prefName.name, default as Long) as T?
|
||||
String::class -> pref.getString(prefName.name, default as String?) as T?
|
||||
Set::class -> convertFromStringSet(pref.getStringSet(prefName.name, null), default) as T?
|
||||
Set::class -> convertFromStringSet(
|
||||
pref.getStringSet(prefName.name, null),
|
||||
default
|
||||
) as T?
|
||||
|
||||
else -> deserializeClass(prefName.name, default, prefName.data.prefLocation)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -113,7 +152,11 @@ object PrefManager {
|
|||
is Float -> irrelevantPreferences!!.getFloat(key, default) as T
|
||||
is Long -> irrelevantPreferences!!.getLong(key, default) as T
|
||||
is String -> irrelevantPreferences!!.getString(key, default) as T
|
||||
is Set<*> -> convertFromStringSet(irrelevantPreferences!!.getStringSet(key, null), default) as T
|
||||
is Set<*> -> convertFromStringSet(
|
||||
irrelevantPreferences!!.getStringSet(key, null),
|
||||
default
|
||||
) as T
|
||||
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -125,12 +168,36 @@ object PrefManager {
|
|||
fun <T> getNullableCustomVal(key: String, default: T?, clazz: Class<T>): T? {
|
||||
return try {
|
||||
when {
|
||||
clazz.isAssignableFrom(Boolean::class.java) -> irrelevantPreferences!!.getBoolean(key, default as? Boolean ?: false) as T?
|
||||
clazz.isAssignableFrom(Int::class.java) -> irrelevantPreferences!!.getInt(key, default as? Int ?: 0) as T?
|
||||
clazz.isAssignableFrom(Float::class.java) -> irrelevantPreferences!!.getFloat(key, default as? Float ?: 0f) as T?
|
||||
clazz.isAssignableFrom(Long::class.java) -> irrelevantPreferences!!.getLong(key, default as? Long ?: 0L) as T?
|
||||
clazz.isAssignableFrom(String::class.java) -> irrelevantPreferences!!.getString(key, default as? String) as T?
|
||||
clazz.isAssignableFrom(Set::class.java) -> convertFromStringSet(irrelevantPreferences!!.getStringSet(key, null), default) as T?
|
||||
clazz.isAssignableFrom(Boolean::class.java) -> irrelevantPreferences!!.getBoolean(
|
||||
key,
|
||||
default as? Boolean ?: false
|
||||
) as T?
|
||||
|
||||
clazz.isAssignableFrom(Int::class.java) -> irrelevantPreferences!!.getInt(
|
||||
key,
|
||||
default as? Int ?: 0
|
||||
) as T?
|
||||
|
||||
clazz.isAssignableFrom(Float::class.java) -> irrelevantPreferences!!.getFloat(
|
||||
key,
|
||||
default as? Float ?: 0f
|
||||
) as T?
|
||||
|
||||
clazz.isAssignableFrom(Long::class.java) -> irrelevantPreferences!!.getLong(
|
||||
key,
|
||||
default as? Long ?: 0L
|
||||
) as T?
|
||||
|
||||
clazz.isAssignableFrom(String::class.java) -> irrelevantPreferences!!.getString(
|
||||
key,
|
||||
default as? String
|
||||
) as T?
|
||||
|
||||
clazz.isAssignableFrom(Set::class.java) -> convertFromStringSet(
|
||||
irrelevantPreferences!!.getStringSet(key, null),
|
||||
default
|
||||
) as T?
|
||||
|
||||
else -> deserializeClass(key, default, Location.Irrelevant)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -173,7 +240,7 @@ object PrefManager {
|
|||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getLiveVal(prefName: PrefName, default: T) : SharedPreferenceLiveData<T> {
|
||||
fun <T> getLiveVal(prefName: PrefName, default: T): SharedPreferenceLiveData<T> {
|
||||
val pref = getPrefLocation(prefName.data.prefLocation)
|
||||
return when (prefName.data.type) {
|
||||
Boolean::class -> SharedPreferenceBooleanLiveData(
|
||||
|
@ -181,31 +248,37 @@ object PrefManager {
|
|||
prefName.name,
|
||||
default as Boolean
|
||||
) as SharedPreferenceLiveData<T>
|
||||
|
||||
Int::class -> SharedPreferenceIntLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Int
|
||||
) as SharedPreferenceLiveData<T>
|
||||
|
||||
Float::class -> SharedPreferenceFloatLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Float
|
||||
) as SharedPreferenceLiveData<T>
|
||||
|
||||
Long::class -> SharedPreferenceLongLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Long
|
||||
) as SharedPreferenceLiveData<T>
|
||||
|
||||
String::class -> SharedPreferenceStringLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as String
|
||||
) as SharedPreferenceLiveData<T>
|
||||
|
||||
Set::class -> SharedPreferenceStringSetLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Set<String>
|
||||
) as SharedPreferenceLiveData<T>
|
||||
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +307,8 @@ object PrefManager {
|
|||
this as? SharedPreferenceStringSetLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<Set<String>>")
|
||||
|
||||
fun getAnimeDownloadPreferences(): SharedPreferences = animeDownloadsPreferences!! //needs to be used externally
|
||||
fun getAnimeDownloadPreferences(): SharedPreferences =
|
||||
animeDownloadsPreferences!! //needs to be used externally
|
||||
|
||||
fun exportAllPrefs(prefLocation: List<Location>): String {
|
||||
return PreferencePackager.pack(
|
||||
|
@ -272,7 +346,7 @@ object PrefManager {
|
|||
return if (hadError) {
|
||||
snackString("Error importing preferences")
|
||||
false
|
||||
} else {
|
||||
} else {
|
||||
snackString("Preferences imported")
|
||||
true
|
||||
}
|
||||
|
@ -331,7 +405,7 @@ object PrefManager {
|
|||
}
|
||||
|
||||
|
||||
private fun <T> serializeClass(key: String, value: T, location: Location){
|
||||
private fun <T> serializeClass(key: String, value: T, location: Location) {
|
||||
val pref = getPrefLocation(location)
|
||||
try {
|
||||
val bos = ByteArrayOutputStream()
|
||||
|
|
|
@ -2,8 +2,8 @@ package ani.dantotsu.settings.saving
|
|||
|
||||
import android.graphics.Color
|
||||
import ani.dantotsu.connections.mal.MAL
|
||||
import ani.dantotsu.settings.saving.internal.Pref
|
||||
import ani.dantotsu.settings.saving.internal.Location
|
||||
import ani.dantotsu.settings.saving.internal.Pref
|
||||
|
||||
enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
|
||||
//General
|
||||
|
@ -20,7 +20,13 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
|
|||
CheckUpdate(Pref(Location.General, Boolean::class, true)),
|
||||
VerboseLogging(Pref(Location.General, Boolean::class, false)),
|
||||
DohProvider(Pref(Location.General, Int::class, 0)),
|
||||
DefaultUserAgent(Pref(Location.General, String::class, "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:110.0) Gecko/20100101 Firefox/110.0")),
|
||||
DefaultUserAgent(
|
||||
Pref(
|
||||
Location.General,
|
||||
String::class,
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:110.0) Gecko/20100101 Firefox/110.0"
|
||||
)
|
||||
),
|
||||
AnimeSourcesOrder(Pref(Location.General, List::class, listOf<String>())),
|
||||
AnimeSearchHistory(Pref(Location.General, Set::class, setOf<String>())),
|
||||
MangaSourcesOrder(Pref(Location.General, List::class, listOf<String>())),
|
||||
|
@ -42,7 +48,13 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
|
|||
ImmersiveMode(Pref(Location.UI, Boolean::class, false)),
|
||||
SmallView(Pref(Location.UI, Boolean::class, true)),
|
||||
DefaultStartUpTab(Pref(Location.UI, Int::class, 1)),
|
||||
HomeLayoutShow(Pref(Location.UI, List::class, listOf(true, false, false, true, false, false, true))),
|
||||
HomeLayoutShow(
|
||||
Pref(
|
||||
Location.UI,
|
||||
List::class,
|
||||
listOf(true, false, false, true, false, false, true)
|
||||
)
|
||||
),
|
||||
BannerAnimations(Pref(Location.UI, Boolean::class, true)),
|
||||
LayoutAnimations(Pref(Location.UI, Boolean::class, true)),
|
||||
AnimationSpeed(Pref(Location.UI, Float::class, 1f)),
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package ani.dantotsu.settings.saving.internal
|
||||
|
||||
import android.content.Context
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
|
||||
class Compat {
|
||||
companion object {
|
||||
|
|
|
@ -8,6 +8,7 @@ data class Pref(
|
|||
val type: KClass<*>,
|
||||
val default: Any
|
||||
)
|
||||
|
||||
enum class Location(val location: String, val exportable: Boolean) {
|
||||
General("ani.dantotsu.general", true),
|
||||
UI("ani.dantotsu.ui", true),
|
||||
|
|
|
@ -2,7 +2,6 @@ package ani.dantotsu.settings.saving.internal
|
|||
|
||||
import android.security.keystore.KeyGenParameterSpec
|
||||
import android.security.keystore.KeyProperties
|
||||
import java.security.KeyStore
|
||||
import java.security.SecureRandom
|
||||
import javax.crypto.Cipher
|
||||
import javax.crypto.KeyGenerator
|
||||
|
@ -15,7 +14,8 @@ import javax.crypto.spec.PBEKeySpec
|
|||
class PreferenceKeystore {
|
||||
companion object {
|
||||
fun generateKey(alias: String) {
|
||||
val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
|
||||
val keyGenerator =
|
||||
KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
|
||||
|
||||
keyGenerator.init(
|
||||
KeyGenParameterSpec.Builder(
|
||||
|
@ -30,17 +30,31 @@ class PreferenceKeystore {
|
|||
keyGenerator.generateKey()
|
||||
}
|
||||
|
||||
fun encryptWithPassword(password: CharArray, plaintext: String, salt: ByteArray): ByteArray {
|
||||
fun encryptWithPassword(
|
||||
password: CharArray,
|
||||
plaintext: String,
|
||||
salt: ByteArray
|
||||
): ByteArray {
|
||||
val secretKey = deriveKeyFromPassword(password, salt)
|
||||
val cipher = Cipher.getInstance("${KeyProperties.KEY_ALGORITHM_AES}/${KeyProperties.BLOCK_MODE_CBC}/${KeyProperties.ENCRYPTION_PADDING_PKCS7}")
|
||||
val cipher =
|
||||
Cipher.getInstance("${KeyProperties.KEY_ALGORITHM_AES}/${KeyProperties.BLOCK_MODE_CBC}/${KeyProperties.ENCRYPTION_PADDING_PKCS7}")
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey, IvParameterSpec(ByteArray(16)))
|
||||
return cipher.doFinal(plaintext.toByteArray(Charsets.UTF_8))
|
||||
}
|
||||
|
||||
fun decryptWithPassword(password: CharArray, ciphertext: ByteArray, salt: ByteArray): String {
|
||||
fun decryptWithPassword(
|
||||
password: CharArray,
|
||||
ciphertext: ByteArray,
|
||||
salt: ByteArray
|
||||
): String {
|
||||
val secretKey = deriveKeyFromPassword(password, salt)
|
||||
val cipher = Cipher.getInstance("${KeyProperties.KEY_ALGORITHM_AES}/${KeyProperties.BLOCK_MODE_CBC}/${KeyProperties.ENCRYPTION_PADDING_PKCS7}")
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, IvParameterSpec(ByteArray(16))) // Use the correct IV
|
||||
val cipher =
|
||||
Cipher.getInstance("${KeyProperties.KEY_ALGORITHM_AES}/${KeyProperties.BLOCK_MODE_CBC}/${KeyProperties.ENCRYPTION_PADDING_PKCS7}")
|
||||
cipher.init(
|
||||
Cipher.DECRYPT_MODE,
|
||||
secretKey,
|
||||
IvParameterSpec(ByteArray(16))
|
||||
) // Use the correct IV
|
||||
return cipher.doFinal(ciphertext).toString(Charsets.UTF_8)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
package ani.dantotsu.settings.saving.internal
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import ani.dantotsu.connections.discord.serializers.Activity
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.toast
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
|
||||
|
@ -28,8 +24,10 @@ class PreferencePackager {
|
|||
*/
|
||||
fun unpack(decryptedJson: String): Boolean {
|
||||
val gson = Gson()
|
||||
val type = object : TypeToken<Map<String, Map<String, Map<String, Any>>>>() {}.type //oh god...
|
||||
val rawPrefsMap: Map<String, Map<String, Map<String, Any>>> = gson.fromJson(decryptedJson, type)
|
||||
val type = object :
|
||||
TypeToken<Map<String, Map<String, Map<String, Any>>>>() {}.type //oh god...
|
||||
val rawPrefsMap: Map<String, Map<String, Map<String, Any>>> =
|
||||
gson.fromJson(decryptedJson, type)
|
||||
|
||||
|
||||
val deserializedMap = mutableMapOf<String, Map<String, Any?>>()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue