LibreTube/app/src/main/java/com/github/libretube/preferences/InstanceSettings.kt

305 lines
12 KiB
Kotlin
Raw Normal View History

2022-06-11 15:23:09 +05:30
package com.github.libretube.preferences
import android.content.ContentResolver
2022-07-02 01:02:26 +05:30
import android.content.Intent
2022-06-11 15:23:09 +05:30
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.widget.Toast
2022-07-21 20:29:06 +05:30
import androidx.activity.result.ActivityResultLauncher
2022-06-11 15:23:09 +05:30
import androidx.activity.result.contract.ActivityResultContracts
2022-07-21 20:29:06 +05:30
import androidx.appcompat.app.AppCompatActivity
2022-06-11 15:23:09 +05:30
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
2022-07-15 02:02:42 +05:30
import androidx.preference.SwitchPreferenceCompat
2022-06-11 15:23:09 +05:30
import com.github.libretube.R
2022-07-01 20:24:20 +05:30
import com.github.libretube.activities.SettingsActivity
2022-06-11 16:34:33 +05:30
import com.github.libretube.dialogs.CustomInstanceDialog
2022-06-25 21:41:11 +05:30
import com.github.libretube.dialogs.DeleteAccountDialog
2022-06-11 15:23:09 +05:30
import com.github.libretube.dialogs.LoginDialog
2022-07-01 13:49:00 +05:30
import com.github.libretube.dialogs.LogoutDialog
import com.github.libretube.dialogs.RequireRestartDialog
2022-07-21 20:29:06 +05:30
import com.github.libretube.util.PermissionHelper
2022-06-11 15:23:09 +05:30
import com.github.libretube.util.RetrofitInstance
2022-06-24 20:56:36 +05:30
import org.json.JSONObject
import org.json.JSONTokener
import retrofit2.HttpException
2022-06-11 15:23:09 +05:30
import java.io.IOException
import java.io.InputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
class InstanceSettings : PreferenceFragmentCompat() {
val TAG = "InstanceSettings"
2022-07-21 20:29:06 +05:30
companion object {
lateinit var getContent: ActivityResultLauncher<String>
}
2022-06-11 15:23:09 +05:30
override fun onCreate(savedInstanceState: Bundle?) {
2022-07-21 20:29:06 +05:30
getContent =
2022-06-11 15:23:09 +05:30
registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
if (uri != null) {
try {
// Open a specific media item using ParcelFileDescriptor.
val resolver: ContentResolver =
requireActivity()
.contentResolver
// "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)
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 (
2022-07-21 20:29:06 +05:30
i in 0 until jsonObject.getJSONArray("subscriptions")
.length()
2022-06-11 15:23:09 +05:30
) {
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
}
}
inputStream?.bufferedReader()?.readLines()?.forEach {
if (it.isNotBlank()) {
val channelId = it.substringBefore(",")
2022-06-24 20:56:36 +05:30
if (channelId.length == 24) {
2022-06-11 15:23:09 +05:30
channels.add(channelId)
2022-06-24 20:56:36 +05:30
}
2022-06-11 15:23:09 +05:30
}
}
}
inputStream?.close()
subscribe(channels)
} catch (e: Exception) {
Log.e(TAG, e.toString())
Toast.makeText(
context,
R.string.error,
Toast.LENGTH_SHORT
).show()
}
}
}
super.onCreate(savedInstanceState)
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.instance_settings, rootKey)
2022-07-01 13:59:00 +05:30
val settingsActivity = activity as SettingsActivity
2022-07-03 15:43:38 +05:30
settingsActivity.changeTopBarText(getString(R.string.instance))
2022-06-11 15:23:09 +05:30
2022-07-17 21:48:39 +05:30
val instance = findPreference<ListPreference>(PreferenceKeys.FETCH_INSTANCE)
2022-06-11 19:25:25 +05:30
// fetchInstance()
2022-07-03 13:50:53 +05:30
initCustomInstances(instance!!)
instance.setOnPreferenceChangeListener { _, newValue ->
val restartDialog = RequireRestartDialog()
restartDialog.show(childFragmentManager, "RequireRestartDialog")
2022-06-11 15:23:09 +05:30
RetrofitInstance.url = newValue.toString()
2022-07-17 21:48:39 +05:30
if (!PreferenceHelper.getBoolean(PreferenceKeys.AUTH_INSTANCE_TOGGLE, false)) {
2022-07-03 13:50:53 +05:30
RetrofitInstance.authUrl = newValue.toString()
logout()
}
RetrofitInstance.lazyMgr.reset()
true
}
2022-07-17 21:48:39 +05:30
val authInstance = findPreference<ListPreference>(PreferenceKeys.AUTH_INSTANCE)
2022-07-03 13:50:53 +05:30
initCustomInstances(authInstance!!)
// hide auth instance if option deselected
2022-07-17 21:48:39 +05:30
if (!PreferenceHelper.getBoolean(PreferenceKeys.AUTH_INSTANCE_TOGGLE, false)) {
2022-07-03 13:50:53 +05:30
authInstance.isVisible = false
}
authInstance.setOnPreferenceChangeListener { _, newValue ->
2022-07-03 15:09:25 +05:30
// save new auth url
RetrofitInstance.authUrl = newValue.toString()
2022-06-11 15:23:09 +05:30
RetrofitInstance.lazyMgr.reset()
2022-06-11 16:34:33 +05:30
logout()
val restartDialog = RequireRestartDialog()
restartDialog.show(childFragmentManager, "RequireRestartDialog")
2022-06-11 16:34:33 +05:30
true
}
2022-07-18 23:06:21 +05:30
val authInstanceToggle =
findPreference<SwitchPreferenceCompat>(PreferenceKeys.AUTH_INSTANCE_TOGGLE)
2022-07-03 13:50:53 +05:30
authInstanceToggle?.setOnPreferenceChangeListener { _, newValue ->
authInstance.isVisible = newValue == true
logout()
2022-07-03 15:09:25 +05:30
// either use new auth url or the normal api url if auth instance disabled
2022-07-03 13:50:53 +05:30
RetrofitInstance.authUrl = if (newValue == false) RetrofitInstance.url
else authInstance.value
val restartDialog = RequireRestartDialog()
restartDialog.show(childFragmentManager, "RequireRestartDialog")
2022-07-03 13:50:53 +05:30
true
}
2022-07-17 21:48:39 +05:30
val customInstance = findPreference<Preference>(PreferenceKeys.CUSTOM_INSTANCE)
2022-06-11 16:34:33 +05:30
customInstance?.setOnPreferenceClickListener {
val newFragment = CustomInstanceDialog()
newFragment.show(childFragmentManager, "CustomInstanceDialog")
2022-06-11 15:23:09 +05:30
true
}
2022-07-17 21:48:39 +05:30
val clearCustomInstances = findPreference<Preference>(PreferenceKeys.CLEAR_CUSTOM_INSTANCES)
2022-06-11 19:25:25 +05:30
clearCustomInstances?.setOnPreferenceClickListener {
PreferenceHelper.removePreference("customInstances")
2022-07-02 01:02:26 +05:30
val intent = Intent(context, SettingsActivity::class.java)
startActivity(intent)
2022-06-11 19:25:25 +05:30
true
}
2022-07-17 21:48:39 +05:30
val login = findPreference<Preference>(PreferenceKeys.LOGIN_REGISTER)
val token = PreferenceHelper.getToken()
2022-07-08 17:56:00 +05:30
if (token != "") login?.setTitle(R.string.logout)
2022-06-11 15:23:09 +05:30
login?.setOnPreferenceClickListener {
2022-07-01 13:49:00 +05:30
if (token == "") {
val newFragment = LoginDialog()
newFragment.show(childFragmentManager, "Login")
} else {
val newFragment = LogoutDialog()
newFragment.show(childFragmentManager, "Logout")
}
2022-06-11 15:23:09 +05:30
true
}
2022-07-17 21:48:39 +05:30
val deleteAccount = findPreference<Preference>(PreferenceKeys.DELETE_ACCOUNT)
2022-06-25 21:41:11 +05:30
deleteAccount?.setOnPreferenceClickListener {
val token = PreferenceHelper.getToken()
2022-06-25 21:41:11 +05:30
if (token != "") {
val newFragment = DeleteAccountDialog()
newFragment.show(childFragmentManager, "DeleteAccountDialog")
} else {
Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show()
}
true
}
2022-07-17 21:48:39 +05:30
val importFromYt = findPreference<Preference>(PreferenceKeys.IMPORT_SUBS)
2022-06-11 15:23:09 +05:30
importFromYt?.setOnPreferenceClickListener {
2022-07-03 13:50:53 +05:30
importSubscriptions()
2022-06-11 15:23:09 +05:30
true
}
}
2022-07-03 13:50:53 +05:30
private fun initCustomInstances(instancePref: ListPreference) {
2022-07-24 15:45:51 +05:30
lifecycleScope.launchWhenCreated {
val customInstances = PreferenceHelper.getCustomInstances()
2022-06-11 19:25:25 +05:30
2022-07-24 15:45:51 +05:30
var instanceNames = arrayListOf<String>()
var instanceValues = arrayListOf<String>()
2022-06-11 19:25:25 +05:30
2022-07-24 15:45:51 +05:30
// fetch official public instances
2022-06-11 19:25:25 +05:30
2022-06-11 15:23:09 +05:30
val response = try {
RetrofitInstance.api.getInstances("https://instances.tokhmi.xyz/")
} catch (e: Exception) {
2022-07-24 15:45:51 +05:30
e.printStackTrace()
emptyList()
2022-06-11 15:23:09 +05:30
}
2022-07-24 15:45:51 +05:30
response.forEach {
if (it.name != null && it.api_url != null) {
instanceNames += it.name!!
instanceValues += it.api_url!!
}
2022-06-11 15:23:09 +05:30
}
2022-06-11 19:25:25 +05:30
2022-07-24 15:45:51 +05:30
customInstances.forEach { instance ->
instanceNames += instance.name
instanceValues += instance.apiUrl
}
2022-06-11 19:25:25 +05:30
2022-06-11 15:23:09 +05:30
runOnUiThread {
2022-07-24 15:45:51 +05:30
// add custom instances to the list preference
instancePref.entries = instanceNames.toTypedArray()
instancePref.entryValues = instanceValues.toTypedArray()
instancePref.summaryProvider =
2022-06-11 15:23:09 +05:30
Preference.SummaryProvider<ListPreference> { preference ->
2022-07-24 15:45:51 +05:30
preference.entry
2022-06-11 15:23:09 +05:30
}
}
}
}
2022-07-24 15:45:51 +05:30
private fun logout() {
PreferenceHelper.setToken("")
Toast.makeText(context, getString(R.string.loggedout), Toast.LENGTH_SHORT).show()
}
2022-06-11 15:23:09 +05:30
private fun Fragment?.runOnUiThread(action: () -> Unit) {
this ?: return
if (!isAdded) return // Fragment not attached to an Activity
activity?.runOnUiThread(action)
}
2022-07-03 13:50:53 +05:30
private fun importSubscriptions() {
val token = PreferenceHelper.getToken()
2022-07-21 20:29:06 +05:30
if (token != "") {
// check StorageAccess
2022-07-27 15:27:04 +05:30
val accessGranted =
PermissionHelper.isStoragePermissionGranted(activity as AppCompatActivity)
2022-07-21 20:29:06 +05:30
if (accessGranted) getContent.launch("*/*")
else PermissionHelper.requestReadWrite(activity as AppCompatActivity)
2022-07-21 20:17:14 +05:30
} else {
2022-07-21 20:29:06 +05:30
Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show()
2022-07-21 20:17:14 +05:30
}
2022-07-03 13:50:53 +05:30
}
2022-06-11 15:23:09 +05:30
private fun subscribe(channels: List<String>) {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val token = PreferenceHelper.getToken()
RetrofitInstance.authApi.importSubscriptions(
2022-06-11 15:23:09 +05:30
false,
2022-06-26 14:38:10 +05:30
token,
2022-06-11 15:23:09 +05:30
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()
}
}