diff --git a/app/build.gradle b/app/build.gradle index c339424ac..b12ee55d6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -74,4 +74,7 @@ dependencies { implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.2' implementation 'com.arthenica:ffmpeg-kit-min:4.5.1.LTS' + + implementation 'com.blankj:utilcode:1.30.0' + } \ No newline at end of file diff --git a/app/src/main/java/com/github/libretube/Settings.kt b/app/src/main/java/com/github/libretube/Settings.kt index 37b5b7206..5638a1d85 100644 --- a/app/src/main/java/com/github/libretube/Settings.kt +++ b/app/src/main/java/com/github/libretube/Settings.kt @@ -1,19 +1,78 @@ package com.github.libretube +import android.Manifest +import android.content.ContentValues.TAG import android.content.Context +import android.content.pm.PackageManager +import android.net.Uri +import android.os.Build import android.os.Bundle +import android.os.Environment 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.appcompat.app.AppCompatDelegate +import androidx.core.app.ActivityCompat import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.preference.ListPreference import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat +import androidx.preference.SwitchPreferenceCompat +import com.blankj.utilcode.util.UriUtils +import com.github.libretube.obj.Subscribe import retrofit2.HttpException +import java.io.ByteArrayOutputStream import java.io.IOException +import java.util.zip.ZipFile class Settings : PreferenceFragmentCompat() { + + companion object { + lateinit var getContent: ActivityResultLauncher + } + + + override fun onCreate(savedInstanceState: Bundle?) { + getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? -> + + if (uri != null) { + var zipfile = ZipFile(UriUtils.uri2File(uri)) + + var zipentry = + zipfile.getEntry("Takeout/YouTube and YouTube Music/subscriptions/subscriptions.csv") + + var inputStream = zipfile.getInputStream(zipentry) + + val baos = ByteArrayOutputStream() + + inputStream.use { it.copyTo(baos) } + + var subscriptions = baos.toByteArray().decodeToString() + + var subscribedCount = 0 + + for (text in subscriptions.lines()) { + if (text.take(24) != "Channel Id,Channel Url,C" && !text.take(24).isEmpty()) { + subscribe(text.take(24)) + subscribedCount++ + Log.d(TAG, "subscribed: " + text + " total: " + subscribedCount) + } + } + + Toast.makeText( + context, + "Subscribed to " + subscribedCount + " channels.", + Toast.LENGTH_SHORT + ).show() + } + + } + super.onCreate(savedInstanceState) + } + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.settings, rootKey) val instance = findPreference("instance") @@ -22,7 +81,7 @@ class Settings : PreferenceFragmentCompat() { RetrofitInstance.url = newValue.toString() RetrofitInstance.lazyMgr.reset() val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE) - if(sharedPref?.getString("token","")!="") { + if (sharedPref?.getString("token", "") != "") { with(sharedPref!!.edit()) { putString("token", "") apply() @@ -32,15 +91,65 @@ class Settings : PreferenceFragmentCompat() { true } - val login = findPreference("login_register") - login?.setOnPreferenceClickListener { - val newFragment = LoginDialog() - newFragment.show(childFragmentManager, "Login") - true + val login = findPreference("login_register") + login?.setOnPreferenceClickListener { + val newFragment = LoginDialog() + newFragment.show(childFragmentManager, "Login") + true + } + + val importFromYt = findPreference("import_from_yt") + importFromYt?.setOnPreferenceClickListener { + + //check StorageAccess + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + Log.d("myz", "" + Build.VERSION.SDK_INT) + if (!Environment.isExternalStorageManager()) { + 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 (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 + ) + } } + getContent.launch("application/zip") + + + 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 + } + + } + private fun fetchInstance() { lifecycleScope.launchWhenCreated { val response = try { @@ -50,15 +159,15 @@ class Settings : PreferenceFragmentCompat() { Log.e("settings", "IOException, you might not have internet connection") return@launchWhenCreated } catch (e: HttpException) { - Log.e("settings", "HttpException, unexpected response ${e.toString()}") + Log.e("settings", "HttpException, unexpected response $e") return@launchWhenCreated - } catch (e: Exception){ - Log.e("settings",e.toString()) + } catch (e: Exception) { + Log.e("settings", e.toString()) return@launchWhenCreated } val listEntries: MutableList = ArrayList() val listEntryValues: MutableList = ArrayList() - for(item in response){ + for (item in response) { listEntries.add(item.name!!) listEntryValues.add(item.api_url!!) } @@ -68,20 +177,45 @@ class Settings : PreferenceFragmentCompat() { 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 + 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(channel_id: String) { + fun run() { + lifecycleScope.launchWhenCreated { + val response = try { + val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE) + RetrofitInstance.api.subscribe( + sharedPref?.getString("token", "")!!, + Subscribe(channel_id) + ) + } 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 + } + } + } + run() + } } + diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index 1f2f7dfcb..559897445 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -404,4 +404,17 @@ ZM ZW + + + System Default + Light Theme + Dark Theme + + + + A + L + D + + \ 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 e843f9122..f1d1f9c60 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -29,4 +29,7 @@ Download Failed! Open in VLC Can\'t open in VLC. Maybe it\'s not installed yet? + Import subscriptions from youtube + App theme + \ 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 52f90411a..a2035177b 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -30,4 +30,29 @@ app:key="login_register" app:title="@string/login_register" /> + + + + + + + + + + + + + + + \ No newline at end of file