diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 31c00cbde..4cee2a677 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -27,6 +27,10 @@
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:configChanges="orientation|screenSize"
/>
+
- }
-
- 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)
- 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 {
- 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 != "") {
- 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
- }
-
- val themeToggle = findPreference("theme_togglee")
- themeToggle?.setOnPreferenceChangeListener { _, newValue ->
- when (newValue.toString()) {
- "A" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
- "L" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
- "D" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
- }
- true
- }
-
- val changeLanguage = findPreference("language")
- changeLanguage?.setOnPreferenceChangeListener { _, _ ->
- val refresh = Intent(context, MainActivity::class.java)
- startActivity(refresh)
- true
- }
-
- val about = findPreference("about")
- about?.setOnPreferenceClickListener {
- val uri = Uri.parse("https://libre-tube.github.io/")
- val intent = Intent(Intent.ACTION_VIEW).setData(uri)
- startActivity(intent)
- 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")
- 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/SettingsActivity.kt b/app/src/main/java/com/github/libretube/SettingsActivity.kt
new file mode 100644
index 000000000..0fb13644e
--- /dev/null
+++ b/app/src/main/java/com/github/libretube/SettingsActivity.kt
@@ -0,0 +1,320 @@
+package com.github.libretube
+
+import android.Manifest
+import android.content.ContentResolver
+import android.content.Context
+import android.content.Intent
+import android.content.SharedPreferences
+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.view.View
+import android.widget.Toast
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatDelegate
+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
+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 SettingsActivity : AppCompatActivity(),
+ SharedPreferences.OnSharedPreferenceChangeListener{
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ overridePendingTransition(50, 50);
+ val view = this.findViewById(android.R.id.content)
+ view.setAlpha(0F);
+ view.animate().alpha(1F).setDuration(300);
+ setContentView(R.layout.activity_settings)
+ if (savedInstanceState == null) {
+ supportFragmentManager
+ .beginTransaction()
+ .replace(R.id.settings, SettingsFragment())
+ .commit()
+ }
+
+ PreferenceManager.getDefaultSharedPreferences(this)
+ .registerOnSharedPreferenceChangeListener(this)
+
+ }
+
+ override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, rootKey: String?) {}
+
+
+ class SettingsFragment : PreferenceFragmentCompat() {
+ val TAG = "Settings"
+
+ companion object {
+ 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)
+ 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 {
+ 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 != "") {
+ 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
+ }
+
+ val themeToggle = findPreference("theme_togglee")
+ themeToggle?.setOnPreferenceChangeListener { _, newValue ->
+ when (newValue.toString()) {
+ "A" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
+ "L" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
+ "D" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
+ }
+ true
+ }
+
+ val changeLanguage = findPreference("language")
+ changeLanguage?.setOnPreferenceChangeListener { _, _ ->
+ val refresh = Intent(context, MainActivity::class.java)
+ startActivity(refresh)
+ true
+ }
+
+ val about = findPreference("about")
+ about?.setOnPreferenceClickListener {
+ val uri = Uri.parse("https://libre-tube.github.io/")
+ val intent = Intent(Intent.ACTION_VIEW).setData(uri)
+ startActivity(intent)
+ 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")
+ 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()
+ }
+ }
+
+ override fun onBackPressed() {
+ PreferenceManager.getDefaultSharedPreferences(this)
+ .unregisterOnSharedPreferenceChangeListener(this)
+ intent = Intent(this, MainActivity::class.java)
+ startActivity(intent)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml
new file mode 100644
index 000000000..de6591a20
--- /dev/null
+++ b/app/src/main/res/layout/activity_settings.xml
@@ -0,0 +1,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/nav.xml b/app/src/main/res/navigation/nav.xml
index f164bbb0c..eabf2f9bc 100644
--- a/app/src/main/res/navigation/nav.xml
+++ b/app/src/main/res/navigation/nav.xml
@@ -46,6 +46,6 @@
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0d709f843..51d9d8b8e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -63,6 +63,11 @@
Light Theme
Dark Theme
%1$s subscribers
+ Settings
+ Location
+ Instance
+ Customization
+ Website
%1$s videos
No Internet Connection
Retry
diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml
index caa6994ce..56ae14456 100644
--- a/app/src/main/res/xml/settings.xml
+++ b/app/src/main/res/xml/settings.xml
@@ -1,6 +1,9 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file