2022-05-11 01:35:15 +05:30
|
|
|
package com.github.libretube
|
|
|
|
|
|
|
|
import android.Manifest
|
2022-06-01 11:32:16 +05:30
|
|
|
import android.app.NotificationManager
|
2022-05-24 00:56:11 +05:30
|
|
|
import android.content.ContentResolver
|
|
|
|
import android.content.Context
|
|
|
|
import android.content.DialogInterface
|
|
|
|
import android.content.Intent
|
|
|
|
import android.content.SharedPreferences
|
2022-05-11 01:35:15 +05:30
|
|
|
import android.content.pm.PackageManager
|
|
|
|
import android.net.Uri
|
|
|
|
import android.os.Build
|
|
|
|
import android.os.Bundle
|
2022-05-17 02:02:32 +05:30
|
|
|
import android.text.Html
|
2022-05-11 01:35:15 +05:30
|
|
|
import android.text.TextUtils
|
|
|
|
import android.util.Log
|
2022-05-11 13:34:48 +05:30
|
|
|
import android.view.View
|
2022-05-11 01:35:15 +05:30
|
|
|
import android.widget.Toast
|
|
|
|
import androidx.activity.result.ActivityResultLauncher
|
|
|
|
import androidx.activity.result.contract.ActivityResultContracts
|
|
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
|
|
import androidx.core.app.ActivityCompat
|
|
|
|
import androidx.core.content.ContextCompat
|
|
|
|
import androidx.fragment.app.Fragment
|
|
|
|
import androidx.lifecycle.lifecycleScope
|
|
|
|
import androidx.preference.ListPreference
|
|
|
|
import androidx.preference.Preference
|
|
|
|
import androidx.preference.PreferenceFragmentCompat
|
|
|
|
import androidx.preference.PreferenceManager
|
2022-05-20 20:03:29 +05:30
|
|
|
import com.google.android.material.color.DynamicColors
|
2022-05-20 19:05:05 +05:30
|
|
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
2022-06-02 21:37:09 +05:30
|
|
|
import org.json.JSONObject
|
|
|
|
import org.json.JSONTokener
|
|
|
|
import retrofit2.HttpException
|
2022-05-11 01:35:15 +05:30
|
|
|
import java.io.IOException
|
|
|
|
import java.io.InputStream
|
|
|
|
import java.util.zip.ZipEntry
|
|
|
|
import java.util.zip.ZipInputStream
|
2022-05-24 00:04:18 +05:30
|
|
|
|
2022-05-22 15:28:27 +05:30
|
|
|
private var isCurrentViewMainSettings = true
|
2022-05-31 01:49:42 +05:30
|
|
|
private var requireMainActivityRestart = false
|
2022-05-22 15:28:27 +05:30
|
|
|
|
2022-05-20 03:23:55 +05:30
|
|
|
class SettingsActivity :
|
|
|
|
AppCompatActivity(),
|
|
|
|
SharedPreferences.OnSharedPreferenceChangeListener {
|
2022-05-31 01:53:44 +05:30
|
|
|
|
2022-05-11 01:35:15 +05:30
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
2022-05-20 03:43:02 +05:30
|
|
|
DynamicColors.applyToActivityIfAvailable(this)
|
2022-05-20 03:11:21 +05:30
|
|
|
updateAccentColor(this)
|
|
|
|
updateThemeMode(this)
|
|
|
|
|
2022-05-11 01:35:15 +05:30
|
|
|
super.onCreate(savedInstanceState)
|
2022-05-13 22:25:15 +05:30
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
2022-05-19 21:52:19 +05:30
|
|
|
overridePendingTransition(50, 50)
|
2022-05-13 22:25:15 +05:30
|
|
|
}
|
2022-05-11 13:34:48 +05:30
|
|
|
val view = this.findViewById<View>(android.R.id.content)
|
2022-05-20 03:39:47 +05:30
|
|
|
view.alpha = 0F
|
|
|
|
view.animate().alpha(1F).duration = 300
|
2022-05-19 21:52:19 +05:30
|
|
|
|
2022-05-11 01:35:15 +05:30
|
|
|
setContentView(R.layout.activity_settings)
|
|
|
|
if (savedInstanceState == null) {
|
|
|
|
supportFragmentManager
|
|
|
|
.beginTransaction()
|
|
|
|
.replace(R.id.settings, SettingsFragment())
|
|
|
|
.commit()
|
|
|
|
}
|
|
|
|
|
|
|
|
PreferenceManager.getDefaultSharedPreferences(this)
|
|
|
|
.registerOnSharedPreferenceChangeListener(this)
|
|
|
|
}
|
|
|
|
|
2022-05-21 13:32:04 +05:30
|
|
|
override fun onSharedPreferenceChanged(
|
|
|
|
sharedPreferences: SharedPreferences?,
|
|
|
|
rootKey: String?
|
|
|
|
) {
|
|
|
|
}
|
2022-05-11 01:35:15 +05:30
|
|
|
|
|
|
|
class SettingsFragment : PreferenceFragmentCompat() {
|
|
|
|
val TAG = "Settings"
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
lateinit var getContent: ActivityResultLauncher<String>
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
2022-05-21 13:32:04 +05:30
|
|
|
getContent =
|
|
|
|
registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
|
|
|
|
if (uri != null) {
|
|
|
|
try {
|
|
|
|
// Open a specific media item using ParcelFileDescriptor.
|
|
|
|
val resolver: ContentResolver =
|
|
|
|
requireActivity()
|
|
|
|
.contentResolver
|
2022-05-11 01:35:15 +05:30
|
|
|
|
2022-05-21 13:32:04 +05:30
|
|
|
// "rw" for read-and-write;
|
|
|
|
// "rwt" for truncating or overwriting existing file contents.
|
|
|
|
// val readOnlyMode = "r"
|
|
|
|
// uri - I have got from onActivityResult
|
|
|
|
val type = resolver.getType(uri)
|
2022-05-11 01:35:15 +05:30
|
|
|
|
2022-05-21 13:32:04 +05:30
|
|
|
var inputStream: InputStream? = resolver.openInputStream(uri)
|
|
|
|
val channels = ArrayList<String>()
|
|
|
|
if (type == "application/json") {
|
|
|
|
val json = inputStream?.bufferedReader()?.readLines()?.get(0)
|
|
|
|
val jsonObject = JSONTokener(json).nextValue() as JSONObject
|
|
|
|
Log.e(TAG, jsonObject.getJSONArray("subscriptions").toString())
|
|
|
|
for (
|
|
|
|
i in 0 until jsonObject.getJSONArray("subscriptions")
|
|
|
|
.length()
|
|
|
|
) {
|
|
|
|
var url =
|
|
|
|
jsonObject.getJSONArray("subscriptions").getJSONObject(i)
|
|
|
|
.getString("url")
|
|
|
|
url = url.replace("https://www.youtube.com/channel/", "")
|
|
|
|
Log.e(TAG, url)
|
|
|
|
channels.add(url)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (type == "application/zip") {
|
|
|
|
val zis = ZipInputStream(inputStream)
|
|
|
|
var entry: ZipEntry? = zis.nextEntry
|
|
|
|
while (entry != null) {
|
|
|
|
if (entry.name.endsWith(".csv")) {
|
|
|
|
inputStream = zis
|
|
|
|
break
|
|
|
|
}
|
|
|
|
entry = zis.nextEntry
|
2022-05-11 01:35:15 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-21 13:32:04 +05:30
|
|
|
inputStream?.bufferedReader()?.readLines()?.forEach {
|
|
|
|
if (it.isNotBlank()) {
|
|
|
|
val channelId = it.substringBefore(",")
|
|
|
|
if (channelId.length == 24)
|
|
|
|
channels.add(channelId)
|
|
|
|
}
|
2022-05-11 01:35:15 +05:30
|
|
|
}
|
|
|
|
}
|
2022-05-21 13:32:04 +05:30
|
|
|
inputStream?.close()
|
2022-05-11 01:35:15 +05:30
|
|
|
|
2022-05-21 13:32:04 +05:30
|
|
|
subscribe(channels)
|
|
|
|
} catch (e: Exception) {
|
|
|
|
Log.e(TAG, e.toString())
|
|
|
|
Toast.makeText(
|
|
|
|
context,
|
|
|
|
R.string.error,
|
|
|
|
Toast.LENGTH_SHORT
|
|
|
|
).show()
|
|
|
|
}
|
2022-05-11 01:35:15 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
super.onCreate(savedInstanceState)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
|
|
setPreferencesFromResource(R.xml.settings, rootKey)
|
|
|
|
val instance = findPreference<ListPreference>("instance")
|
|
|
|
fetchInstance()
|
|
|
|
instance?.setOnPreferenceChangeListener { _, newValue ->
|
|
|
|
RetrofitInstance.url = newValue.toString()
|
|
|
|
RetrofitInstance.lazyMgr.reset()
|
|
|
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
|
|
|
if (sharedPref?.getString("token", "") != "") {
|
|
|
|
with(sharedPref!!.edit()) {
|
|
|
|
putString("token", "")
|
|
|
|
apply()
|
|
|
|
}
|
|
|
|
Toast.makeText(context, R.string.loggedout, Toast.LENGTH_SHORT).show()
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
val login = findPreference<Preference>("login_register")
|
|
|
|
login?.setOnPreferenceClickListener {
|
2022-06-02 21:37:09 +05:30
|
|
|
requireMainActivityRestart = true
|
2022-05-11 01:35:15 +05:30
|
|
|
val newFragment = LoginDialog()
|
|
|
|
newFragment.show(childFragmentManager, "Login")
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2022-05-16 15:41:22 +05:30
|
|
|
val sponsorblock = findPreference<Preference>("sponsorblock")
|
|
|
|
sponsorblock?.setOnPreferenceClickListener {
|
2022-05-22 15:28:27 +05:30
|
|
|
isCurrentViewMainSettings = false
|
2022-05-16 15:41:22 +05:30
|
|
|
val newFragment = SponsorBlockSettings()
|
2022-05-20 03:23:55 +05:30
|
|
|
parentFragmentManager.beginTransaction()
|
2022-05-16 15:41:22 +05:30
|
|
|
.replace(R.id.settings, newFragment)
|
|
|
|
.commitNow()
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2022-05-11 01:35:15 +05:30
|
|
|
val importFromYt = findPreference<Preference>("import_from_yt")
|
|
|
|
importFromYt?.setOnPreferenceClickListener {
|
|
|
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
|
|
|
val token = sharedPref?.getString("token", "")!!
|
2022-05-20 03:23:55 +05:30
|
|
|
// check StorageAccess
|
2022-05-11 01:35:15 +05:30
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
|
|
Log.d("myz", "" + Build.VERSION.SDK_INT)
|
|
|
|
if (ContextCompat.checkSelfPermission(
|
|
|
|
this.requireContext(),
|
|
|
|
Manifest.permission.READ_EXTERNAL_STORAGE
|
|
|
|
)
|
|
|
|
!= PackageManager.PERMISSION_GRANTED
|
|
|
|
) {
|
|
|
|
ActivityCompat.requestPermissions(
|
2022-05-20 03:23:55 +05:30
|
|
|
this.requireActivity(),
|
|
|
|
arrayOf(
|
2022-05-11 01:35:15 +05:30
|
|
|
Manifest.permission.READ_EXTERNAL_STORAGE,
|
|
|
|
Manifest.permission.MANAGE_EXTERNAL_STORAGE
|
2022-05-20 03:23:55 +05:30
|
|
|
),
|
|
|
|
1
|
|
|
|
) // permission request code is just an int
|
2022-05-11 01:35:15 +05:30
|
|
|
} else if (token != "") {
|
|
|
|
getContent.launch("*/*")
|
|
|
|
} else {
|
|
|
|
Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (ActivityCompat.checkSelfPermission(
|
|
|
|
requireContext(),
|
|
|
|
Manifest.permission.READ_EXTERNAL_STORAGE
|
2022-05-21 13:32:04 +05:30
|
|
|
) != PackageManager.PERMISSION_GRANTED ||
|
|
|
|
ActivityCompat.checkSelfPermission(
|
2022-05-20 03:23:55 +05:30
|
|
|
requireContext(),
|
|
|
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
|
|
|
) != PackageManager.PERMISSION_GRANTED
|
2022-05-11 01:35:15 +05:30
|
|
|
) {
|
|
|
|
ActivityCompat.requestPermissions(
|
|
|
|
this.requireActivity(),
|
|
|
|
arrayOf(
|
|
|
|
Manifest.permission.READ_EXTERNAL_STORAGE,
|
|
|
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
|
|
|
),
|
|
|
|
1
|
|
|
|
)
|
|
|
|
} else if (token != "") {
|
|
|
|
getContent.launch("*/*")
|
|
|
|
} else {
|
|
|
|
Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
val themeToggle = findPreference<ListPreference>("theme_togglee")
|
2022-05-22 15:28:27 +05:30
|
|
|
themeToggle?.setOnPreferenceChangeListener { _, _ ->
|
2022-05-20 03:11:21 +05:30
|
|
|
val refresh = Intent(context, SettingsActivity::class.java)
|
|
|
|
startActivity(refresh)
|
2022-05-31 01:49:42 +05:30
|
|
|
requireMainActivityRestart = true
|
2022-05-11 01:35:15 +05:30
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2022-05-19 21:52:19 +05:30
|
|
|
val accentColor = findPreference<Preference>("accent_color")
|
2022-05-20 03:23:55 +05:30
|
|
|
accentColor?.setOnPreferenceChangeListener { _, _ ->
|
2022-05-31 01:49:42 +05:30
|
|
|
requireMainActivityRestart = true
|
2022-05-19 21:52:19 +05:30
|
|
|
val refresh = Intent(context, SettingsActivity::class.java)
|
|
|
|
startActivity(refresh)
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2022-05-22 23:54:12 +05:30
|
|
|
val iconChange = findPreference<ListPreference>("icon_change")
|
2022-05-23 23:10:02 +05:30
|
|
|
iconChange?.setOnPreferenceChangeListener { _, newValue ->
|
|
|
|
changeIcon(requireContext(), newValue.toString())
|
2022-05-22 23:54:12 +05:30
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2022-05-31 01:49:42 +05:30
|
|
|
val gridColumns = findPreference<ListPreference>("grid")
|
|
|
|
gridColumns?.setOnPreferenceChangeListener { _, _ ->
|
|
|
|
requireMainActivityRestart = true
|
2022-05-11 01:35:15 +05:30
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2022-05-15 19:26:24 +05:30
|
|
|
val clearHistory = findPreference<Preference>("clear_history")
|
|
|
|
clearHistory?.setOnPreferenceClickListener {
|
2022-05-21 13:32:04 +05:30
|
|
|
val sharedPreferences =
|
|
|
|
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
2022-05-15 19:26:24 +05:30
|
|
|
sharedPreferences.edit().remove("search_history").commit()
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2022-05-11 01:35:15 +05:30
|
|
|
val about = findPreference<Preference>("about")
|
|
|
|
about?.setOnPreferenceClickListener {
|
|
|
|
val uri = Uri.parse("https://libre-tube.github.io/")
|
|
|
|
val intent = Intent(Intent.ACTION_VIEW).setData(uri)
|
|
|
|
startActivity(intent)
|
|
|
|
true
|
|
|
|
}
|
2022-05-17 02:02:32 +05:30
|
|
|
|
|
|
|
val license = findPreference<Preference>("license")
|
|
|
|
license?.setOnPreferenceClickListener {
|
2022-05-20 03:23:55 +05:30
|
|
|
val licenseString = view?.context?.assets!!.open("gpl3.html").bufferedReader().use {
|
2022-05-17 02:02:32 +05:30
|
|
|
it.readText()
|
|
|
|
}
|
|
|
|
val licenseHtml = if (Build.VERSION.SDK_INT >= 24) {
|
2022-05-20 03:23:55 +05:30
|
|
|
Html.fromHtml(licenseString, 1)
|
2022-05-17 02:02:32 +05:30
|
|
|
} else {
|
|
|
|
Html.fromHtml(licenseString)
|
|
|
|
}
|
2022-05-20 19:05:05 +05:30
|
|
|
MaterialAlertDialogBuilder(view?.context!!)
|
2022-05-21 13:32:04 +05:30
|
|
|
.setPositiveButton(
|
|
|
|
getString(R.string.okay),
|
|
|
|
DialogInterface.OnClickListener { _, _ -> }
|
|
|
|
)
|
2022-05-17 02:02:32 +05:30
|
|
|
.setMessage(licenseHtml)
|
|
|
|
.create()
|
|
|
|
.show()
|
|
|
|
true
|
|
|
|
}
|
2022-05-11 01:35:15 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
private fun fetchInstance() {
|
|
|
|
lifecycleScope.launchWhenCreated {
|
|
|
|
val response = try {
|
|
|
|
RetrofitInstance.api.getInstances("https://instances.tokhmi.xyz/")
|
|
|
|
} catch (e: IOException) {
|
|
|
|
println(e)
|
|
|
|
Log.e("settings", "IOException, you might not have internet connection")
|
|
|
|
return@launchWhenCreated
|
|
|
|
} catch (e: HttpException) {
|
|
|
|
Log.e("settings", "HttpException, unexpected response $e")
|
|
|
|
return@launchWhenCreated
|
|
|
|
} catch (e: Exception) {
|
|
|
|
Log.e("settings", e.toString())
|
|
|
|
return@launchWhenCreated
|
|
|
|
}
|
|
|
|
val listEntries: MutableList<String> = ArrayList()
|
|
|
|
val listEntryValues: MutableList<String> = ArrayList()
|
|
|
|
for (item in response) {
|
|
|
|
listEntries.add(item.name!!)
|
|
|
|
listEntryValues.add(item.api_url!!)
|
|
|
|
}
|
|
|
|
val entries = listEntries.toTypedArray<CharSequence>()
|
|
|
|
val entryValues = listEntryValues.toTypedArray<CharSequence>()
|
|
|
|
runOnUiThread {
|
|
|
|
val instance = findPreference<ListPreference>("instance")
|
|
|
|
instance?.entries = entries
|
|
|
|
instance?.entryValues = entryValues
|
|
|
|
instance?.summaryProvider =
|
|
|
|
Preference.SummaryProvider<ListPreference> { preference ->
|
|
|
|
val text = preference.entry
|
|
|
|
if (TextUtils.isEmpty(text)) {
|
|
|
|
"kavin.rocks (Official)"
|
|
|
|
} else {
|
|
|
|
text
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
|
|
|
this ?: return
|
|
|
|
if (!isAdded) return // Fragment not attached to an Activity
|
|
|
|
activity?.runOnUiThread(action)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun subscribe(channels: List<String>) {
|
|
|
|
fun run() {
|
|
|
|
lifecycleScope.launchWhenCreated {
|
|
|
|
val response = try {
|
2022-05-21 13:32:04 +05:30
|
|
|
val sharedPref =
|
|
|
|
context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
2022-05-11 01:35:15 +05:30
|
|
|
RetrofitInstance.api.importSubscriptions(
|
|
|
|
false,
|
|
|
|
sharedPref?.getString("token", "")!!,
|
|
|
|
channels
|
|
|
|
)
|
|
|
|
} catch (e: IOException) {
|
|
|
|
Log.e(TAG, "IOException, you might not have internet connection")
|
|
|
|
return@launchWhenCreated
|
|
|
|
} catch (e: HttpException) {
|
|
|
|
Log.e(TAG, "HttpException, unexpected response$e")
|
|
|
|
return@launchWhenCreated
|
|
|
|
}
|
|
|
|
if (response.message == "ok") {
|
|
|
|
Toast.makeText(
|
|
|
|
context,
|
|
|
|
R.string.importsuccess,
|
|
|
|
Toast.LENGTH_SHORT
|
|
|
|
).show()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
run()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-11 13:34:48 +05:30
|
|
|
override fun onBackPressed() {
|
2022-05-22 15:28:27 +05:30
|
|
|
if (isCurrentViewMainSettings) {
|
|
|
|
PreferenceManager.getDefaultSharedPreferences(this)
|
|
|
|
.unregisterOnSharedPreferenceChangeListener(this)
|
2022-05-31 01:49:42 +05:30
|
|
|
if (requireMainActivityRestart) {
|
2022-05-31 11:12:55 +05:30
|
|
|
requireMainActivityRestart = false
|
2022-06-01 11:32:16 +05:30
|
|
|
// kill player notification
|
|
|
|
val nManager = this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
|
|
nManager.cancelAll()
|
2022-05-31 01:49:42 +05:30
|
|
|
restartMainActivity(this)
|
|
|
|
finishAffinity()
|
|
|
|
} else {
|
|
|
|
super.onBackPressed()
|
|
|
|
}
|
|
|
|
finishAndRemoveTask()
|
2022-05-22 15:28:27 +05:30
|
|
|
} else {
|
|
|
|
isCurrentViewMainSettings = true
|
|
|
|
supportFragmentManager
|
|
|
|
.beginTransaction()
|
|
|
|
.replace(R.id.settings, SettingsFragment())
|
|
|
|
.commit()
|
|
|
|
}
|
2022-05-11 01:35:15 +05:30
|
|
|
}
|
2022-05-20 03:23:55 +05:30
|
|
|
}
|