mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-13 22:00:30 +05:30
Merge branch 'master' into title_description_seperation
This commit is contained in:
commit
33d634b713
@ -10,8 +10,8 @@ android {
|
||||
applicationId 'com.github.libretube'
|
||||
minSdk 21
|
||||
targetSdk 31
|
||||
versionCode 6
|
||||
versionName '0.2.4'
|
||||
versionCode 7
|
||||
versionName '0.2.5'
|
||||
multiDexEnabled true
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
resValue "string", "app_name", "LibreTube"
|
||||
@ -71,7 +71,8 @@ dependencies {
|
||||
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-jackson:2.9.0'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.2'
|
||||
//do not update jackson annotations! it does not supports <api26
|
||||
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.1'
|
||||
|
||||
implementation 'com.arthenica:ffmpeg-kit-min:4.5.1.LTS'
|
||||
|
||||
|
@ -16,10 +16,23 @@
|
||||
}
|
||||
],
|
||||
"attributes": [],
|
||||
"versionCode": 5,
|
||||
"versionName": "0.2.3",
|
||||
"versionCode": 7,
|
||||
"versionName": "0.2.5",
|
||||
"outputFile": "app-x86_64-release.apk"
|
||||
},
|
||||
{
|
||||
"type": "ONE_OF_MANY",
|
||||
"filters": [
|
||||
{
|
||||
"filterType": "ABI",
|
||||
"value": "armeabi-v7a"
|
||||
}
|
||||
],
|
||||
"attributes": [],
|
||||
"versionCode": 7,
|
||||
"versionName": "0.2.5",
|
||||
"outputFile": "app-armeabi-v7a-release.apk"
|
||||
},
|
||||
{
|
||||
"type": "ONE_OF_MANY",
|
||||
"filters": [
|
||||
@ -29,8 +42,8 @@
|
||||
}
|
||||
],
|
||||
"attributes": [],
|
||||
"versionCode": 5,
|
||||
"versionName": "0.2.3",
|
||||
"versionCode": 7,
|
||||
"versionName": "0.2.5",
|
||||
"outputFile": "app-x86-release.apk"
|
||||
},
|
||||
{
|
||||
@ -42,22 +55,9 @@
|
||||
}
|
||||
],
|
||||
"attributes": [],
|
||||
"versionCode": 5,
|
||||
"versionName": "0.2.3",
|
||||
"versionCode": 7,
|
||||
"versionName": "0.2.5",
|
||||
"outputFile": "app-arm64-v8a-release.apk"
|
||||
},
|
||||
{
|
||||
"type": "ONE_OF_MANY",
|
||||
"filters": [
|
||||
{
|
||||
"filterType": "ABI",
|
||||
"value": "armeabi-v7a"
|
||||
}
|
||||
],
|
||||
"attributes": [],
|
||||
"versionCode": 5,
|
||||
"versionName": "0.2.3",
|
||||
"outputFile": "app-armeabi-v7a-release.apk"
|
||||
}
|
||||
],
|
||||
"elementType": "File"
|
||||
|
@ -7,6 +7,7 @@
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
@ -43,7 +43,9 @@ class Home : Fragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val recyclerView = view.findViewById<RecyclerView>(R.id.recview)
|
||||
recyclerView.layoutManager = GridLayoutManager(view.context, resources.getInteger(R.integer.grid_items))
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
val grid = sharedPreferences.getString("grid", resources.getInteger(R.integer.grid_items).toString())!!
|
||||
recyclerView.layoutManager = GridLayoutManager(view.context, grid.toInt())
|
||||
val progressbar = view.findViewById<ProgressBar>(R.id.progressBar)
|
||||
fetchJson(progressbar,recyclerView)
|
||||
refreshLayout = view.findViewById(R.id.home_refresh)
|
||||
|
@ -13,6 +13,7 @@ import android.util.Log
|
||||
import android.view.*
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.LinearLayout
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
@ -39,6 +40,11 @@ class MainActivity : AppCompatActivity() {
|
||||
RetrofitInstance.url = sharedPreferences.getString("instance", "https://pipedapi.kavin.rocks/")!!
|
||||
DynamicColors.applyToActivitiesIfAvailable(application)
|
||||
setContentView(R.layout.activity_main)
|
||||
when (sharedPreferences.getString("theme_togglee", "A")!!) {
|
||||
"A" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
"L" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
||||
"D" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
||||
}
|
||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||
|
||||
bottomNavigationView = findViewById(R.id.bottomNav)
|
||||
|
@ -52,8 +52,13 @@ interface PipedApi {
|
||||
@POST("unsubscribe")
|
||||
suspend fun unsubscribe(@Header("Authorization") token: String, @Body subscribe: Subscribe): Message
|
||||
|
||||
@POST("import")
|
||||
suspend fun importSubscriptions(@Header("Authorization") token: String, @Body channels: List<String>): Message
|
||||
|
||||
//only for fetching servers list
|
||||
@GET
|
||||
suspend fun getInstances(@Url url: String): List<Instances>
|
||||
|
||||
|
||||
|
||||
}
|
@ -194,9 +194,9 @@ class PlayerFragment : Fragment() {
|
||||
view.findViewById<ConstraintLayout>(R.id.main_container).isClickable = true
|
||||
view.findViewById<LinearLayout>(R.id.linLayout).visibility = View.GONE
|
||||
val mainActivity = activity as MainActivity
|
||||
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||
isFullScreen = true
|
||||
} else {
|
||||
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|
||||
isFullScreen=true
|
||||
}else{
|
||||
with(motionLayout) {
|
||||
getConstraintSet(R.id.start).constrainHeight(R.id.player, 0)
|
||||
enableTransition(R.id.yt_transition, true)
|
||||
@ -231,9 +231,11 @@ class PlayerFragment : Fragment() {
|
||||
} catch (e: IOException) {
|
||||
println(e)
|
||||
Log.e(TAG, "IOException, you might not have internet connection")
|
||||
Toast.makeText(context,R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
||||
return@launchWhenCreated
|
||||
} catch (e: HttpException) {
|
||||
Log.e(TAG, "HttpException, unexpected response")
|
||||
Toast.makeText(context,R.string.server_error, Toast.LENGTH_SHORT).show()
|
||||
return@launchWhenCreated
|
||||
}
|
||||
var videosNameArray: Array<CharSequence> = arrayOf()
|
||||
@ -266,10 +268,12 @@ class PlayerFragment : Fragment() {
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
val defres = sharedPreferences.getString("default_res", "")!!
|
||||
when {
|
||||
defres != "" -> {
|
||||
run lit@{
|
||||
defres!="" -> {
|
||||
var foundRes = false
|
||||
run lit@ {
|
||||
response.videoStreams!!.forEachIndexed { index, pipedStream ->
|
||||
if (pipedStream.quality!!.contains(defres)) {
|
||||
if (pipedStream.quality!!.contains(defres)){
|
||||
foundRes = true
|
||||
val dataSourceFactory: DataSource.Factory =
|
||||
DefaultHttpDataSource.Factory()
|
||||
val videoItem: MediaItem = MediaItem.Builder()
|
||||
@ -288,6 +292,12 @@ class PlayerFragment : Fragment() {
|
||||
exoPlayer.setMediaSource(mergeSource)
|
||||
view.findViewById<TextView>(R.id.quality_text).text = videosNameArray[index + 1]
|
||||
return@lit
|
||||
}else if (index+1 == response.videoStreams.size){
|
||||
val mediaItem: MediaItem = MediaItem.Builder()
|
||||
.setUri(response.hls)
|
||||
.setSubtitleConfigurations(subtitle)
|
||||
.build()
|
||||
exoPlayer.setMediaItem(mediaItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,11 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.AutoCompleteTextView
|
||||
import android.widget.TextView.OnEditorActionListener
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
@ -75,6 +77,17 @@ class SearchFragment : Fragment() {
|
||||
}
|
||||
|
||||
})
|
||||
autoTextView.setOnEditorActionListener(OnEditorActionListener { _, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
hideKeyboard();
|
||||
autoTextView.dismissDropDown();
|
||||
return@OnEditorActionListener true
|
||||
}
|
||||
false
|
||||
})
|
||||
autoTextView.setOnDismissListener {
|
||||
hideKeyboard();
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchSuggestions(query: String, autoTextView: AutoCompleteTextView){
|
||||
@ -125,4 +138,8 @@ class SearchFragment : Fragment() {
|
||||
requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
hideKeyboard()
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
package com.github.libretube
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ContentValues.TAG
|
||||
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.os.Environment
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
@ -15,59 +14,100 @@ import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
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.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.io.*
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
class Settings : PreferenceFragmentCompat() {
|
||||
|
||||
class Settings : PreferenceFragmentCompat() {
|
||||
val TAG = "Settings"
|
||||
companion object {
|
||||
lateinit var getContent: ActivityResultLauncher<String>
|
||||
}
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
|
||||
|
||||
if (uri != null) {
|
||||
var zipfile = ZipFile(UriUtils.uri2File(uri))
|
||||
try{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
|
||||
var zipentry =
|
||||
zipfile.getEntry("Takeout/YouTube and YouTube Music/subscriptions/subscriptions.csv")
|
||||
// Open a specific media item using ParcelFileDescriptor.
|
||||
val resolver: ContentResolver =
|
||||
requireActivity()
|
||||
.contentResolver
|
||||
|
||||
var inputStream = zipfile.getInputStream(zipentry)
|
||||
// "rw" for read-and-write;
|
||||
// "rwt" for truncating or overwriting existing file contents.
|
||||
val readOnlyMode = "r"
|
||||
// uri - I have got from onActivityResult
|
||||
//uri = data.getData();
|
||||
val parcelFile = resolver.openFileDescriptor(uri, readOnlyMode)
|
||||
val fileReader = FileReader(parcelFile!!.fileDescriptor)
|
||||
val reader = BufferedReader(fileReader)
|
||||
var line: String?
|
||||
var channels: MutableList<String> = emptyList<String>().toMutableList()
|
||||
var subscribedCount = 0
|
||||
while (reader.readLine().also { line = it } != null) {
|
||||
if (line!!.replace(" ","") != "" && subscribedCount >0) {
|
||||
val channel = line!!.split(",")[0]
|
||||
channels.add(channel)
|
||||
|
||||
val baos = ByteArrayOutputStream()
|
||||
Log.d(TAG, "subscribed: " + line + " total: " + subscribedCount)
|
||||
}
|
||||
subscribedCount++
|
||||
}
|
||||
subscribe(channels)
|
||||
reader.close()
|
||||
fileReader.close()
|
||||
}else{
|
||||
Log.d(TAG,UriUtils.uri2File(uri).toString())
|
||||
val file = UriUtils.uri2File(uri)
|
||||
var inputStream: InputStream? = null
|
||||
if (file.extension == "zip") {
|
||||
var zipfile = ZipFile(file)
|
||||
|
||||
inputStream.use { it.copyTo(baos) }
|
||||
var zipentry =
|
||||
zipfile.getEntry("Takeout/YouTube and YouTube Music/subscriptions/subscriptions.csv")
|
||||
|
||||
var subscriptions = baos.toByteArray().decodeToString()
|
||||
inputStream = zipfile.getInputStream(zipentry)
|
||||
}else if(file.extension == "csv"){
|
||||
inputStream = file.inputStream()
|
||||
}
|
||||
val baos = ByteArrayOutputStream()
|
||||
|
||||
var subscribedCount = 0
|
||||
inputStream?.use { it.copyTo(baos) }
|
||||
|
||||
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)
|
||||
var subscriptions = baos.toByteArray().decodeToString()
|
||||
var channels: MutableList<String> = emptyList<String>().toMutableList()
|
||||
var subscribedCount = 0
|
||||
for (text in subscriptions.lines().subList(1,subscriptions.lines().size)) {
|
||||
if (text.replace(" ","") != "") {
|
||||
val channel = text.split(",")[0]
|
||||
channels.add(channel)
|
||||
subscribedCount++
|
||||
Log.d(TAG, "subscribed: " + text + " total: " + subscribedCount)
|
||||
}
|
||||
}
|
||||
subscribe(channels)
|
||||
}
|
||||
}
|
||||
|
||||
Toast.makeText(
|
||||
context,
|
||||
"Subscribed to " + subscribedCount + " channels.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}catch (e: Exception){
|
||||
Log.e(TAG,e.toString())
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.error,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -100,17 +140,24 @@ class Settings : PreferenceFragmentCompat() {
|
||||
|
||||
val importFromYt = findPreference<Preference>("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 (!Environment.isExternalStorageManager()) {
|
||||
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(
|
||||
@ -129,12 +176,12 @@ class Settings : PreferenceFragmentCompat() {
|
||||
),
|
||||
1
|
||||
)
|
||||
}else if (token != ""){
|
||||
getContent.launch("*/*")
|
||||
}else{
|
||||
Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
getContent.launch("application/zip")
|
||||
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
@ -197,15 +244,12 @@ class Settings : PreferenceFragmentCompat() {
|
||||
}
|
||||
|
||||
|
||||
private fun subscribe(channel_id: String) {
|
||||
private fun subscribe(channels: List<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)
|
||||
)
|
||||
RetrofitInstance.api.importSubscriptions(sharedPref?.getString("token", "")!!,channels)
|
||||
} catch (e: IOException) {
|
||||
Log.e(TAG, "IOException, you might not have internet connection")
|
||||
return@launchWhenCreated
|
||||
@ -213,9 +257,17 @@ class Settings : PreferenceFragmentCompat() {
|
||||
Log.e(TAG, "HttpException, unexpected response$e")
|
||||
return@launchWhenCreated
|
||||
}
|
||||
if(response.message == "ok"){
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.importsuccess,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
run()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,6 @@ class Subscriptions : Fragment() {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||
token = sharedPref?.getString("token","")!!
|
||||
Log.e(TAG,token)
|
||||
refreshLayout = view.findViewById(R.id.sub_refresh)
|
||||
if(token!=""){
|
||||
view.findViewById<RelativeLayout>(R.id.loginOrRegister).visibility=View.GONE
|
||||
@ -59,7 +58,9 @@ class Subscriptions : Fragment() {
|
||||
fetchChannels(channelRecView)
|
||||
|
||||
var feedRecView = view.findViewById<RecyclerView>(R.id.sub_feed)
|
||||
feedRecView.layoutManager = GridLayoutManager(view.context, resources.getInteger(R.integer.grid_items))
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
val grid = sharedPreferences.getString("grid", resources.getInteger(R.integer.grid_items).toString())!!
|
||||
feedRecView.layoutManager = GridLayoutManager(view.context, grid.toInt())
|
||||
fetchFeed(feedRecView, progressBar)
|
||||
|
||||
refreshLayout?.setOnRefreshListener {
|
||||
@ -92,7 +93,7 @@ class Subscriptions : Fragment() {
|
||||
val response = try {
|
||||
RetrofitInstance.api.getFeed(token)
|
||||
}catch(e: IOException) {
|
||||
println(e)
|
||||
Log.e(TAG,e.toString())
|
||||
Log.e(TAG, "IOException, you might not have internet connection")
|
||||
return@launchWhenCreated
|
||||
} catch (e: HttpException) {
|
||||
@ -119,7 +120,7 @@ class Subscriptions : Fragment() {
|
||||
val response = try {
|
||||
RetrofitInstance.api.subscriptions(token)
|
||||
}catch(e: IOException) {
|
||||
println(e)
|
||||
Log.e(TAG,e.toString())
|
||||
Log.e(TAG, "IOException, you might not have internet connection")
|
||||
return@launchWhenCreated
|
||||
} catch (e: HttpException) {
|
||||
@ -137,16 +138,11 @@ class Subscriptions : Fragment() {
|
||||
}
|
||||
run()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
Log.e(TAG,"Stopped")
|
||||
subscriptionAdapter = null
|
||||
view?.findViewById<RecyclerView>(R.id.sub_feed)?.adapter=null
|
||||
super.onStop()
|
||||
}
|
||||
override fun onDestroy() {
|
||||
Log.e(TAG,"Destroyed")
|
||||
super.onDestroy()
|
||||
subscriptionAdapter = null
|
||||
view?.findViewById<RecyclerView>(R.id.sub_feed)?.adapter=null
|
||||
}
|
||||
|
||||
}
|
||||
|
10
app/src/main/res/drawable/ic_column.xml
Normal file
10
app/src/main/res/drawable/ic_column.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M10,18h5L15,5h-5v13zM4,18h5L9,5L4,5v13zM16,5v13h5L21,5h-5z"/>
|
||||
</vector>
|
@ -236,12 +236,12 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@+id/player_channelImage"
|
||||
android:layout_toStartOf="@+id/player_subscribe"
|
||||
android:text=""
|
||||
android:textStyle="bold"
|
||||
android:layout_toEndOf="@+id/player_channelImage"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"/>
|
||||
android:maxLines="1"
|
||||
android:text=""
|
||||
android:textStyle="bold" />
|
||||
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
|
@ -51,7 +51,9 @@
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="@+id/thumbnailcard"
|
||||
app:layout_constraintStart_toEndOf="@+id/channel_image"
|
||||
app:layout_constraintTop_toBottomOf="@+id/thumbnailcard" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/thumbnailcard"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_channel"
|
||||
|
@ -31,7 +31,6 @@
|
||||
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
|
||||
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="fontFamily">@font/roboto</item>
|
||||
|
||||
</style>
|
||||
</resources>
|
@ -32,7 +32,6 @@
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:windowLightStatusBar">true</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="fontFamily">@font/roboto</item>
|
||||
|
||||
</style>
|
||||
</resources>
|
@ -417,6 +417,7 @@
|
||||
<item>D</item>
|
||||
</string-array>
|
||||
<string-array name="defres">
|
||||
<item>HLS</item>
|
||||
<item>1080p</item>
|
||||
<item>720p</item>
|
||||
<item>480p</item>
|
||||
@ -424,4 +425,20 @@
|
||||
<item>240p</item>
|
||||
<item>144p</item>
|
||||
</string-array>
|
||||
<string-array name="defresValue">
|
||||
<item></item>
|
||||
<item>1080p</item>
|
||||
<item>720p</item>
|
||||
<item>480p</item>
|
||||
<item>360p</item>
|
||||
<item>240p</item>
|
||||
<item>144p</item>
|
||||
</string-array>
|
||||
<string-array name="grid">
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
</string-array>
|
||||
</resources>
|
@ -17,11 +17,13 @@
|
||||
<string name="loggedout">Logged out successfully!</string>
|
||||
<string name="registered">Registered successfully! You may now subscribe to channels you want.</string>
|
||||
<string name="already_logged_in">You are already logged in, you may logout of your account.</string>
|
||||
<string name="login_first">Please login and try again!</string>
|
||||
<string name="instances">Choose an instance</string>
|
||||
<string name="customInstance">Add a custom instance</string>
|
||||
<string name="region">Choose a region</string>
|
||||
<string name="login_register">Login/Register</string>
|
||||
<string name="please_login">Please Login or Register from the settings to show your Subscriptions!</string>
|
||||
<string name="importsuccess">Subscribed successfully!</string>
|
||||
<string name="subscribeIsEmpty">Subscribe to some channels first!</string>
|
||||
<string name="cannotDownload">Can\'t Download this stream!</string>
|
||||
<string name="dlcomplete">Download is completed!</string>
|
||||
@ -33,7 +35,9 @@
|
||||
<string name="app_theme">App theme</string>
|
||||
<string name="server_error">Server countered a problem. Maybe try another instance?</string>
|
||||
<string name="unknown_error">Network error!</string>
|
||||
<string name="error">Something went wrong!</string>
|
||||
<string name="empty">Username and Password can\'t be empty!</string>
|
||||
<string name="notgmail">This is not your gmail account!</string>
|
||||
<string name="defres">Default Video Resolution</string>
|
||||
<string name="grid">Choose the grid columns</string>
|
||||
</resources>
|
@ -29,6 +29,5 @@
|
||||
<item name="colorPrimaryInverse">@color/md_theme_light_primaryInverse</item>
|
||||
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="fontFamily">@font/roboto</item>
|
||||
</style>
|
||||
</resources>
|
@ -1,11 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.preference.SwitchPreferenceCompat
|
||||
app:key="darkMode"
|
||||
app:title="Toggle dark mode"
|
||||
app:isPreferenceVisible="false"/>
|
||||
<ListPreference
|
||||
app:key="region"
|
||||
app:title="@string/region"
|
||||
@ -54,10 +49,19 @@
|
||||
app:title="@string/defres"
|
||||
app:key="default_res"
|
||||
app:entries="@array/defres"
|
||||
app:entryValues="@array/defres"
|
||||
app:entryValues="@array/defresValue"
|
||||
app:defaultValue=""
|
||||
android:icon="@drawable/ic_hd"
|
||||
app:useSimpleSummaryProvider="true"
|
||||
/>
|
||||
<ListPreference
|
||||
app:title="@string/grid"
|
||||
app:key="grid"
|
||||
app:entries="@array/grid"
|
||||
app:entryValues="@array/grid"
|
||||
app:defaultValue="@integer/grid_items"
|
||||
android:icon="@drawable/ic_column"
|
||||
app:useSimpleSummaryProvider="true"
|
||||
/>
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user