From 9986c2a7d5bac75cd943bd196173a8cab872e1df Mon Sep 17 00:00:00 2001 From: Bnyro Date: Sat, 11 Jun 2022 11:53:09 +0200 Subject: [PATCH 1/2] moved instance settings --- .../libretube/preferences/InstanceSettings.kt | 266 ++++++++++++++++++ .../libretube/preferences/MainSettings.kt | 250 +--------------- app/src/main/res/layout/fragment_about.xml | 12 +- app/src/main/res/values/strings.xml | 3 +- app/src/main/res/xml/instance_settings.xml | 34 +++ app/src/main/res/xml/settings.xml | 76 ++--- 6 files changed, 340 insertions(+), 301 deletions(-) create mode 100644 app/src/main/java/com/github/libretube/preferences/InstanceSettings.kt create mode 100644 app/src/main/res/xml/instance_settings.xml diff --git a/app/src/main/java/com/github/libretube/preferences/InstanceSettings.kt b/app/src/main/java/com/github/libretube/preferences/InstanceSettings.kt new file mode 100644 index 000000000..ed8a02d96 --- /dev/null +++ b/app/src/main/java/com/github/libretube/preferences/InstanceSettings.kt @@ -0,0 +1,266 @@ +package com.github.libretube.preferences + +import android.Manifest +import android.content.ContentResolver +import android.content.Context +import android.content.pm.PackageManager +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.text.TextUtils +import android.util.Log +import android.widget.TextView +import android.widget.Toast +import androidx.activity.result.contract.ActivityResultContracts +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 com.github.libretube.R +import com.github.libretube.dialogs.LoginDialog +import com.github.libretube.requireMainActivityRestart +import com.github.libretube.util.RetrofitInstance +import org.json.JSONObject +import org.json.JSONTokener +import retrofit2.HttpException +import java.io.IOException +import java.io.InputStream +import java.util.zip.ZipEntry +import java.util.zip.ZipInputStream + +class InstanceSettings : PreferenceFragmentCompat() { + val TAG = "InstanceSettings" + + override fun onCreate(savedInstanceState: Bundle?) { + MainSettings.getContent = + 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() + 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 + } + } + + inputStream?.bufferedReader()?.readLines()?.forEach { + if (it.isNotBlank()) { + val channelId = it.substringBefore(",") + if (channelId.length == 24) + channels.add(channelId) + } + } + } + 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) + + val topBarTextView = activity?.findViewById(R.id.topBar_textView) + topBarTextView?.text = getString(R.string.instance) + + val instance = findPreference("instance_server") + 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("login_register") + login?.setOnPreferenceClickListener { + requireMainActivityRestart = true + val newFragment = LoginDialog() + newFragment.show(childFragmentManager, "Login") + true + } + + val importFromYt = findPreference("import_from_yt") + importFromYt?.setOnPreferenceClickListener { + val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE) + val token = sharedPref?.getString("token", "")!! + // check StorageAccess + 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( + this.requireActivity(), + arrayOf( + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.MANAGE_EXTERNAL_STORAGE + ), + 1 + ) // permission request code is just an int + } else if (token != "") { + MainSettings.getContent.launch("*/*") + } else { + Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show() + } + } else { + if (ActivityCompat.checkSelfPermission( + requireContext(), + Manifest.permission.READ_EXTERNAL_STORAGE + ) != PackageManager.PERMISSION_GRANTED || + ActivityCompat.checkSelfPermission( + requireContext(), + Manifest.permission.WRITE_EXTERNAL_STORAGE + ) != PackageManager.PERMISSION_GRANTED + ) { + ActivityCompat.requestPermissions( + this.requireActivity(), + arrayOf( + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE + ), + 1 + ) + } else if (token != "") { + MainSettings.getContent.launch("*/*") + } else { + Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show() + } + } + true + } + } + + 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 = ArrayList() + val listEntryValues: MutableList = ArrayList() + for (item in response) { + listEntries.add(item.name!!) + listEntryValues.add(item.api_url!!) + } + val entries = listEntries.toTypedArray() + val entryValues = listEntryValues.toTypedArray() + runOnUiThread { + val instance = findPreference("instance_server") + instance?.entries = entries + instance?.entryValues = entryValues + instance?.summaryProvider = + Preference.SummaryProvider { 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) { + fun run() { + lifecycleScope.launchWhenCreated { + val response = try { + val sharedPref = + context?.getSharedPreferences("token", Context.MODE_PRIVATE) + 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() + } +} diff --git a/app/src/main/java/com/github/libretube/preferences/MainSettings.kt b/app/src/main/java/com/github/libretube/preferences/MainSettings.kt index 04bb1d33d..6ccfcf446 100644 --- a/app/src/main/java/com/github/libretube/preferences/MainSettings.kt +++ b/app/src/main/java/com/github/libretube/preferences/MainSettings.kt @@ -1,37 +1,15 @@ package com.github.libretube.preferences -import android.Manifest -import android.content.ContentResolver -import android.content.Context -import android.content.pm.PackageManager -import android.net.Uri -import android.os.Build import android.os.Bundle -import android.text.TextUtils -import android.util.Log -import android.widget.Toast import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.contract.ActivityResultContracts -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 com.github.libretube.R -import com.github.libretube.dialogs.LoginDialog import com.github.libretube.isCurrentViewMainSettings import com.github.libretube.requireMainActivityRestart -import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.ThemeHelper -import java.io.IOException -import java.io.InputStream -import java.util.zip.ZipEntry -import java.util.zip.ZipInputStream -import org.json.JSONObject -import org.json.JSONTokener -import retrofit2.HttpException class MainSettings : PreferenceFragmentCompat() { val TAG = "SettingsFragment" @@ -40,76 +18,6 @@ class MainSettings : PreferenceFragmentCompat() { lateinit var getContent: ActivityResultLauncher } - override fun onCreate(savedInstanceState: Bundle?) { - getContent = - 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() - 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 - } - } - - inputStream?.bufferedReader()?.readLines()?.forEach { - if (it.isNotBlank()) { - val channelId = it.substringBefore(",") - if (channelId.length == 24) - channels.add(channelId) - } - } - } - 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.settings, rootKey) @@ -125,27 +33,10 @@ class MainSettings : PreferenceFragmentCompat() { true } - val instance = findPreference("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("login_register") - login?.setOnPreferenceClickListener { - requireMainActivityRestart = true - val newFragment = LoginDialog() - newFragment.show(childFragmentManager, "Login") + val instance = findPreference("instance") + instance?.setOnPreferenceClickListener { + val newFragment = InstanceSettings() + navigateSettings(newFragment) true } @@ -156,8 +47,8 @@ class MainSettings : PreferenceFragmentCompat() { true } - val sponsorblock = findPreference("sponsorblock") - sponsorblock?.setOnPreferenceClickListener { + val sponsorBlock = findPreference("sponsorblock") + sponsorBlock?.setOnPreferenceClickListener { val newFragment = SponsorBlockSettings() navigateSettings(newFragment) true @@ -176,59 +67,6 @@ class MainSettings : PreferenceFragmentCompat() { navigateSettings(newFragment) true } - - val importFromYt = findPreference("import_from_yt") - importFromYt?.setOnPreferenceClickListener { - val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE) - val token = sharedPref?.getString("token", "")!! - // check StorageAccess - 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( - this.requireActivity(), - arrayOf( - Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.MANAGE_EXTERNAL_STORAGE - ), - 1 - ) // permission request code is just an int - } 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 - ) != PackageManager.PERMISSION_GRANTED || - ActivityCompat.checkSelfPermission( - requireContext(), - Manifest.permission.WRITE_EXTERNAL_STORAGE - ) != PackageManager.PERMISSION_GRANTED - ) { - 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 - } } private fun navigateSettings(newFragment: Fragment) { @@ -237,80 +75,4 @@ class MainSettings : PreferenceFragmentCompat() { .replace(R.id.settings, newFragment) .commitNow() } - - 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 = ArrayList() - val listEntryValues: MutableList = ArrayList() - for (item in response) { - listEntries.add(item.name!!) - listEntryValues.add(item.api_url!!) - } - val entries = listEntries.toTypedArray() - val entryValues = listEntryValues.toTypedArray() - runOnUiThread { - val instance = findPreference("instance") - instance?.entries = entries - instance?.entryValues = entryValues - instance?.summaryProvider = - Preference.SummaryProvider { 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) { - fun run() { - lifecycleScope.launchWhenCreated { - val response = try { - val sharedPref = - context?.getSharedPreferences("token", Context.MODE_PRIVATE) - 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() - } } diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml index 8e92d159f..8e1ccc650 100644 --- a/app/src/main/res/layout/fragment_about.xml +++ b/app/src/main/res/layout/fragment_about.xml @@ -39,7 +39,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:padding="10dp"> + android:paddingHorizontal="20dp" android:paddingVertical="10dp"> + android:paddingHorizontal="20dp" android:paddingVertical="10dp"> + android:paddingHorizontal="20dp" android:paddingVertical="10dp"> + android:paddingHorizontal="20dp" android:paddingVertical="10dp"> + android:paddingHorizontal="20dp" android:paddingVertical="10dp"> + android:paddingHorizontal="20dp" android:paddingVertical="10dp"> Please log in and try again. Choose an instance Add a custom instance - Choose a region + Region Log in/register Please log in or register in the settings first. Subscribed @@ -161,4 +161,5 @@ Silly shaped Flying flame Boosted bird + Piped, login, subscriptions diff --git a/app/src/main/res/xml/instance_settings.xml b/app/src/main/res/xml/instance_settings.xml new file mode 100644 index 000000000..f76aa1fe1 --- /dev/null +++ b/app/src/main/res/xml/instance_settings.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml index 8a9a59986..942736b00 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -5,83 +5,59 @@ + app:key="region" + app:title="@string/region" + app:useSimpleSummaryProvider="true" /> - - - - - - - - - - - - - + app:key="language" + app:title="@string/changeLanguage" + app:useSimpleSummaryProvider="true" /> + android:icon="@drawable/ic_server" + app:key="instance" + app:summary="@string/instance_summary" + app:title="@string/instance" /> + + + app:title="@string/sponsorblock" /> + app:title="@string/advanced" /> + app:title="@string/about" /> From 162c1682c029a4818814ba9683b77131dcedc3ba Mon Sep 17 00:00:00 2001 From: Bnyro Date: Sat, 11 Jun 2022 11:53:43 +0200 Subject: [PATCH 2/2] ktlint --- .../com/github/libretube/preferences/InstanceSettings.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/github/libretube/preferences/InstanceSettings.kt b/app/src/main/java/com/github/libretube/preferences/InstanceSettings.kt index ed8a02d96..21753bb8d 100644 --- a/app/src/main/java/com/github/libretube/preferences/InstanceSettings.kt +++ b/app/src/main/java/com/github/libretube/preferences/InstanceSettings.kt @@ -23,13 +23,13 @@ import com.github.libretube.R import com.github.libretube.dialogs.LoginDialog import com.github.libretube.requireMainActivityRestart import com.github.libretube.util.RetrofitInstance -import org.json.JSONObject -import org.json.JSONTokener -import retrofit2.HttpException import java.io.IOException import java.io.InputStream import java.util.zip.ZipEntry import java.util.zip.ZipInputStream +import org.json.JSONObject +import org.json.JSONTokener +import retrofit2.HttpException class InstanceSettings : PreferenceFragmentCompat() { val TAG = "InstanceSettings"