mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 06:10:31 +05:30
commit
45f87649f9
@ -1,13 +1,11 @@
|
|||||||
package com.github.libretube
|
package com.github.libretube
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import org.junit.Assert.*
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instrumented test, which will execute on an Android device.
|
* Instrumented test, which will execute on an Android device.
|
||||||
*
|
*
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_libretube_round"
|
android:roundIcon="@mipmap/ic_libretube_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.LibreTube"
|
android:theme="@style/Theme.MY"
|
||||||
android:name=".myApp"
|
android:name=".myApp"
|
||||||
android:networkSecurityConfig="@xml/network_security_config"
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
|
@ -12,7 +12,6 @@ import androidx.core.text.HtmlCompat
|
|||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.github.libretube.adapters.PlaylistsAdapter
|
|
||||||
import com.github.libretube.obj.PlaylistId
|
import com.github.libretube.obj.PlaylistId
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
@ -29,14 +28,14 @@ class AddtoPlaylistDialog : DialogFragment() {
|
|||||||
videoId = arguments?.getString("videoId")!!
|
videoId = arguments?.getString("videoId")!!
|
||||||
val builder = MaterialAlertDialogBuilder(it)
|
val builder = MaterialAlertDialogBuilder(it)
|
||||||
// Get the layout inflater
|
// Get the layout inflater
|
||||||
val inflater = requireActivity().layoutInflater;
|
val inflater = requireActivity().layoutInflater
|
||||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
token = sharedPref?.getString("token","")!!
|
token = sharedPref?.getString("token", "")!!
|
||||||
var view: View = inflater.inflate(R.layout.dialog_addtoplaylist, null)
|
var view: View = inflater.inflate(R.layout.dialog_addtoplaylist, null)
|
||||||
spinner = view.findViewById(R.id.playlists_spinner)
|
spinner = view.findViewById(R.id.playlists_spinner)
|
||||||
button = view.findViewById(R.id.addToPlaylist)
|
button = view.findViewById(R.id.addToPlaylist)
|
||||||
if(token!=""){
|
if (token != "") {
|
||||||
fetchPlaylists()
|
fetchPlaylists()
|
||||||
}
|
}
|
||||||
val typedValue = TypedValue()
|
val typedValue = TypedValue()
|
||||||
this.requireActivity().theme.resolveAttribute(R.attr.colorPrimaryDark, typedValue, true)
|
this.requireActivity().theme.resolveAttribute(R.attr.colorPrimaryDark, typedValue, true)
|
||||||
@ -51,64 +50,61 @@ class AddtoPlaylistDialog : DialogFragment() {
|
|||||||
builder.create()
|
builder.create()
|
||||||
} ?: throw IllegalStateException("Activity cannot be null")
|
} ?: throw IllegalStateException("Activity cannot be null")
|
||||||
}
|
}
|
||||||
private fun fetchPlaylists(){
|
private fun fetchPlaylists() {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.playlists(token)
|
RetrofitInstance.api.playlists(token)
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
Toast.makeText(context,R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
Log.e(TAG, "HttpException, unexpected response")
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
Toast.makeText(context,R.string.server_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
if (response.isNotEmpty()){
|
if (response.isNotEmpty()) {
|
||||||
var names = emptyList<String>().toMutableList()
|
var names = emptyList<String>().toMutableList()
|
||||||
for(playlist in response){
|
for (playlist in response) {
|
||||||
names.add(playlist.name!!)
|
names.add(playlist.name!!)
|
||||||
}
|
}
|
||||||
val arrayAdapter = ArrayAdapter(requireContext(),android.R.layout.simple_spinner_item,names)
|
val arrayAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, names)
|
||||||
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||||
spinner.adapter = arrayAdapter
|
spinner.adapter = arrayAdapter
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
button.setOnClickListener {
|
button.setOnClickListener {
|
||||||
addToPlaylist(response[spinner.selectedItemPosition].id!!)
|
addToPlaylist(response[spinner.selectedItemPosition].id!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
}
|
}
|
||||||
private fun addToPlaylist(playlistId: String){
|
private fun addToPlaylist(playlistId: String) {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.addToPlaylist(token, PlaylistId(playlistId, videoId))
|
RetrofitInstance.api.addToPlaylist(token, PlaylistId(playlistId, videoId))
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
Toast.makeText(context,R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
Log.e(TAG, "HttpException, unexpected response")
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
Toast.makeText(context,R.string.server_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
if (response.message == "ok"){
|
if (response.message == "ok") {
|
||||||
Toast.makeText(context,R.string.success, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show()
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
}else{
|
} else {
|
||||||
Toast.makeText(context,R.string.fail, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
package com.github.libretube
|
package com.github.libretube
|
||||||
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils.substring
|
import android.text.TextUtils.substring
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -23,18 +20,17 @@ import com.github.libretube.adapters.ChannelAdapter
|
|||||||
import com.github.libretube.obj.Subscribe
|
import com.github.libretube.obj.Subscribe
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import retrofit2.HttpException
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import retrofit2.HttpException
|
||||||
|
|
||||||
class ChannelFragment : Fragment() {
|
class ChannelFragment : Fragment() {
|
||||||
|
|
||||||
private var channel_id: String? = null
|
private var channel_id: String? = null
|
||||||
private val TAG = "ChannelFragment"
|
private val TAG = "ChannelFragment"
|
||||||
var nextPage: String? =null
|
var nextPage: String? = null
|
||||||
var channelAdapter: ChannelAdapter? = null
|
var channelAdapter: ChannelAdapter? = null
|
||||||
var isLoading = true
|
var isLoading = true
|
||||||
var isSubscribed: Boolean =false
|
var isSubscribed: Boolean = false
|
||||||
private var refreshLayout: SwipeRefreshLayout? = null
|
private var refreshLayout: SwipeRefreshLayout? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@ -45,20 +41,19 @@ class ChannelFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
return inflater.inflate(R.layout.fragment_channel, container, false)
|
return inflater.inflate(R.layout.fragment_channel, container, false)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
channel_id = channel_id!!.replace("/channel/","")
|
channel_id = channel_id!!.replace("/channel/", "")
|
||||||
view.findViewById<TextView>(R.id.channel_name).text=channel_id
|
view.findViewById<TextView>(R.id.channel_name).text = channel_id
|
||||||
val recyclerView = view.findViewById<RecyclerView>(R.id.channel_recView)
|
val recyclerView = view.findViewById<RecyclerView>(R.id.channel_recView)
|
||||||
recyclerView.layoutManager = LinearLayoutManager(context)
|
recyclerView.layoutManager = LinearLayoutManager(context)
|
||||||
refreshLayout = view.findViewById(R.id.channel_refresh)
|
refreshLayout = view.findViewById(R.id.channel_refresh)
|
||||||
@ -68,7 +63,7 @@ class ChannelFragment : Fragment() {
|
|||||||
fetchChannel(view)
|
fetchChannel(view)
|
||||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
val subButton = view.findViewById<MaterialButton>(R.id.channel_subscribe)
|
val subButton = view.findViewById<MaterialButton>(R.id.channel_subscribe)
|
||||||
if (sharedPref?.getString("token","") != "") {
|
if (sharedPref?.getString("token", "") != "") {
|
||||||
isSubscribed(subButton)
|
isSubscribed(subButton)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,28 +76,26 @@ class ChannelFragment : Fragment() {
|
|||||||
scrollView.viewTreeObserver
|
scrollView.viewTreeObserver
|
||||||
.addOnScrollChangedListener {
|
.addOnScrollChangedListener {
|
||||||
if (scrollView.getChildAt(0).bottom
|
if (scrollView.getChildAt(0).bottom
|
||||||
== (scrollView.height + scrollView.scrollY)) {
|
== (scrollView.height + scrollView.scrollY)
|
||||||
//scroll view is at bottom
|
) {
|
||||||
if(nextPage!=null && !isLoading){
|
// scroll view is at bottom
|
||||||
isLoading=true
|
if (nextPage != null && !isLoading) {
|
||||||
refreshLayout?.isRefreshing = true;
|
isLoading = true
|
||||||
|
refreshLayout?.isRefreshing = true
|
||||||
fetchNextPage()
|
fetchNextPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isSubscribed(button: MaterialButton){
|
private fun isSubscribed(button: MaterialButton) {
|
||||||
@SuppressLint("ResourceAsColor")
|
@SuppressLint("ResourceAsColor")
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
RetrofitInstance.api.isSubscribed(channel_id!!,sharedPref?.getString("token","")!!)
|
RetrofitInstance.api.isSubscribed(channel_id!!, sharedPref?.getString("token", "")!!)
|
||||||
} catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
@ -112,33 +105,34 @@ class ChannelFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
if (response.subscribed==true){
|
if (response.subscribed == true) {
|
||||||
isSubscribed=true
|
isSubscribed = true
|
||||||
button.text=getString(R.string.unsubscribe)
|
button.text = getString(R.string.unsubscribe)
|
||||||
}
|
}
|
||||||
if(response.subscribed!=null){
|
if (response.subscribed != null) {
|
||||||
button.setOnClickListener {
|
button.setOnClickListener {
|
||||||
if(isSubscribed){
|
if (isSubscribed) {
|
||||||
unsubscribe()
|
unsubscribe()
|
||||||
button.text=getString(R.string.subscribe)
|
button.text = getString(R.string.subscribe)
|
||||||
}else{
|
} else {
|
||||||
subscribe()
|
subscribe()
|
||||||
button.text=getString(R.string.unsubscribe)
|
button.text = getString(R.string.unsubscribe)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun subscribe(){
|
private fun subscribe() {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
RetrofitInstance.api.subscribe(sharedPref?.getString("token","")!!, Subscribe(channel_id))
|
RetrofitInstance.api.subscribe(sharedPref?.getString("token", "")!!, Subscribe(channel_id))
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
@ -146,18 +140,18 @@ class ChannelFragment : Fragment() {
|
|||||||
Log.e(TAG, "HttpException, unexpected response$e")
|
Log.e(TAG, "HttpException, unexpected response$e")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
isSubscribed=true
|
isSubscribed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
}
|
}
|
||||||
private fun unsubscribe(){
|
private fun unsubscribe() {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
RetrofitInstance.api.unsubscribe(sharedPref?.getString("token","")!!, Subscribe(channel_id))
|
RetrofitInstance.api.unsubscribe(sharedPref?.getString("token", "")!!, Subscribe(channel_id))
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
@ -165,37 +159,37 @@ class ChannelFragment : Fragment() {
|
|||||||
Log.e(TAG, "HttpException, unexpected response")
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
isSubscribed=false
|
isSubscribed = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchChannel(view: View){
|
private fun fetchChannel(view: View) {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.getChannel(channel_id!!)
|
RetrofitInstance.api.getChannel(channel_id!!)
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
refreshLayout?.isRefreshing = false;
|
refreshLayout?.isRefreshing = false
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
refreshLayout?.isRefreshing = false;
|
refreshLayout?.isRefreshing = false
|
||||||
Log.e(TAG, "HttpException, unexpected response")
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
nextPage = response.nextpage
|
nextPage = response.nextpage
|
||||||
isLoading=false
|
isLoading = false
|
||||||
refreshLayout?.isRefreshing = false;
|
refreshLayout?.isRefreshing = false
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
view.findViewById<ScrollView>(R.id.channel_scrollView).visibility = View.VISIBLE
|
view.findViewById<ScrollView>(R.id.channel_scrollView).visibility = View.VISIBLE
|
||||||
val channelName = view.findViewById<TextView>(R.id.channel_name)
|
val channelName = view.findViewById<TextView>(R.id.channel_name)
|
||||||
channelName.text = if (response.name?.length!! > 18) response.name.toString().substring(0,16) + "..." else response.name
|
channelName.text = if (response.name?.length!! > 18) response.name.toString().substring(0, 16) + "..." else response.name
|
||||||
val channelVerified = view.findViewById<ImageView>(R.id.channel_verified)
|
val channelVerified = view.findViewById<ImageView>(R.id.channel_verified)
|
||||||
if (response.verified) channelVerified.visibility = View.VISIBLE
|
if (response.verified) channelVerified.visibility = View.VISIBLE
|
||||||
view.findViewById<TextView>(R.id.channel_subs).text=resources.getString(R.string.subscribers, response.subscriberCount.formatShort())
|
view.findViewById<TextView>(R.id.channel_subs).text = resources.getString(R.string.subscribers, response.subscriberCount.formatShort())
|
||||||
val channelDescription = view.findViewById<TextView>(R.id.channel_description)
|
val channelDescription = view.findViewById<TextView>(R.id.channel_description)
|
||||||
if (response.description?.trim() == "") channelDescription.visibility = View.GONE else channelDescription.text = response.description?.trim()
|
if (response.description?.trim() == "") channelDescription.visibility = View.GONE else channelDescription.text = response.description?.trim()
|
||||||
val bannerImage = view.findViewById<ImageView>(R.id.channel_banner)
|
val bannerImage = view.findViewById<ImageView>(R.id.channel_banner)
|
||||||
@ -204,18 +198,17 @@ class ChannelFragment : Fragment() {
|
|||||||
Picasso.get().load(response.avatarUrl).into(channelImage)
|
Picasso.get().load(response.avatarUrl).into(channelImage)
|
||||||
channelAdapter = ChannelAdapter(response.relatedStreams!!.toMutableList())
|
channelAdapter = ChannelAdapter(response.relatedStreams!!.toMutableList())
|
||||||
view.findViewById<RecyclerView>(R.id.channel_recView).adapter = channelAdapter
|
view.findViewById<RecyclerView>(R.id.channel_recView).adapter = channelAdapter
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
}
|
}
|
||||||
private fun fetchNextPage(){
|
private fun fetchNextPage() {
|
||||||
fun run() {
|
fun run() {
|
||||||
|
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.getChannelNextPage(channel_id!!,nextPage!!)
|
RetrofitInstance.api.getChannelNextPage(channel_id!!, nextPage!!)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
refreshLayout?.isRefreshing = false
|
refreshLayout?.isRefreshing = false
|
||||||
println(e)
|
println(e)
|
||||||
@ -223,12 +216,12 @@ class ChannelFragment : Fragment() {
|
|||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
refreshLayout?.isRefreshing = false
|
refreshLayout?.isRefreshing = false
|
||||||
Log.e(TAG, "HttpException, unexpected response,"+e.response())
|
Log.e(TAG, "HttpException, unexpected response," + e.response())
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
nextPage = response.nextpage
|
nextPage = response.nextpage
|
||||||
channelAdapter?.updateItems(response.relatedStreams!!)
|
channelAdapter?.updateItems(response.relatedStreams!!)
|
||||||
isLoading=false
|
isLoading = false
|
||||||
refreshLayout?.isRefreshing = false
|
refreshLayout?.isRefreshing = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,8 +237,8 @@ class ChannelFragment : Fragment() {
|
|||||||
val scrollView = view?.findViewById<ScrollView>(R.id.channel_scrollView)
|
val scrollView = view?.findViewById<ScrollView>(R.id.channel_scrollView)
|
||||||
scrollView?.viewTreeObserver?.removeOnScrollChangedListener {
|
scrollView?.viewTreeObserver?.removeOnScrollChangedListener {
|
||||||
}
|
}
|
||||||
channelAdapter=null
|
channelAdapter = null
|
||||||
view?.findViewById<RecyclerView>(R.id.channel_recView)?.adapter=null
|
view?.findViewById<RecyclerView>(R.id.channel_recView)?.adapter = null
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -39,11 +39,10 @@ class CreatePlaylistDialog : DialogFragment() {
|
|||||||
val createPlaylistBtn = rootView.findViewById<Button>(R.id.create_new_playlist)
|
val createPlaylistBtn = rootView.findViewById<Button>(R.id.create_new_playlist)
|
||||||
createPlaylistBtn.setOnClickListener {
|
createPlaylistBtn.setOnClickListener {
|
||||||
var listName = playlistName.text.toString()
|
var listName = playlistName.text.toString()
|
||||||
if(listName != "") {
|
if (listName != "") {
|
||||||
setFragmentResult("key_parent", bundleOf("playlistName" to "$listName"))
|
setFragmentResult("key_parent", bundleOf("playlistName" to "$listName"))
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Toast.makeText(context, R.string.emptyPlaylistName, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, R.string.emptyPlaylistName, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,11 @@ import android.annotation.SuppressLint
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import com.google.android.exoplayer2.ui.PlayerView
|
|
||||||
import com.google.android.exoplayer2.ui.StyledPlayerControlView
|
|
||||||
import com.google.android.exoplayer2.ui.StyledPlayerView
|
import com.google.android.exoplayer2.ui.StyledPlayerView
|
||||||
|
|
||||||
internal class CustomExoPlayerView(
|
internal class CustomExoPlayerView(
|
||||||
context: Context, attributeSet: AttributeSet? = null
|
context: Context,
|
||||||
|
attributeSet: AttributeSet? = null
|
||||||
) : StyledPlayerView(context, attributeSet) {
|
) : StyledPlayerView(context, attributeSet) {
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@ -18,7 +17,7 @@ internal class CustomExoPlayerView(
|
|||||||
MotionEvent.ACTION_DOWN -> {
|
MotionEvent.ACTION_DOWN -> {
|
||||||
if (isControllerFullyVisible) {
|
if (isControllerFullyVisible) {
|
||||||
hideController()
|
hideController()
|
||||||
}else {
|
} else {
|
||||||
showController()
|
showController()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import androidx.core.text.HtmlCompat
|
|||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
|
||||||
|
|
||||||
class DownloadDialog : DialogFragment() {
|
class DownloadDialog : DialogFragment() {
|
||||||
private val TAG = "DownloadDialog"
|
private val TAG = "DownloadDialog"
|
||||||
var vidName = arrayListOf<String>()
|
var vidName = arrayListOf<String>()
|
||||||
@ -37,9 +36,9 @@ class DownloadDialog : DialogFragment() {
|
|||||||
val inflater = requireActivity().layoutInflater
|
val inflater = requireActivity().layoutInflater
|
||||||
var view: View = inflater.inflate(R.layout.dialog_download, null)
|
var view: View = inflater.inflate(R.layout.dialog_download, null)
|
||||||
val videoSpinner = view.findViewById<Spinner>(R.id.video_spinner)
|
val videoSpinner = view.findViewById<Spinner>(R.id.video_spinner)
|
||||||
val videoArrayAdapter =ArrayAdapter<String>(requireContext(),android.R.layout.simple_spinner_item,vidName)
|
val videoArrayAdapter = ArrayAdapter<String>(requireContext(), android.R.layout.simple_spinner_item, vidName)
|
||||||
videoArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
videoArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||||
videoSpinner.adapter=videoArrayAdapter
|
videoSpinner.adapter = videoArrayAdapter
|
||||||
videoSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
videoSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||||
override fun onItemSelected(
|
override fun onItemSelected(
|
||||||
parent: AdapterView<*>,
|
parent: AdapterView<*>,
|
||||||
@ -48,12 +47,12 @@ class DownloadDialog : DialogFragment() {
|
|||||||
id: Long
|
id: Long
|
||||||
) {
|
) {
|
||||||
selectedVideo = position
|
selectedVideo = position
|
||||||
Log.d(TAG,selectedVideo.toString())
|
Log.d(TAG, selectedVideo.toString())
|
||||||
}
|
}
|
||||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||||
}
|
}
|
||||||
val audioSpinner = view.findViewById<Spinner>(R.id.audio_spinner)
|
val audioSpinner = view.findViewById<Spinner>(R.id.audio_spinner)
|
||||||
val audioArrayAdapter = ArrayAdapter<String>(requireContext(),android.R.layout.simple_spinner_item,audioName)
|
val audioArrayAdapter = ArrayAdapter<String>(requireContext(), android.R.layout.simple_spinner_item, audioName)
|
||||||
audioArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
audioArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||||
audioSpinner.adapter = audioArrayAdapter
|
audioSpinner.adapter = audioArrayAdapter
|
||||||
audioSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
audioSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||||
@ -64,7 +63,7 @@ class DownloadDialog : DialogFragment() {
|
|||||||
id: Long
|
id: Long
|
||||||
) {
|
) {
|
||||||
selectedAudio = position
|
selectedAudio = position
|
||||||
Log.d(TAG,selectedAudio.toString())
|
Log.d(TAG, selectedAudio.toString())
|
||||||
}
|
}
|
||||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||||
}
|
}
|
||||||
@ -72,16 +71,16 @@ class DownloadDialog : DialogFragment() {
|
|||||||
radioGroup.setOnCheckedChangeListener { group, checkedId ->
|
radioGroup.setOnCheckedChangeListener { group, checkedId ->
|
||||||
val radio: RadioButton = view.findViewById(checkedId)
|
val radio: RadioButton = view.findViewById(checkedId)
|
||||||
extension = radio.text.toString()
|
extension = radio.text.toString()
|
||||||
Log.d(TAG,extension)
|
Log.d(TAG, extension)
|
||||||
}
|
}
|
||||||
view.findViewById<Button>(R.id.download).setOnClickListener {
|
view.findViewById<Button>(R.id.download).setOnClickListener {
|
||||||
val intent = Intent(context,DownloadService::class.java)
|
val intent = Intent(context, DownloadService::class.java)
|
||||||
intent.putExtra("videoId",videoId)
|
intent.putExtra("videoId", videoId)
|
||||||
intent.putExtra("videoUrl",vidUrl[selectedVideo])
|
intent.putExtra("videoUrl", vidUrl[selectedVideo])
|
||||||
intent.putExtra("audioUrl",audioUrl[selectedAudio])
|
intent.putExtra("audioUrl", audioUrl[selectedAudio])
|
||||||
intent.putExtra("duration",duration)
|
intent.putExtra("duration", duration)
|
||||||
intent.putExtra("extension",extension)
|
intent.putExtra("extension", extension)
|
||||||
//intent.putExtra("command","-y -i ${response.videoStreams[which].url} -i ${response.audioStreams!![0].url} -c copy ${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)}/${videoId}.mkv")
|
// intent.putExtra("command","-y -i ${response.videoStreams[which].url} -i ${response.audioStreams!![0].url} -c copy ${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)}/${videoId}.mkv")
|
||||||
context?.startService(intent)
|
context?.startService(intent)
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
|
@ -16,17 +16,16 @@ import androidx.core.app.NotificationManagerCompat
|
|||||||
import com.arthenica.ffmpegkit.FFmpegKit
|
import com.arthenica.ffmpegkit.FFmpegKit
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
var IS_DOWNLOAD_RUNNING = false
|
var IS_DOWNLOAD_RUNNING = false
|
||||||
class DownloadService : Service(){
|
class DownloadService : Service() {
|
||||||
val TAG = "DownloadService"
|
val TAG = "DownloadService"
|
||||||
private var downloadId: Long =-1
|
private var downloadId: Long = -1
|
||||||
private lateinit var videoId: String
|
private lateinit var videoId: String
|
||||||
private lateinit var videoUrl: String
|
private lateinit var videoUrl: String
|
||||||
private lateinit var audioUrl: String
|
private lateinit var audioUrl: String
|
||||||
private lateinit var extension: String
|
private lateinit var extension: String
|
||||||
private var duration: Int = 0
|
private var duration: Int = 0
|
||||||
//private lateinit var command: String
|
// private lateinit var command: String
|
||||||
private lateinit var audioDir: File
|
private lateinit var audioDir: File
|
||||||
private lateinit var videoDir: File
|
private lateinit var videoDir: File
|
||||||
lateinit var service: NotificationManager
|
lateinit var service: NotificationManager
|
||||||
@ -41,29 +40,31 @@ class DownloadService : Service(){
|
|||||||
videoUrl = intent.getStringExtra("videoUrl")!!
|
videoUrl = intent.getStringExtra("videoUrl")!!
|
||||||
audioUrl = intent.getStringExtra("audioUrl")!!
|
audioUrl = intent.getStringExtra("audioUrl")!!
|
||||||
extension = intent.getStringExtra("extension")!!
|
extension = intent.getStringExtra("extension")!!
|
||||||
//command = intent.getStringExtra("command")!!
|
// command = intent.getStringExtra("command")!!
|
||||||
duration = intent.getIntExtra("duration",1)
|
duration = intent.getIntExtra("duration", 1)
|
||||||
service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
val channelId =
|
val channelId =
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val chan = NotificationChannel("service",
|
val chan = NotificationChannel(
|
||||||
"DownloadService", NotificationManager.IMPORTANCE_NONE)
|
"service",
|
||||||
chan.lightColor = Color.BLUE
|
"DownloadService", NotificationManager.IMPORTANCE_NONE
|
||||||
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
|
)
|
||||||
service.createNotificationChannel(chan)
|
chan.lightColor = Color.BLUE
|
||||||
"service"
|
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
|
||||||
} else {
|
service.createNotificationChannel(chan)
|
||||||
// If earlier version channel ID is not used
|
"service"
|
||||||
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
} else {
|
||||||
""
|
// If earlier version channel ID is not used
|
||||||
}
|
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
||||||
|
""
|
||||||
|
}
|
||||||
var pendingIntent: PendingIntent? = null
|
var pendingIntent: PendingIntent? = null
|
||||||
pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_MUTABLE)
|
PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_MUTABLE)
|
||||||
} else {
|
} else {
|
||||||
PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
|
PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
|
||||||
}
|
}
|
||||||
//Creating a notification and setting its various attributes
|
// Creating a notification and setting its various attributes
|
||||||
notification =
|
notification =
|
||||||
NotificationCompat.Builder(this@DownloadService, channelId)
|
NotificationCompat.Builder(this@DownloadService, channelId)
|
||||||
.setSmallIcon(R.drawable.ic_download)
|
.setSmallIcon(R.drawable.ic_download)
|
||||||
@ -75,7 +76,7 @@ class DownloadService : Service(){
|
|||||||
.setProgress(100, 0, true)
|
.setProgress(100, 0, true)
|
||||||
.setContentIntent(pendingIntent)
|
.setContentIntent(pendingIntent)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
startForeground(1,notification.build())
|
startForeground(1, notification.build())
|
||||||
downloadManager()
|
downloadManager()
|
||||||
|
|
||||||
return super.onStartCommand(intent, flags, startId)
|
return super.onStartCommand(intent, flags, startId)
|
||||||
@ -112,10 +113,10 @@ class DownloadService : Service(){
|
|||||||
val downloadManager: DownloadManager =
|
val downloadManager: DownloadManager =
|
||||||
applicationContext.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
|
applicationContext.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
|
||||||
downloadId = downloadManager.enqueue(request)
|
downloadId = downloadManager.enqueue(request)
|
||||||
if(audioUrl==""){downloadId = 0L}
|
if (audioUrl == "") { downloadId = 0L }
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
Log.e(TAG, "download error $e")
|
Log.e(TAG, "download error $e")
|
||||||
try{
|
try {
|
||||||
downloadId = 0L
|
downloadId = 0L
|
||||||
val request: DownloadManager.Request =
|
val request: DownloadManager.Request =
|
||||||
DownloadManager.Request(Uri.parse(audioUrl))
|
DownloadManager.Request(Uri.parse(audioUrl))
|
||||||
@ -128,36 +129,35 @@ class DownloadService : Service(){
|
|||||||
val downloadManager: DownloadManager =
|
val downloadManager: DownloadManager =
|
||||||
applicationContext.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
|
applicationContext.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
|
||||||
downloadManager.enqueue(request)
|
downloadManager.enqueue(request)
|
||||||
|
} catch (e: Exception) {
|
||||||
}catch (e: Exception){
|
|
||||||
Log.e(TAG, "audio download error $e")
|
Log.e(TAG, "audio download error $e")
|
||||||
stopService(Intent(this,DownloadService::class.java))}
|
stopService(Intent(this, DownloadService::class.java))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val onDownloadComplete: BroadcastReceiver = object : BroadcastReceiver() {
|
private val onDownloadComplete: BroadcastReceiver = object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
//Fetching the download id received with the broadcast
|
// Fetching the download id received with the broadcast
|
||||||
val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
|
val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
|
||||||
//Checking if the received broadcast is for our enqueued download by matching download id
|
// Checking if the received broadcast is for our enqueued download by matching download id
|
||||||
if (downloadId == id) {
|
if (downloadId == id) {
|
||||||
downloadId=0L
|
downloadId = 0L
|
||||||
try{
|
try {
|
||||||
val request: DownloadManager.Request =
|
val request: DownloadManager.Request =
|
||||||
DownloadManager.Request(Uri.parse(audioUrl))
|
DownloadManager.Request(Uri.parse(audioUrl))
|
||||||
.setTitle("Audio") // Title of the Download Notification
|
.setTitle("Audio") // Title of the Download Notification
|
||||||
.setDescription("Downloading") // Description of the Download Notification
|
.setDescription("Downloading") // Description of the Download Notification
|
||||||
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE) // Visibility of the download Notification
|
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE) // Visibility of the download Notification
|
||||||
.setDestinationUri(Uri.fromFile(audioDir))
|
.setDestinationUri(Uri.fromFile(audioDir))
|
||||||
.setAllowedOverMetered(true) // Set if download is allowed on Mobile network
|
.setAllowedOverMetered(true) // Set if download is allowed on Mobile network
|
||||||
.setAllowedOverRoaming(true) //
|
.setAllowedOverRoaming(true) //
|
||||||
val downloadManager: DownloadManager =
|
val downloadManager: DownloadManager =
|
||||||
applicationContext.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
|
applicationContext.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
|
||||||
downloadManager.enqueue(request)
|
downloadManager.enqueue(request)
|
||||||
}catch (e: Exception){}
|
} catch (e: Exception) {}
|
||||||
}else if (downloadId == 0L){
|
} else if (downloadId == 0L) {
|
||||||
val libreTube = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),"LibreTube")
|
val libreTube = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LibreTube")
|
||||||
if (!libreTube.exists()) {
|
if (!libreTube.exists()) {
|
||||||
libreTube.mkdirs()
|
libreTube.mkdirs()
|
||||||
Log.e(TAG, "libreTube Directory make")
|
Log.e(TAG, "libreTube Directory make")
|
||||||
@ -165,18 +165,19 @@ class DownloadService : Service(){
|
|||||||
Log.e(TAG, "libreTube Directory already have")
|
Log.e(TAG, "libreTube Directory already have")
|
||||||
}
|
}
|
||||||
var command: String = when {
|
var command: String = when {
|
||||||
videoUrl=="" -> {
|
videoUrl == "" -> {
|
||||||
"-y -i $audioDir -c copy ${libreTube}/${videoId}-audio$extension"
|
"-y -i $audioDir -c copy $libreTube/$videoId-audio$extension"
|
||||||
}
|
}
|
||||||
audioUrl=="" -> {
|
audioUrl == "" -> {
|
||||||
"-y -i $videoDir -c copy ${libreTube}/${videoId}-video$extension"
|
"-y -i $videoDir -c copy $libreTube/$videoId-video$extension"
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
"-y -i $videoDir -i $audioDir -c copy ${libreTube}/${videoId}$extension"
|
"-y -i $videoDir -i $audioDir -c copy $libreTube/${videoId}$extension"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notification.setContentTitle("Muxing")
|
notification.setContentTitle("Muxing")
|
||||||
FFmpegKit.executeAsync(command,
|
FFmpegKit.executeAsync(
|
||||||
|
command,
|
||||||
{ session ->
|
{ session ->
|
||||||
val state = session.state
|
val state = session.state
|
||||||
val returnCode = session.returnCode
|
val returnCode = session.returnCode
|
||||||
@ -194,7 +195,7 @@ class DownloadService : Service(){
|
|||||||
val folder_main = ".tmp"
|
val folder_main = ".tmp"
|
||||||
val f = File(path, folder_main)
|
val f = File(path, folder_main)
|
||||||
f.deleteRecursively()
|
f.deleteRecursively()
|
||||||
if (returnCode.toString()!="0"){
|
if (returnCode.toString() != "0") {
|
||||||
var builder = NotificationCompat.Builder(this@DownloadService, "failed")
|
var builder = NotificationCompat.Builder(this@DownloadService, "failed")
|
||||||
.setSmallIcon(R.drawable.ic_download)
|
.setSmallIcon(R.drawable.ic_download)
|
||||||
.setContentTitle(resources.getString(R.string.downloadfailed))
|
.setContentTitle(resources.getString(R.string.downloadfailed))
|
||||||
@ -207,13 +208,14 @@ class DownloadService : Service(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
stopForeground(true)
|
stopForeground(true)
|
||||||
stopService(Intent(this@DownloadService,DownloadService::class.java))
|
stopService(Intent(this@DownloadService, DownloadService::class.java))
|
||||||
}, {
|
}, {
|
||||||
// CALLED WHEN SESSION PRINTS LOGS
|
// CALLED WHEN SESSION PRINTS LOGS
|
||||||
Log.e(TAG,it.message.toString())
|
Log.e(TAG, it.message.toString())
|
||||||
}) {
|
}
|
||||||
|
) {
|
||||||
// CALLED WHEN SESSION GENERATES STATISTICS
|
// CALLED WHEN SESSION GENERATES STATISTICS
|
||||||
Log.e(TAG+"stat",it.time.toString())
|
Log.e(TAG + "stat", it.time.toString())
|
||||||
/*val progress = it.time/(10*duration!!)
|
/*val progress = it.time/(10*duration!!)
|
||||||
if (progress<1){
|
if (progress<1){
|
||||||
notification
|
notification
|
||||||
@ -221,7 +223,6 @@ class DownloadService : Service(){
|
|||||||
service.notify(1,notification.build())
|
service.notify(1,notification.build())
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,10 +246,9 @@ class DownloadService : Service(){
|
|||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
try {
|
try {
|
||||||
unregisterReceiver(onDownloadComplete)
|
unregisterReceiver(onDownloadComplete)
|
||||||
}catch (e: Exception){}
|
} catch (e: Exception) {}
|
||||||
IS_DOWNLOAD_RUNNING = false
|
IS_DOWNLOAD_RUNNING = false
|
||||||
Log.d(TAG,"dl finished!")
|
Log.d(TAG, "dl finished!")
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,23 +2,21 @@ package com.github.libretube
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ProgressBar
|
import android.widget.ProgressBar
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
|
||||||
import okhttp3.*
|
|
||||||
import retrofit2.HttpException
|
|
||||||
import com.github.libretube.adapters.TrendingAdapter
|
import com.github.libretube.adapters.TrendingAdapter
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import okhttp3.*
|
||||||
|
import retrofit2.HttpException
|
||||||
|
|
||||||
class Home : Fragment() {
|
class Home : Fragment() {
|
||||||
|
|
||||||
@ -31,51 +29,47 @@ class Home : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
|
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
return inflater.inflate(R.layout.fragment_home, container, false)
|
return inflater.inflate(R.layout.fragment_home, container, false)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
val recyclerView = view.findViewById<RecyclerView>(R.id.recview)
|
val recyclerView = view.findViewById<RecyclerView>(R.id.recview)
|
||||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
val grid = sharedPreferences.getString("grid", resources.getInteger(R.integer.grid_items).toString())!!
|
val grid = sharedPreferences.getString("grid", resources.getInteger(R.integer.grid_items).toString())!!
|
||||||
recyclerView.layoutManager = GridLayoutManager(view.context, grid.toInt())
|
recyclerView.layoutManager = GridLayoutManager(view.context, grid.toInt())
|
||||||
val progressbar = view.findViewById<ProgressBar>(R.id.progressBar)
|
val progressbar = view.findViewById<ProgressBar>(R.id.progressBar)
|
||||||
fetchJson(progressbar,recyclerView)
|
fetchJson(progressbar, recyclerView)
|
||||||
refreshLayout = view.findViewById(R.id.home_refresh)
|
refreshLayout = view.findViewById(R.id.home_refresh)
|
||||||
refreshLayout?.isEnabled = true
|
refreshLayout?.isEnabled = true
|
||||||
refreshLayout?.setOnRefreshListener {
|
refreshLayout?.setOnRefreshListener {
|
||||||
Log.d(TAG,"hmm")
|
Log.d(TAG, "hmm")
|
||||||
fetchJson(progressbar,recyclerView)
|
fetchJson(progressbar, recyclerView)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun fetchJson(progressBar: ProgressBar, recyclerView: RecyclerView) {
|
||||||
private fun fetchJson(progressBar: ProgressBar, recyclerView: RecyclerView) {
|
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
RetrofitInstance.api.getTrending(sharedPreferences.getString("region", "US")!!)
|
RetrofitInstance.api.getTrending(sharedPreferences.getString("region", "US")!!)
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
Toast.makeText(context,R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
Log.e(TAG, "HttpException, unexpected response")
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
Toast.makeText(context,R.string.server_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}finally {
|
} finally {
|
||||||
refreshLayout?.isRefreshing = false
|
refreshLayout?.isRefreshing = false
|
||||||
}
|
}
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
@ -84,8 +78,7 @@ class Home : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
|
|
||||||
}
|
}
|
||||||
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
||||||
this ?: return
|
this ?: return
|
||||||
@ -94,9 +87,9 @@ class Home : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
view?.findViewById<RecyclerView>(R.id.recview)?.adapter=null
|
view?.findViewById<RecyclerView>(R.id.recview)?.adapter = null
|
||||||
refreshLayout = null
|
refreshLayout = null
|
||||||
Log.e(TAG,"destroyview")
|
Log.e(TAG, "destroyview")
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,8 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import com.github.libretube.adapters.PlaylistsAdapter
|
import com.github.libretube.adapters.PlaylistsAdapter
|
||||||
import com.github.libretube.obj.Playlists
|
import com.github.libretube.obj.Playlists
|
||||||
import retrofit2.HttpException
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import retrofit2.HttpException
|
||||||
|
|
||||||
class Library : Fragment() {
|
class Library : Fragment() {
|
||||||
|
|
||||||
@ -30,12 +29,12 @@ class Library : Fragment() {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
arguments?.let {
|
arguments?.let {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
@ -47,107 +46,104 @@ class Library : Fragment() {
|
|||||||
playlistRecyclerView = view.findViewById(R.id.playlist_recView)
|
playlistRecyclerView = view.findViewById(R.id.playlist_recView)
|
||||||
playlistRecyclerView.layoutManager = LinearLayoutManager(view.context)
|
playlistRecyclerView.layoutManager = LinearLayoutManager(view.context)
|
||||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
token = sharedPref?.getString("token","")!!
|
token = sharedPref?.getString("token", "")!!
|
||||||
refreshLayout = view.findViewById(R.id.playlist_refresh)
|
refreshLayout = view.findViewById(R.id.playlist_refresh)
|
||||||
if(token!="") {
|
if (token != "") {
|
||||||
view.findViewById<ImageView>(R.id.boogh2).visibility=View.GONE
|
view.findViewById<ImageView>(R.id.boogh2).visibility = View.GONE
|
||||||
view.findViewById<TextView>(R.id.textLike2).visibility=View.GONE
|
view.findViewById<TextView>(R.id.textLike2).visibility = View.GONE
|
||||||
fetchPlaylists(view)
|
fetchPlaylists(view)
|
||||||
refreshLayout?.isEnabled = true
|
refreshLayout?.isEnabled = true
|
||||||
refreshLayout?.setOnRefreshListener {
|
refreshLayout?.setOnRefreshListener {
|
||||||
Log.d(TAG,"hmm")
|
Log.d(TAG, "hmm")
|
||||||
fetchPlaylists(view)
|
fetchPlaylists(view)
|
||||||
}
|
}
|
||||||
view.findViewById<Button>(R.id.create_playlist).setOnClickListener {
|
view.findViewById<Button>(R.id.create_playlist).setOnClickListener {
|
||||||
val newFragment = CreatePlaylistDialog()
|
val newFragment = CreatePlaylistDialog()
|
||||||
newFragment.show(childFragmentManager, "Create Playlist")
|
newFragment.show(childFragmentManager, "Create Playlist")
|
||||||
}
|
}
|
||||||
childFragmentManager.setFragmentResultListener("key_parent", this) { _, result->
|
childFragmentManager.setFragmentResultListener("key_parent", this) { _, result ->
|
||||||
val playlistName = result.getString("playlistName")
|
val playlistName = result.getString("playlistName")
|
||||||
createPlaylist("$playlistName", view);
|
createPlaylist("$playlistName", view)
|
||||||
}
|
}
|
||||||
} else{
|
} else {
|
||||||
refreshLayout?.isEnabled = false
|
refreshLayout?.isEnabled = false
|
||||||
view.findViewById<Button>(R.id.create_playlist).visibility = View.GONE
|
view.findViewById<Button>(R.id.create_playlist).visibility = View.GONE
|
||||||
with(view.findViewById<ImageView>(R.id.boogh2)){
|
with(view.findViewById<ImageView>(R.id.boogh2)) {
|
||||||
visibility=View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
setImageResource(R.drawable.ic_login)
|
setImageResource(R.drawable.ic_login)
|
||||||
}
|
}
|
||||||
with(view.findViewById<TextView>(R.id.textLike2)){
|
with(view.findViewById<TextView>(R.id.textLike2)) {
|
||||||
visibility=View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
text = getString(R.string.please_login)
|
text = getString(R.string.please_login)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchPlaylists(view: View){
|
private fun fetchPlaylists(view: View) {
|
||||||
fun run() {
|
fun run() {
|
||||||
refreshLayout?.isRefreshing = true
|
refreshLayout?.isRefreshing = true
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.playlists(token)
|
RetrofitInstance.api.playlists(token)
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
Toast.makeText(context,R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
Log.e(TAG, "HttpException, unexpected response")
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
Toast.makeText(context,R.string.server_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}finally {
|
} finally {
|
||||||
refreshLayout?.isRefreshing = false
|
refreshLayout?.isRefreshing = false
|
||||||
}
|
}
|
||||||
if (response.isNotEmpty()){
|
if (response.isNotEmpty()) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
with(view.findViewById<ImageView>(R.id.boogh2)){
|
with(view.findViewById<ImageView>(R.id.boogh2)) {
|
||||||
visibility=View.GONE
|
visibility = View.GONE
|
||||||
}
|
}
|
||||||
with(view.findViewById<TextView>(R.id.textLike2)){
|
with(view.findViewById<TextView>(R.id.textLike2)) {
|
||||||
visibility=View.GONE
|
visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val playlistsAdapter = PlaylistsAdapter(response.toMutableList(),requireActivity())
|
val playlistsAdapter = PlaylistsAdapter(response.toMutableList(), requireActivity())
|
||||||
playlistRecyclerView.adapter= playlistsAdapter
|
playlistRecyclerView.adapter = playlistsAdapter
|
||||||
}else{
|
} else {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
with(view.findViewById<ImageView>(R.id.boogh2)){
|
with(view.findViewById<ImageView>(R.id.boogh2)) {
|
||||||
visibility=View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
setImageResource(R.drawable.ic_list)
|
setImageResource(R.drawable.ic_list)
|
||||||
}
|
}
|
||||||
with(view.findViewById<TextView>(R.id.textLike2)){
|
with(view.findViewById<TextView>(R.id.textLike2)) {
|
||||||
visibility=View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
text = getString(R.string.emptyList)
|
text = getString(R.string.emptyList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
}
|
}
|
||||||
private fun createPlaylist(name: String, view: View){
|
private fun createPlaylist(name: String, view: View) {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.createPlaylist(token, Playlists(name = name))
|
RetrofitInstance.api.createPlaylist(token, Playlists(name = name))
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
Toast.makeText(context,R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
Log.e(TAG, "HttpException, unexpected response $e")
|
Log.e(TAG, "HttpException, unexpected response $e")
|
||||||
Toast.makeText(context,R.string.server_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
if (response != null){
|
if (response != null) {
|
||||||
Toast.makeText(context,R.string.playlistCreated, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.playlistCreated, Toast.LENGTH_SHORT).show()
|
||||||
fetchPlaylists(view)
|
fetchPlaylists(view)
|
||||||
}else{
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
|
@ -2,7 +2,6 @@ package com.github.libretube
|
|||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
@ -15,15 +14,12 @@ import androidx.appcompat.app.AlertDialog
|
|||||||
import androidx.core.text.HtmlCompat
|
import androidx.core.text.HtmlCompat
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import com.github.libretube.adapters.TrendingAdapter
|
|
||||||
import com.github.libretube.obj.Login
|
import com.github.libretube.obj.Login
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import org.w3c.dom.Text
|
import org.w3c.dom.Text
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
import kotlin.math.log
|
|
||||||
|
|
||||||
class LoginDialog : DialogFragment() {
|
class LoginDialog : DialogFragment() {
|
||||||
private val TAG = "LoginDialog"
|
private val TAG = "LoginDialog"
|
||||||
@ -33,43 +29,43 @@ class LoginDialog : DialogFragment() {
|
|||||||
return activity?.let {
|
return activity?.let {
|
||||||
val builder = MaterialAlertDialogBuilder(it)
|
val builder = MaterialAlertDialogBuilder(it)
|
||||||
// Get the layout inflater
|
// Get the layout inflater
|
||||||
val inflater = requireActivity().layoutInflater;
|
val inflater = requireActivity().layoutInflater
|
||||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
val token = sharedPref?.getString("token","")
|
val token = sharedPref?.getString("token", "")
|
||||||
var view: View
|
var view: View
|
||||||
Log.e("dafaq",token!!)
|
Log.e("dafaq", token!!)
|
||||||
if(token!=""){
|
if (token != "") {
|
||||||
val sharedPref2 = context?.getSharedPreferences("username", Context.MODE_PRIVATE)
|
val sharedPref2 = context?.getSharedPreferences("username", Context.MODE_PRIVATE)
|
||||||
val user = sharedPref2?.getString("username","")
|
val user = sharedPref2?.getString("username", "")
|
||||||
view = inflater.inflate(R.layout.dialog_logout, null)
|
view = inflater.inflate(R.layout.dialog_logout, null)
|
||||||
view.findViewById<TextView>(R.id.user).text = view.findViewById<TextView>(R.id.user).text.toString()+" ("+user+")"
|
view.findViewById<TextView>(R.id.user).text = view.findViewById<TextView>(R.id.user).text.toString() + " (" + user + ")"
|
||||||
view.findViewById<Button>(R.id.logout).setOnClickListener {
|
view.findViewById<Button>(R.id.logout).setOnClickListener {
|
||||||
Toast.makeText(context,R.string.loggedout, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.loggedout, Toast.LENGTH_SHORT).show()
|
||||||
val sharedPref = context?.getSharedPreferences("token",Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
with (sharedPref!!.edit()) {
|
with(sharedPref!!.edit()) {
|
||||||
putString("token","")
|
putString("token", "")
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
view = inflater.inflate(R.layout.dialog_login, null)
|
view = inflater.inflate(R.layout.dialog_login, null)
|
||||||
username=view.findViewById(R.id.username)
|
username = view.findViewById(R.id.username)
|
||||||
password=view.findViewById(R.id.password)
|
password = view.findViewById(R.id.password)
|
||||||
view.findViewById<Button>(R.id.login).setOnClickListener {
|
view.findViewById<Button>(R.id.login).setOnClickListener {
|
||||||
if(username.text.toString()!="" && password.text.toString()!=""){
|
if (username.text.toString() != "" && password.text.toString() != "") {
|
||||||
val login = Login(username.text.toString(),password.text.toString())
|
val login = Login(username.text.toString(), password.text.toString())
|
||||||
login(login)
|
login(login)
|
||||||
}else{
|
} else {
|
||||||
Toast.makeText(context,R.string.empty, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.empty, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
view.findViewById<Button>(R.id.register).setOnClickListener {
|
view.findViewById<Button>(R.id.register).setOnClickListener {
|
||||||
if(username.text.toString()!="" && password.text.toString()!=""){
|
if (username.text.toString() != "" && password.text.toString() != "") {
|
||||||
val login = Login(username.text.toString(),password.text.toString())
|
val login = Login(username.text.toString(), password.text.toString())
|
||||||
register(login)
|
register(login)
|
||||||
}else{
|
} else {
|
||||||
Toast.makeText(context,R.string.empty, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.empty, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,83 +84,80 @@ class LoginDialog : DialogFragment() {
|
|||||||
builder.create()
|
builder.create()
|
||||||
} ?: throw IllegalStateException("Activity cannot be null")
|
} ?: throw IllegalStateException("Activity cannot be null")
|
||||||
}
|
}
|
||||||
private fun login(login: Login){
|
private fun login(login: Login) {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.login(login)
|
RetrofitInstance.api.login(login)
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
Toast.makeText(context,R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
Log.e(TAG, "HttpException, unexpected response")
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
Toast.makeText(context,R.string.server_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG,"dafaq?"+e.toString())
|
Log.e(TAG, "dafaq?" + e.toString())
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
if (response.error!= null){
|
if (response.error != null) {
|
||||||
Toast.makeText(context, response.error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, response.error, Toast.LENGTH_SHORT).show()
|
||||||
}else if(response.token!=null){
|
} else if (response.token != null) {
|
||||||
Toast.makeText(context,R.string.loggedIn, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.loggedIn, Toast.LENGTH_SHORT).show()
|
||||||
val sharedPref = context?.getSharedPreferences("token",Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
with (sharedPref!!.edit()) {
|
with(sharedPref!!.edit()) {
|
||||||
putString("token",response.token)
|
putString("token", response.token)
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
val sharedPref2 = context?.getSharedPreferences("username",Context.MODE_PRIVATE)
|
val sharedPref2 = context?.getSharedPreferences("username", Context.MODE_PRIVATE)
|
||||||
with (sharedPref2!!.edit()) {
|
with(sharedPref2!!.edit()) {
|
||||||
putString("username",login.username)
|
putString("username", login.username)
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
}
|
}
|
||||||
private fun register(login: Login){
|
private fun register(login: Login) {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.register(login)
|
RetrofitInstance.api.register(login)
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
Toast.makeText(context,R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
Log.e(TAG, "HttpException, unexpected response")
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
Toast.makeText(context,R.string.server_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG,"dafaq?"+e.toString())
|
Log.e(TAG, "dafaq?" + e.toString())
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
if (response.error!= null){
|
if (response.error != null) {
|
||||||
Toast.makeText(context, response.error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, response.error, Toast.LENGTH_SHORT).show()
|
||||||
}else if(response.token!=null){
|
} else if (response.token != null) {
|
||||||
Toast.makeText(context,R.string.registered, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.registered, Toast.LENGTH_SHORT).show()
|
||||||
val sharedPref = context?.getSharedPreferences("token",Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
with (sharedPref!!.edit()) {
|
with(sharedPref!!.edit()) {
|
||||||
putString("token",response.token)
|
putString("token", response.token)
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
val sharedPref2 = context?.getSharedPreferences("username",Context.MODE_PRIVATE)
|
val sharedPref2 = context?.getSharedPreferences("username", Context.MODE_PRIVATE)
|
||||||
with (sharedPref2!!.edit()) {
|
with(sharedPref2!!.edit()) {
|
||||||
putString("username",login.username)
|
putString("username", login.username)
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ import android.view.inputmethod.InputMethodManager
|
|||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.constraintlayout.motion.widget.MotionLayout
|
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
@ -30,13 +29,12 @@ import androidx.navigation.ui.setupWithNavController
|
|||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
import com.google.android.material.color.DynamicColors
|
import com.google.android.material.color.DynamicColors
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
val TAG = "MainActivity"
|
val TAG = "MainActivity"
|
||||||
lateinit var bottomNavigationView: BottomNavigationView
|
lateinit var bottomNavigationView: BottomNavigationView
|
||||||
lateinit var toolbar: Toolbar
|
lateinit var toolbar: Toolbar
|
||||||
lateinit var navController : NavController
|
lateinit var navController: NavController
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
DynamicColors.applyToActivityIfAvailable(this)
|
DynamicColors.applyToActivityIfAvailable(this)
|
||||||
@ -50,42 +48,21 @@ class MainActivity : AppCompatActivity() {
|
|||||||
SponsorBlockSettings.sponsorsEnabled = sharedPreferences.getBoolean("sponsors_category_key", false)
|
SponsorBlockSettings.sponsorsEnabled = sharedPreferences.getBoolean("sponsors_category_key", false)
|
||||||
SponsorBlockSettings.outroEnabled = sharedPreferences.getBoolean("outro_category_key", false)
|
SponsorBlockSettings.outroEnabled = sharedPreferences.getBoolean("outro_category_key", false)
|
||||||
|
|
||||||
|
updateAccentColor(this)
|
||||||
val languageName = sharedPreferences.getString("language", "sys")
|
updateThemeMode(this)
|
||||||
if (languageName != "") {
|
updateLanguage(this)
|
||||||
var locale = if (languageName != "sys" && "$languageName".length < 3 ){
|
|
||||||
Locale(languageName)
|
|
||||||
} else if ("$languageName".length > 3) {
|
|
||||||
Locale(languageName?.substring(0,2), languageName?.substring(4,6))
|
|
||||||
} else {
|
|
||||||
Locale.getDefault()
|
|
||||||
}
|
|
||||||
val res = resources
|
|
||||||
val dm = res.displayMetrics
|
|
||||||
val conf = res.configuration
|
|
||||||
conf.setLocale(locale)
|
|
||||||
Locale.setDefault(locale)
|
|
||||||
res.updateConfiguration(conf, dm)
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
val connectivityManager = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
val connectivityManager = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||||
val networkInfo=connectivityManager.activeNetworkInfo
|
val networkInfo = connectivityManager.activeNetworkInfo
|
||||||
val isConnected = networkInfo != null && networkInfo.isConnected
|
val isConnected = networkInfo != null && networkInfo.isConnected
|
||||||
|
|
||||||
if (isConnected == false) {
|
if (!isConnected) {
|
||||||
setContentView(R.layout.activity_nointernet)
|
setContentView(R.layout.activity_nointernet)
|
||||||
findViewById<Button>(R.id.retry_button).setOnClickListener() {
|
findViewById<Button>(R.id.retry_button).setOnClickListener() {
|
||||||
recreate()
|
recreate()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
|
|
||||||
bottomNavigationView = findViewById(R.id.bottomNav)
|
bottomNavigationView = findViewById(R.id.bottomNav)
|
||||||
@ -98,6 +75,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
"library" -> navController.navigate(R.id.library)
|
"library" -> navController.navigate(R.id.library)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bottomNavigationView.setBackgroundColor(0) // otherwise Navbar Theme doesn't change
|
||||||
bottomNavigationView.setOnItemSelectedListener {
|
bottomNavigationView.setOnItemSelectedListener {
|
||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
R.id.home2 -> {
|
R.id.home2 -> {
|
||||||
@ -106,12 +84,12 @@ class MainActivity : AppCompatActivity() {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.subscriptions -> {
|
R.id.subscriptions -> {
|
||||||
//navController.backQueue.clear()
|
// navController.backQueue.clear()
|
||||||
navController.navigate(R.id.subscriptions)
|
navController.navigate(R.id.subscriptions)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.library -> {
|
R.id.library -> {
|
||||||
//navController.backQueue.clear()
|
// navController.backQueue.clear()
|
||||||
navController.navigate(R.id.library)
|
navController.navigate(R.id.library)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -121,7 +99,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
toolbar = findViewById(R.id.toolbar)
|
toolbar = findViewById(R.id.toolbar)
|
||||||
val typedValue = TypedValue()
|
val typedValue = TypedValue()
|
||||||
this.theme.resolveAttribute(R.attr.colorPrimaryDark, typedValue, true)
|
this.theme.resolveAttribute(R.attr.colorPrimary, typedValue, true)
|
||||||
val hexColor = String.format("#%06X", (0xFFFFFF and typedValue.data))
|
val hexColor = String.format("#%06X", (0xFFFFFF and typedValue.data))
|
||||||
val appName = HtmlCompat.fromHtml(
|
val appName = HtmlCompat.fromHtml(
|
||||||
"Libre<span style='color:$hexColor';>Tube</span>",
|
"Libre<span style='color:$hexColor';>Tube</span>",
|
||||||
@ -129,12 +107,12 @@ class MainActivity : AppCompatActivity() {
|
|||||||
)
|
)
|
||||||
toolbar.title = appName
|
toolbar.title = appName
|
||||||
|
|
||||||
toolbar.setNavigationOnClickListener{
|
toolbar.setNavigationOnClickListener {
|
||||||
//settings activity stuff
|
// settings activity stuff
|
||||||
val intent = Intent(this, SettingsActivity::class.java)
|
val intent = Intent(this, SettingsActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
toolbar.setOnMenuItemClickListener {
|
toolbar.setOnMenuItemClickListener {
|
||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
@ -146,134 +124,128 @@ class MainActivity : AppCompatActivity() {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
val action: String? = intent?.action
|
val action: String? = intent?.action
|
||||||
val data: Uri? = intent?.data
|
val data: Uri? = intent?.data
|
||||||
Log.d(TAG, "dafaq"+data.toString())
|
Log.d(TAG, "dafaq" + data.toString())
|
||||||
|
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
Log.d("dafaq",data.host+" ${data.path} ")
|
Log.d("dafaq", data.host + " ${data.path} ")
|
||||||
if(data.host != null){
|
if (data.host != null) {
|
||||||
if(data.path != null){
|
if (data.path != null) {
|
||||||
//channel
|
// channel
|
||||||
if(data.path!!.contains("/channel/") || data.path!!.contains("/c/") || data.path!!.contains("/user/")){
|
if (data.path!!.contains("/channel/") || data.path!!.contains("/c/") || data.path!!.contains("/user/")) {
|
||||||
var channel = data.path
|
var channel = data.path
|
||||||
channel = channel!!.replace("/c/","")
|
channel = channel!!.replace("/c/", "")
|
||||||
channel = channel!!.replace("/user/","")
|
channel = channel!!.replace("/user/", "")
|
||||||
val bundle = bundleOf("channel_id" to channel)
|
val bundle = bundleOf("channel_id" to channel)
|
||||||
navController.navigate(R.id.channel,bundle)
|
navController.navigate(R.id.channel, bundle)
|
||||||
}else if(data.path!!.contains("/playlist")){
|
} else if (data.path!!.contains("/playlist")) {
|
||||||
var playlist = data.query!!
|
var playlist = data.query!!
|
||||||
if (playlist.contains("&"))
|
if (playlist.contains("&")) {
|
||||||
{
|
var playlists = playlist.split("&")
|
||||||
var playlists = playlist.split("&")
|
for (v in playlists) {
|
||||||
for (v in playlists){
|
if (v.contains("list=")) {
|
||||||
if (v.contains("list=")){
|
playlist = v
|
||||||
playlist = v
|
break
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
playlist = playlist.replace("list=","")
|
|
||||||
val bundle = bundleOf("playlist_id" to playlist)
|
|
||||||
navController.navigate(R.id.playlistFragment,bundle)
|
|
||||||
}else if(data.path!!.contains("/shorts/") || data.path!!.contains("/embed/") || data.path!!.contains("/v/")){
|
|
||||||
var watch = data.path!!.replace("/shorts/","").replace("/v/","").replace("/embed/","")
|
|
||||||
var bundle = Bundle()
|
|
||||||
bundle.putString("videoId",watch)
|
|
||||||
var frag = PlayerFragment()
|
|
||||||
frag.arguments = bundle
|
|
||||||
supportFragmentManager.beginTransaction()
|
|
||||||
.remove(PlayerFragment())
|
|
||||||
.commit()
|
|
||||||
supportFragmentManager.beginTransaction()
|
|
||||||
.replace(R.id.container, frag)
|
|
||||||
.commitNow()
|
|
||||||
Handler().postDelayed({
|
|
||||||
val motionLayout = findViewById<MotionLayout>(R.id.playerMotionLayout)
|
|
||||||
motionLayout.transitionToEnd()
|
|
||||||
motionLayout.transitionToStart()
|
|
||||||
}, 100)
|
|
||||||
}else if(data.path!!.contains("/watch") && data.query != null){
|
|
||||||
Log.d("dafaq",data.query!!)
|
|
||||||
var watch = data.query!!
|
|
||||||
if (watch.contains("&"))
|
|
||||||
{
|
|
||||||
var watches = watch.split("&")
|
|
||||||
for (v in watches){
|
|
||||||
if (v.contains("v=")){
|
|
||||||
watch = v
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var bundle = Bundle()
|
|
||||||
bundle.putString("videoId",watch.replace("v=",""))
|
|
||||||
var frag = PlayerFragment()
|
|
||||||
frag.arguments = bundle
|
|
||||||
supportFragmentManager.beginTransaction()
|
|
||||||
.remove(PlayerFragment())
|
|
||||||
.commit()
|
|
||||||
supportFragmentManager.beginTransaction()
|
|
||||||
.replace(R.id.container, frag)
|
|
||||||
.commitNow()
|
|
||||||
Handler().postDelayed({
|
|
||||||
val motionLayout = findViewById<MotionLayout>(R.id.playerMotionLayout)
|
|
||||||
motionLayout.transitionToEnd()
|
|
||||||
motionLayout.transitionToStart()
|
|
||||||
}, 100)
|
|
||||||
|
|
||||||
}else{
|
|
||||||
var watch = data.path!!.replace("/","")
|
|
||||||
var bundle = Bundle()
|
|
||||||
bundle.putString("videoId",watch)
|
|
||||||
var frag = PlayerFragment()
|
|
||||||
frag.arguments = bundle
|
|
||||||
supportFragmentManager.beginTransaction()
|
|
||||||
.remove(PlayerFragment())
|
|
||||||
.commit()
|
|
||||||
supportFragmentManager.beginTransaction()
|
|
||||||
.replace(R.id.container, frag)
|
|
||||||
.commitNow()
|
|
||||||
Handler().postDelayed({
|
|
||||||
val motionLayout = findViewById<MotionLayout>(R.id.playerMotionLayout)
|
|
||||||
motionLayout.transitionToEnd()
|
|
||||||
motionLayout.transitionToStart()
|
|
||||||
}, 100)
|
|
||||||
}
|
}
|
||||||
|
playlist = playlist.replace("list=", "")
|
||||||
|
val bundle = bundleOf("playlist_id" to playlist)
|
||||||
|
navController.navigate(R.id.playlistFragment, bundle)
|
||||||
|
} else if (data.path!!.contains("/shorts/") || data.path!!.contains("/embed/") || data.path!!.contains("/v/")) {
|
||||||
|
var watch = data.path!!.replace("/shorts/", "").replace("/v/", "").replace("/embed/", "")
|
||||||
|
var bundle = Bundle()
|
||||||
|
bundle.putString("videoId", watch)
|
||||||
|
var frag = PlayerFragment()
|
||||||
|
frag.arguments = bundle
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.remove(PlayerFragment())
|
||||||
|
.commit()
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.replace(R.id.container, frag)
|
||||||
|
.commitNow()
|
||||||
|
Handler().postDelayed({
|
||||||
|
val motionLayout = findViewById<MotionLayout>(R.id.playerMotionLayout)
|
||||||
|
motionLayout.transitionToEnd()
|
||||||
|
motionLayout.transitionToStart()
|
||||||
|
}, 100)
|
||||||
|
} else if (data.path!!.contains("/watch") && data.query != null) {
|
||||||
|
Log.d("dafaq", data.query!!)
|
||||||
|
var watch = data.query!!
|
||||||
|
if (watch.contains("&")) {
|
||||||
|
var watches = watch.split("&")
|
||||||
|
for (v in watches) {
|
||||||
|
if (v.contains("v=")) {
|
||||||
|
watch = v
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var bundle = Bundle()
|
||||||
|
bundle.putString("videoId", watch.replace("v=", ""))
|
||||||
|
var frag = PlayerFragment()
|
||||||
|
frag.arguments = bundle
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.remove(PlayerFragment())
|
||||||
|
.commit()
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.replace(R.id.container, frag)
|
||||||
|
.commitNow()
|
||||||
|
Handler().postDelayed({
|
||||||
|
val motionLayout = findViewById<MotionLayout>(R.id.playerMotionLayout)
|
||||||
|
motionLayout.transitionToEnd()
|
||||||
|
motionLayout.transitionToStart()
|
||||||
|
}, 100)
|
||||||
|
} else {
|
||||||
|
var watch = data.path!!.replace("/", "")
|
||||||
|
var bundle = Bundle()
|
||||||
|
bundle.putString("videoId", watch)
|
||||||
|
var frag = PlayerFragment()
|
||||||
|
frag.arguments = bundle
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.remove(PlayerFragment())
|
||||||
|
.commit()
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.replace(R.id.container, frag)
|
||||||
|
.commitNow()
|
||||||
|
Handler().postDelayed({
|
||||||
|
val motionLayout = findViewById<MotionLayout>(R.id.playerMotionLayout)
|
||||||
|
motionLayout.transitionToEnd()
|
||||||
|
motionLayout.transitionToStart()
|
||||||
|
}, 100)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
try{
|
try {
|
||||||
val mainMotionLayout = findViewById<MotionLayout>(R.id.mainMotionLayout)
|
val mainMotionLayout = findViewById<MotionLayout>(R.id.mainMotionLayout)
|
||||||
if (mainMotionLayout.progress == 0.toFloat()){
|
if (mainMotionLayout.progress == 0.toFloat()) {
|
||||||
mainMotionLayout.transitionToEnd()
|
mainMotionLayout.transitionToEnd()
|
||||||
findViewById<ConstraintLayout>(R.id.main_container).isClickable=false
|
findViewById<ConstraintLayout>(R.id.main_container).isClickable = false
|
||||||
val motionLayout = findViewById<MotionLayout>(R.id.playerMotionLayout)
|
val motionLayout = findViewById<MotionLayout>(R.id.playerMotionLayout)
|
||||||
motionLayout.transitionToEnd()
|
motionLayout.transitionToEnd()
|
||||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
with(motionLayout) {
|
with(motionLayout) {
|
||||||
getConstraintSet(R.id.start).constrainHeight(R.id.player, 0)
|
getConstraintSet(R.id.start).constrainHeight(R.id.player, 0)
|
||||||
enableTransition(R.id.yt_transition,true)
|
enableTransition(R.id.yt_transition, true)
|
||||||
}
|
}
|
||||||
findViewById<LinearLayout>(R.id.linLayout).visibility=View.VISIBLE
|
findViewById<LinearLayout>(R.id.linLayout).visibility = View.VISIBLE
|
||||||
isFullScreen=false
|
isFullScreen = false
|
||||||
}else{
|
} else {
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
if (navController.currentBackStackEntry == null && (parent as View).id != R.id.settings){
|
if (navController.currentBackStackEntry == null && (parent as View).id != R.id.settings) {
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (e: Exception){
|
} catch (e: Exception) {
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
moveTaskToBack(true)
|
moveTaskToBack(true)
|
||||||
}
|
}
|
||||||
@ -303,15 +275,17 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_FULLSCREEN
|
window.decorView.systemUiVisibility = (
|
||||||
|
View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||||
or View.SYSTEM_UI_FLAG_IMMERSIVE
|
or View.SYSTEM_UI_FLAG_IMMERSIVE
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
|
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun unsetFullscreen(){
|
private fun unsetFullscreen() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
window.attributes.layoutInDisplayCutoutMode =
|
window.attributes.layoutInDisplayCutoutMode =
|
||||||
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
|
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
|
||||||
@ -335,7 +309,6 @@ class MainActivity : AppCompatActivity() {
|
|||||||
(fragment as? PlayerFragment)?.onUserLeaveHint()
|
(fragment as? PlayerFragment)?.onUserLeaveHint()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
fun Fragment.hideKeyboard() {
|
fun Fragment.hideKeyboard() {
|
||||||
view?.let { activity?.hideKeyboard(it) }
|
view?.let { activity?.hideKeyboard(it) }
|
||||||
|
@ -17,7 +17,10 @@ interface PipedApi {
|
|||||||
suspend fun getSegments(@Path("videoId") videoId: String, @Query("category") category: String): Segments
|
suspend fun getSegments(@Path("videoId") videoId: String, @Query("category") category: String): Segments
|
||||||
|
|
||||||
@GET("nextpage/comments/{videoId}")
|
@GET("nextpage/comments/{videoId}")
|
||||||
suspend fun getCommentsNextPage(@Path("videoId") videoId: String, @Query("nextpage") nextPage: String): CommentsPage
|
suspend fun getCommentsNextPage(
|
||||||
|
@Path("videoId") videoId: String,
|
||||||
|
@Query("nextpage") nextPage: String
|
||||||
|
): CommentsPage
|
||||||
|
|
||||||
@GET("search")
|
@GET("search")
|
||||||
suspend fun getSearchResults(
|
suspend fun getSearchResults(
|
||||||
@ -39,13 +42,19 @@ interface PipedApi {
|
|||||||
suspend fun getChannel(@Path("channelId") channelId: String): Channel
|
suspend fun getChannel(@Path("channelId") channelId: String): Channel
|
||||||
|
|
||||||
@GET("nextpage/channel/{channelId}")
|
@GET("nextpage/channel/{channelId}")
|
||||||
suspend fun getChannelNextPage(@Path("channelId") channelId: String, @Query("nextpage") nextPage: String): Channel
|
suspend fun getChannelNextPage(
|
||||||
|
@Path("channelId") channelId: String,
|
||||||
|
@Query("nextpage") nextPage: String
|
||||||
|
): Channel
|
||||||
|
|
||||||
@GET("playlists/{playlistId}")
|
@GET("playlists/{playlistId}")
|
||||||
suspend fun getPlaylist(@Path("playlistId") playlistId: String): Playlist
|
suspend fun getPlaylist(@Path("playlistId") playlistId: String): Playlist
|
||||||
|
|
||||||
@GET("nextpage/playlists/{playlistId}")
|
@GET("nextpage/playlists/{playlistId}")
|
||||||
suspend fun getPlaylistNextPage(@Path("playlistId") playlistId: String, @Query("nextpage") nextPage: String): Playlist
|
suspend fun getPlaylistNextPage(
|
||||||
|
@Path("playlistId") playlistId: String,
|
||||||
|
@Query("nextpage") nextPage: String
|
||||||
|
): Playlist
|
||||||
|
|
||||||
@POST("login")
|
@POST("login")
|
||||||
suspend fun login(@Body login: Login): Token
|
suspend fun login(@Body login: Login): Token
|
||||||
@ -57,7 +66,10 @@ interface PipedApi {
|
|||||||
suspend fun getFeed(@Query("authToken") token: String?): List<StreamItem>
|
suspend fun getFeed(@Query("authToken") token: String?): List<StreamItem>
|
||||||
|
|
||||||
@GET("subscribed")
|
@GET("subscribed")
|
||||||
suspend fun isSubscribed(@Query("channelId") channelId: String, @Header("Authorization") token: String): Subscribed
|
suspend fun isSubscribed(
|
||||||
|
@Query("channelId") channelId: String,
|
||||||
|
@Header("Authorization") token: String
|
||||||
|
): Subscribed
|
||||||
|
|
||||||
@GET("subscriptions")
|
@GET("subscriptions")
|
||||||
suspend fun subscriptions(@Header("Authorization") token: String): List<Subscription>
|
suspend fun subscriptions(@Header("Authorization") token: String): List<Subscription>
|
||||||
@ -69,7 +81,11 @@ interface PipedApi {
|
|||||||
suspend fun unsubscribe(@Header("Authorization") token: String, @Body subscribe: Subscribe): Message
|
suspend fun unsubscribe(@Header("Authorization") token: String, @Body subscribe: Subscribe): Message
|
||||||
|
|
||||||
@POST("import")
|
@POST("import")
|
||||||
suspend fun importSubscriptions(@Query("override") override: Boolean, @Header("Authorization") token: String, @Body channels: List<String>): Message
|
suspend fun importSubscriptions(
|
||||||
|
@Query("override") override: Boolean,
|
||||||
|
@Header("Authorization") token: String,
|
||||||
|
@Body channels: List<String>
|
||||||
|
): Message
|
||||||
|
|
||||||
@GET("user/playlists")
|
@GET("user/playlists")
|
||||||
suspend fun playlists(@Header("Authorization") token: String): List<Playlists>
|
suspend fun playlists(@Header("Authorization") token: String): List<Playlists>
|
||||||
@ -84,12 +100,12 @@ interface PipedApi {
|
|||||||
suspend fun addToPlaylist(@Header("Authorization") token: String, @Body playlistId: PlaylistId): Message
|
suspend fun addToPlaylist(@Header("Authorization") token: String, @Body playlistId: PlaylistId): Message
|
||||||
|
|
||||||
@POST("user/playlists/remove")
|
@POST("user/playlists/remove")
|
||||||
suspend fun removeFromPlaylist(@Header("Authorization") token: String, @Body playlistId: PlaylistId): Message
|
suspend fun removeFromPlaylist(
|
||||||
|
@Header("Authorization") token: String,
|
||||||
|
@Body playlistId: PlaylistId
|
||||||
|
): Message
|
||||||
|
|
||||||
//only for fetching servers list
|
// only for fetching servers list
|
||||||
@GET
|
@GET
|
||||||
suspend fun getInstances(@Url url: String): List<Instances>
|
suspend fun getInstances(@Url url: String): List<Instances>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -8,20 +8,11 @@ import com.google.android.material.color.DynamicColors
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
|
||||||
|
|
||||||
class Player : Activity() {
|
class Player : Activity() {
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
DynamicColors.applyToActivityIfAvailable(this)
|
DynamicColors.applyToActivityIfAvailable(this)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_player)
|
setContentView(R.layout.activity_player)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,13 +58,12 @@ import com.google.android.exoplayer2.upstream.DefaultHttpDataSource
|
|||||||
import com.google.android.exoplayer2.util.RepeatModeUtil
|
import com.google.android.exoplayer2.util.RepeatModeUtil
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import org.chromium.net.CronetEngine
|
|
||||||
import retrofit2.HttpException
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
import org.chromium.net.CronetEngine
|
||||||
|
import retrofit2.HttpException
|
||||||
|
|
||||||
var isFullScreen = false
|
var isFullScreen = false
|
||||||
|
|
||||||
@ -247,7 +246,6 @@ class PlayerFragment : Fragment() {
|
|||||||
) {
|
) {
|
||||||
fetchNextComments()
|
fetchNextComments()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commentsRecView = view.findViewById(R.id.comments_recView)
|
commentsRecView = view.findViewById(R.id.comments_recView)
|
||||||
@ -274,22 +272,21 @@ class PlayerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkForSegments()
|
private fun checkForSegments() {
|
||||||
{
|
|
||||||
if (!exoPlayer.isPlaying || !SponsorBlockSettings.sponsorBlockEnabled) return
|
if (!exoPlayer.isPlaying || !SponsorBlockSettings.sponsorBlockEnabled) return
|
||||||
|
|
||||||
exoPlayerView.postDelayed(this::checkForSegments, 100)
|
exoPlayerView.postDelayed(this::checkForSegments, 100)
|
||||||
|
|
||||||
if(segmentData.segments.isEmpty() )
|
if (segmentData.segments.isEmpty())
|
||||||
return
|
return
|
||||||
|
|
||||||
segmentData.segments.forEach { segment: Segment ->
|
segmentData.segments.forEach { segment: Segment ->
|
||||||
val segmentStart = (segment.segment!![0] * 1000.0f).toLong()
|
val segmentStart = (segment.segment!![0] * 1000.0f).toLong()
|
||||||
val segmentEnd = (segment.segment!![1] * 1000.0f).toLong()
|
val segmentEnd = (segment.segment!![1] * 1000.0f).toLong()
|
||||||
val currentPosition = exoPlayer.currentPosition
|
val currentPosition = exoPlayer.currentPosition
|
||||||
if(currentPosition in segmentStart until segmentEnd) {
|
if (currentPosition in segmentStart until segmentEnd) {
|
||||||
Toast.makeText(context,R.string.segment_skipped, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.segment_skipped, Toast.LENGTH_SHORT).show()
|
||||||
exoPlayer.seekTo(segmentEnd);
|
exoPlayer.seekTo(segmentEnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -321,7 +318,7 @@ class PlayerFragment : Fragment() {
|
|||||||
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
if(SponsorBlockSettings.sponsorBlockEnabled) {
|
if (SponsorBlockSettings.sponsorBlockEnabled) {
|
||||||
val categories: ArrayList<String> = arrayListOf()
|
val categories: ArrayList<String> = arrayListOf()
|
||||||
if (SponsorBlockSettings.introEnabled) {
|
if (SponsorBlockSettings.introEnabled) {
|
||||||
categories.add("intro")
|
categories.add("intro")
|
||||||
@ -338,7 +335,7 @@ class PlayerFragment : Fragment() {
|
|||||||
if (SponsorBlockSettings.outroEnabled) {
|
if (SponsorBlockSettings.outroEnabled) {
|
||||||
categories.add("outro")
|
categories.add("outro")
|
||||||
}
|
}
|
||||||
if(categories.size > 0) {
|
if (categories.size > 0) {
|
||||||
segmentData = try {
|
segmentData = try {
|
||||||
|
|
||||||
RetrofitInstance.api.getSegments(
|
RetrofitInstance.api.getSegments(
|
||||||
@ -401,10 +398,10 @@ class PlayerFragment : Fragment() {
|
|||||||
exoPlayerView.setShowSubtitleButton(true)
|
exoPlayerView.setShowSubtitleButton(true)
|
||||||
exoPlayerView.setShowNextButton(false)
|
exoPlayerView.setShowNextButton(false)
|
||||||
exoPlayerView.setShowPreviousButton(false)
|
exoPlayerView.setShowPreviousButton(false)
|
||||||
exoPlayerView.setRepeatToggleModes(RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL);
|
exoPlayerView.setRepeatToggleModes(RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL)
|
||||||
// exoPlayerView.controllerShowTimeoutMs = 1500
|
// exoPlayerView.controllerShowTimeoutMs = 1500
|
||||||
exoPlayerView.controllerHideOnTouch = true
|
exoPlayerView.controllerHideOnTouch = true
|
||||||
exoPlayer.setAudioAttributes(audioAttributes,true);
|
exoPlayer.setAudioAttributes(audioAttributes, true)
|
||||||
exoPlayerView.player = exoPlayer
|
exoPlayerView.player = exoPlayer
|
||||||
val sharedPreferences =
|
val sharedPreferences =
|
||||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
@ -433,9 +430,11 @@ class PlayerFragment : Fragment() {
|
|||||||
ProgressiveMediaSource.Factory(dataSourceFactory)
|
ProgressiveMediaSource.Factory(dataSourceFactory)
|
||||||
.createMediaSource(
|
.createMediaSource(
|
||||||
fromUri(
|
fromUri(
|
||||||
response.audioStreams!![getMostBitRate(
|
response.audioStreams!![
|
||||||
response.audioStreams
|
getMostBitRate(
|
||||||
)].url!!
|
response.audioStreams
|
||||||
|
)
|
||||||
|
].url!!
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -479,9 +478,11 @@ class PlayerFragment : Fragment() {
|
|||||||
audioSource = ProgressiveMediaSource.Factory(dataSourceFactory)
|
audioSource = ProgressiveMediaSource.Factory(dataSourceFactory)
|
||||||
.createMediaSource(
|
.createMediaSource(
|
||||||
fromUri(
|
fromUri(
|
||||||
response.audioStreams!![getMostBitRate(
|
response.audioStreams!![
|
||||||
response.audioStreams
|
getMostBitRate(
|
||||||
)].url!!
|
response.audioStreams
|
||||||
|
)
|
||||||
|
].url!!
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -545,9 +546,11 @@ class PlayerFragment : Fragment() {
|
|||||||
ProgressiveMediaSource.Factory(dataSourceFactory)
|
ProgressiveMediaSource.Factory(dataSourceFactory)
|
||||||
.createMediaSource(
|
.createMediaSource(
|
||||||
fromUri(
|
fromUri(
|
||||||
response.audioStreams!![getMostBitRate(
|
response.audioStreams!![
|
||||||
response.audioStreams
|
getMostBitRate(
|
||||||
)].url!!
|
response.audioStreams
|
||||||
|
)
|
||||||
|
].url!!
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -555,7 +558,7 @@ class PlayerFragment : Fragment() {
|
|||||||
MergingMediaSource(videoSource, audioSource)
|
MergingMediaSource(videoSource, audioSource)
|
||||||
exoPlayer.setMediaSource(mergeSource)
|
exoPlayer.setMediaSource(mergeSource)
|
||||||
}
|
}
|
||||||
exoPlayer.seekTo(lastPosition);
|
exoPlayer.seekTo(lastPosition)
|
||||||
view.findViewById<TextView>(R.id.quality_text).text =
|
view.findViewById<TextView>(R.id.quality_text).text =
|
||||||
videosNameArray[which]
|
videosNameArray[which]
|
||||||
}
|
}
|
||||||
@ -566,8 +569,7 @@ class PlayerFragment : Fragment() {
|
|||||||
// Listener for play and pause icon change
|
// Listener for play and pause icon change
|
||||||
exoPlayer!!.addListener(object : com.google.android.exoplayer2.Player.Listener {
|
exoPlayer!!.addListener(object : com.google.android.exoplayer2.Player.Listener {
|
||||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||||
if(isPlaying && SponsorBlockSettings.sponsorBlockEnabled)
|
if (isPlaying && SponsorBlockSettings.sponsorBlockEnabled) {
|
||||||
{
|
|
||||||
exoPlayerView.postDelayed(this@PlayerFragment::checkForSegments, 100)
|
exoPlayerView.postDelayed(this@PlayerFragment::checkForSegments, 100)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -578,9 +580,9 @@ class PlayerFragment : Fragment() {
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
exoPlayerView.keepScreenOn = !(
|
exoPlayerView.keepScreenOn = !(
|
||||||
playbackState == Player.STATE_IDLE || playbackState == Player.STATE_ENDED ||
|
playbackState == Player.STATE_IDLE || playbackState == Player.STATE_ENDED ||
|
||||||
!playWhenReady
|
!playWhenReady
|
||||||
)
|
)
|
||||||
|
|
||||||
if (playWhenReady && playbackState == Player.STATE_READY) {
|
if (playWhenReady && playbackState == Player.STATE_READY) {
|
||||||
// media actually playing
|
// media actually playing
|
||||||
@ -678,9 +680,9 @@ class PlayerFragment : Fragment() {
|
|||||||
requireContext(),
|
requireContext(),
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||||
) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(
|
) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
) != PackageManager.PERMISSION_GRANTED
|
) != PackageManager.PERMISSION_GRANTED
|
||||||
) {
|
) {
|
||||||
ActivityCompat.requestPermissions(
|
ActivityCompat.requestPermissions(
|
||||||
mainActivity,
|
mainActivity,
|
||||||
@ -772,7 +774,6 @@ class PlayerFragment : Fragment() {
|
|||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
if (response.subscribed == true) {
|
if (response.subscribed == true) {
|
||||||
isSubscribed = true
|
isSubscribed = true
|
||||||
@ -864,25 +865,25 @@ class PlayerFragment : Fragment() {
|
|||||||
super.onResume()
|
super.onResume()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchNextComments(){
|
private fun fetchNextComments() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
if (!isLoading) {
|
if (!isLoading) {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.getCommentsNextPage(videoId!!, nextPage!!)
|
RetrofitInstance.api.getCommentsNextPage(videoId!!, nextPage!!)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
Log.e(TAG, "HttpException, unexpected response," + e.response())
|
Log.e(TAG, "HttpException, unexpected response," + e.response())
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
|
||||||
nextPage = response.nextpage
|
|
||||||
commentsAdapter?.updateItems(response.comments!!)
|
|
||||||
isLoading = false
|
|
||||||
}
|
}
|
||||||
|
nextPage = response.nextpage
|
||||||
|
commentsAdapter?.updateItems(response.comments!!)
|
||||||
|
isLoading = false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
|
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
|
||||||
@ -898,7 +899,7 @@ class PlayerFragment : Fragment() {
|
|||||||
view?.findViewById<FrameLayout>(R.id.top_bar)?.visibility = View.GONE
|
view?.findViewById<FrameLayout>(R.id.top_bar)?.visibility = View.GONE
|
||||||
val mainActivity = activity as MainActivity
|
val mainActivity = activity as MainActivity
|
||||||
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
isFullScreen = false;
|
isFullScreen = false
|
||||||
} else {
|
} else {
|
||||||
with(motionLayout) {
|
with(motionLayout) {
|
||||||
getConstraintSet(R.id.start).constrainHeight(R.id.player, 0)
|
getConstraintSet(R.id.start).constrainHeight(R.id.player, 0)
|
||||||
@ -917,6 +918,6 @@ class PlayerFragment : Fragment() {
|
|||||||
|
|
||||||
if (SDK_INT >= Build.VERSION_CODES.N && exoPlayer.isPlaying && (scrollView?.getLocalVisibleRect(bounds) == true || isFullScreen)) {
|
if (SDK_INT >= Build.VERSION_CODES.N && exoPlayer.isPlaying && (scrollView?.getLocalVisibleRect(bounds) == true || isFullScreen)) {
|
||||||
requireActivity().enterPictureInPictureMode()
|
requireActivity().enterPictureInPictureMode()
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,27 +3,23 @@ package com.github.libretube
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.ScrollView
|
import android.widget.ScrollView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.github.libretube.adapters.ChannelAdapter
|
|
||||||
import com.github.libretube.adapters.PlaylistAdapter
|
import com.github.libretube.adapters.PlaylistAdapter
|
||||||
import com.squareup.picasso.Picasso
|
|
||||||
import retrofit2.HttpException
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import retrofit2.HttpException
|
||||||
|
|
||||||
class PlaylistFragment : Fragment() {
|
class PlaylistFragment : Fragment() {
|
||||||
private var playlist_id: String? = null
|
private var playlist_id: String? = null
|
||||||
private val TAG = "PlaylistFragment"
|
private val TAG = "PlaylistFragment"
|
||||||
var nextPage: String? =null
|
var nextPage: String? = null
|
||||||
var playlistAdapter: PlaylistAdapter? = null
|
var playlistAdapter: PlaylistAdapter? = null
|
||||||
var isLoading = true
|
var isLoading = true
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@ -34,7 +30,8 @@ class PlaylistFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
@ -44,19 +41,19 @@ class PlaylistFragment : Fragment() {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
playlist_id = playlist_id!!.replace("/playlist?list=","")
|
playlist_id = playlist_id!!.replace("/playlist?list=", "")
|
||||||
view.findViewById<TextView>(R.id.playlist_name).text=playlist_id
|
view.findViewById<TextView>(R.id.playlist_name).text = playlist_id
|
||||||
val recyclerView = view.findViewById<RecyclerView>(R.id.playlist_recView)
|
val recyclerView = view.findViewById<RecyclerView>(R.id.playlist_recView)
|
||||||
recyclerView.layoutManager = LinearLayoutManager(context)
|
recyclerView.layoutManager = LinearLayoutManager(context)
|
||||||
|
|
||||||
fetchPlaylist(view)
|
fetchPlaylist(view)
|
||||||
}
|
}
|
||||||
private fun fetchPlaylist(view: View){
|
private fun fetchPlaylist(view: View) {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.getPlaylist(playlist_id!!)
|
RetrofitInstance.api.getPlaylist(playlist_id!!)
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
@ -65,15 +62,15 @@ class PlaylistFragment : Fragment() {
|
|||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
nextPage = response.nextpage
|
nextPage = response.nextpage
|
||||||
isLoading=false
|
isLoading = false
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
view.findViewById<TextView>(R.id.playlist_name).text=response.name
|
view.findViewById<TextView>(R.id.playlist_name).text = response.name
|
||||||
view.findViewById<TextView>(R.id.playlist_uploader).text=response.uploader
|
view.findViewById<TextView>(R.id.playlist_uploader).text = response.uploader
|
||||||
view.findViewById<TextView>(R.id.playlist_totVideos).text=response.videos.toString()+" Videos"
|
view.findViewById<TextView>(R.id.playlist_totVideos).text = response.videos.toString() + " Videos"
|
||||||
val sharedPref2 = context?.getSharedPreferences("username", Context.MODE_PRIVATE)
|
val sharedPref2 = context?.getSharedPreferences("username", Context.MODE_PRIVATE)
|
||||||
val user = sharedPref2?.getString("username","")
|
val user = sharedPref2?.getString("username", "")
|
||||||
var isOwner = false
|
var isOwner = false
|
||||||
if(response.uploaderUrl == null && response.uploader.equals(user, true)){
|
if (response.uploaderUrl == null && response.uploader.equals(user, true)) {
|
||||||
isOwner = true
|
isOwner = true
|
||||||
}
|
}
|
||||||
playlistAdapter = PlaylistAdapter(response.relatedStreams!!.toMutableList(), playlist_id!!, isOwner, requireActivity())
|
playlistAdapter = PlaylistAdapter(response.relatedStreams!!.toMutableList(), playlist_id!!, isOwner, requireActivity())
|
||||||
@ -82,15 +79,15 @@ class PlaylistFragment : Fragment() {
|
|||||||
scrollView.viewTreeObserver
|
scrollView.viewTreeObserver
|
||||||
.addOnScrollChangedListener {
|
.addOnScrollChangedListener {
|
||||||
if (scrollView.getChildAt(0).bottom
|
if (scrollView.getChildAt(0).bottom
|
||||||
== (scrollView.height + scrollView.scrollY)) {
|
== (scrollView.height + scrollView.scrollY)
|
||||||
//scroll view is at bottom
|
) {
|
||||||
if(nextPage!=null && !isLoading){
|
// scroll view is at bottom
|
||||||
isLoading=true
|
if (nextPage != null && !isLoading) {
|
||||||
|
isLoading = true
|
||||||
fetchNextPage()
|
fetchNextPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//scroll view is not at bottom
|
// scroll view is not at bottom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,24 +96,23 @@ class PlaylistFragment : Fragment() {
|
|||||||
run()
|
run()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchNextPage(){
|
private fun fetchNextPage() {
|
||||||
fun run() {
|
fun run() {
|
||||||
|
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.getPlaylistNextPage(playlist_id!!,nextPage!!)
|
RetrofitInstance.api.getPlaylistNextPage(playlist_id!!, nextPage!!)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
Log.e(TAG, "HttpException, unexpected response,"+e.response())
|
Log.e(TAG, "HttpException, unexpected response," + e.response())
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
nextPage = response.nextpage
|
nextPage = response.nextpage
|
||||||
playlistAdapter?.updateItems(response.relatedStreams!!)
|
playlistAdapter?.updateItems(response.relatedStreams!!)
|
||||||
isLoading=false
|
isLoading = false
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
|
@ -8,13 +8,13 @@ class ResettableLazyManager {
|
|||||||
val managedDelegates = LinkedList<Resettable>()
|
val managedDelegates = LinkedList<Resettable>()
|
||||||
|
|
||||||
fun register(managed: Resettable) {
|
fun register(managed: Resettable) {
|
||||||
synchronized (managedDelegates) {
|
synchronized(managedDelegates) {
|
||||||
managedDelegates.add(managed)
|
managedDelegates.add(managed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
synchronized (managedDelegates) {
|
synchronized(managedDelegates) {
|
||||||
managedDelegates.forEach { it.reset() }
|
managedDelegates.forEach { it.reset() }
|
||||||
managedDelegates.clear()
|
managedDelegates.clear()
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ interface Resettable {
|
|||||||
fun reset()
|
fun reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResettableLazy<PROPTYPE>(val manager: ResettableLazyManager, val init: ()->PROPTYPE): Resettable {
|
class ResettableLazy<PROPTYPE>(val manager: ResettableLazyManager, val init: () -> PROPTYPE) : Resettable {
|
||||||
@Volatile var lazyHolder = makeInitBlock()
|
@Volatile var lazyHolder = makeInitBlock()
|
||||||
|
|
||||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): PROPTYPE {
|
operator fun getValue(thisRef: Any?, property: KProperty<*>): PROPTYPE {
|
||||||
@ -44,7 +44,7 @@ class ResettableLazy<PROPTYPE>(val manager: ResettableLazyManager, val init: ()-
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <PROPTYPE> resettableLazy(manager: ResettableLazyManager, init: ()->PROPTYPE): ResettableLazy<PROPTYPE> {
|
fun <PROPTYPE> resettableLazy(manager: ResettableLazyManager, init: () -> PROPTYPE): ResettableLazy<PROPTYPE> {
|
||||||
return ResettableLazy(manager, init)
|
return ResettableLazy(manager, init)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,5 +13,4 @@ object RetrofitInstance {
|
|||||||
.build()
|
.build()
|
||||||
.create(PipedApi::class.java)
|
.create(PipedApi::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -23,38 +23,37 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.github.libretube.adapters.SearchAdapter
|
import com.github.libretube.adapters.SearchAdapter
|
||||||
import com.github.libretube.adapters.SearchHistoryAdapter
|
import com.github.libretube.adapters.SearchHistoryAdapter
|
||||||
|
import java.io.IOException
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
class SearchFragment : Fragment() {
|
class SearchFragment : Fragment() {
|
||||||
private val TAG = "SearchFragment"
|
private val TAG = "SearchFragment"
|
||||||
private var selectedFilter = 0
|
private var selectedFilter = 0
|
||||||
private var apiSearchFilter = "all"
|
private var apiSearchFilter = "all"
|
||||||
private var nextPage : String? = null
|
private var nextPage: String? = null
|
||||||
private lateinit var searchRecView : RecyclerView
|
private lateinit var searchRecView: RecyclerView
|
||||||
private var searchAdapter : SearchAdapter? = null
|
private var searchAdapter: SearchAdapter? = null
|
||||||
private var isLoading : Boolean = true
|
private var isLoading: Boolean = true
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
arguments?.let {
|
arguments?.let {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
return inflater.inflate(R.layout.fragment_search, container, false)
|
return inflater.inflate(R.layout.fragment_search, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
searchRecView = view.findViewById<RecyclerView>(R.id.search_recycler)
|
searchRecView = view.findViewById<RecyclerView>(R.id.search_recycler)
|
||||||
@ -81,30 +80,37 @@ class SearchFragment : Fragment() {
|
|||||||
|
|
||||||
MaterialAlertDialogBuilder(view.context)
|
MaterialAlertDialogBuilder(view.context)
|
||||||
.setTitle(getString(R.string.choose_filter))
|
.setTitle(getString(R.string.choose_filter))
|
||||||
.setSingleChoiceItems(filterOptions, selectedFilter, DialogInterface.OnClickListener {
|
.setSingleChoiceItems(
|
||||||
_, id -> tempSelectedItem = id
|
filterOptions, selectedFilter,
|
||||||
})
|
DialogInterface.OnClickListener {
|
||||||
.setPositiveButton(getString(R.string.okay), DialogInterface.OnClickListener { _, _ ->
|
_, id ->
|
||||||
selectedFilter = tempSelectedItem
|
tempSelectedItem = id
|
||||||
apiSearchFilter = when (selectedFilter) {
|
|
||||||
0 -> "all"
|
|
||||||
1 -> "videos"
|
|
||||||
2 -> "channels"
|
|
||||||
3 -> "playlists"
|
|
||||||
4 -> "music_songs"
|
|
||||||
5 -> "music_videos"
|
|
||||||
6 -> "music_albums"
|
|
||||||
7 -> "music_playlists"
|
|
||||||
else -> "all"
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
.setPositiveButton(
|
||||||
|
getString(R.string.okay),
|
||||||
|
DialogInterface.OnClickListener { _, _ ->
|
||||||
|
selectedFilter = tempSelectedItem
|
||||||
|
apiSearchFilter = when (selectedFilter) {
|
||||||
|
0 -> "all"
|
||||||
|
1 -> "videos"
|
||||||
|
2 -> "channels"
|
||||||
|
3 -> "playlists"
|
||||||
|
4 -> "music_songs"
|
||||||
|
5 -> "music_videos"
|
||||||
|
6 -> "music_albums"
|
||||||
|
7 -> "music_playlists"
|
||||||
|
else -> "all"
|
||||||
|
}
|
||||||
fetchSearch(autoTextView.text.toString())
|
fetchSearch(autoTextView.text.toString())
|
||||||
})
|
}
|
||||||
|
)
|
||||||
.setNegativeButton(getString(R.string.cancel), null)
|
.setNegativeButton(getString(R.string.cancel), null)
|
||||||
.create()
|
.create()
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
//show search history
|
// show search history
|
||||||
|
|
||||||
searchRecView.visibility = GONE
|
searchRecView.visibility = GONE
|
||||||
historyRecycler.visibility = VISIBLE
|
historyRecycler.visibility = VISIBLE
|
||||||
@ -129,7 +135,6 @@ class SearchFragment : Fragment() {
|
|||||||
count: Int,
|
count: Int,
|
||||||
after: Int
|
after: Int
|
||||||
) {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||||
@ -143,7 +148,6 @@ class SearchFragment : Fragment() {
|
|||||||
if (!searchRecView.canScrollVertically(1)) {
|
if (!searchRecView.canScrollVertically(1)) {
|
||||||
fetchNextSearchItems(autoTextView.text.toString())
|
fetchNextSearchItems(autoTextView.text.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
@ -167,22 +171,23 @@ class SearchFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
autoTextView.setOnEditorActionListener(OnEditorActionListener { _, actionId, _ ->
|
autoTextView.setOnEditorActionListener(
|
||||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
OnEditorActionListener { _, actionId, _ ->
|
||||||
hideKeyboard()
|
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||||
autoTextView.dismissDropDown()
|
hideKeyboard()
|
||||||
return@OnEditorActionListener true
|
autoTextView.dismissDropDown()
|
||||||
|
return@OnEditorActionListener true
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
false
|
)
|
||||||
})
|
|
||||||
autoTextView.setOnItemClickListener { _, _, _, _ ->
|
autoTextView.setOnItemClickListener { _, _, _, _ ->
|
||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchSuggestions(query: String, autoTextView: AutoCompleteTextView){
|
private fun fetchSuggestions(query: String, autoTextView: AutoCompleteTextView) {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.getSuggestions(query)
|
RetrofitInstance.api.getSuggestions(query)
|
||||||
@ -198,7 +203,7 @@ class SearchFragment : Fragment() {
|
|||||||
autoTextView.setAdapter(adapter)
|
autoTextView.setAdapter(adapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun fetchSearch(query: String){
|
private fun fetchSearch(query: String) {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.getSearchResults(query, apiSearchFilter)
|
RetrofitInstance.api.getSearchResults(query, apiSearchFilter)
|
||||||
@ -211,22 +216,22 @@ class SearchFragment : Fragment() {
|
|||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
nextPage = response.nextpage
|
nextPage = response.nextpage
|
||||||
if(response.items!!.isNotEmpty()){
|
if (response.items!!.isNotEmpty()) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
searchAdapter = SearchAdapter(response.items)
|
searchAdapter = SearchAdapter(response.items)
|
||||||
searchRecView.adapter = searchAdapter
|
searchRecView.adapter = searchAdapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchNextSearchItems(query: String){
|
private fun fetchNextSearchItems(query: String) {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
if (!isLoading) {
|
if (!isLoading) {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.getSearchResultsNextPage(query,apiSearchFilter,nextPage!!)
|
RetrofitInstance.api.getSearchResultsNextPage(query, apiSearchFilter, nextPage!!)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
@ -240,7 +245,7 @@ class SearchFragment : Fragment() {
|
|||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
||||||
this ?: return
|
this ?: return
|
||||||
@ -263,18 +268,14 @@ class SearchFragment : Fragment() {
|
|||||||
|
|
||||||
var historyList = getHistory()
|
var historyList = getHistory()
|
||||||
|
|
||||||
|
|
||||||
if (historyList.size != 0 && query == historyList.get(historyList.size - 1)) {
|
if (historyList.size != 0 && query == historyList.get(historyList.size - 1)) {
|
||||||
return
|
return
|
||||||
} else if (query == "") {
|
} else if (query == "") {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
historyList = historyList + query
|
historyList = historyList + query
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (historyList.size > 10) {
|
if (historyList.size > 10) {
|
||||||
historyList = historyList.takeLast(10)
|
historyList = historyList.takeLast(10)
|
||||||
}
|
}
|
||||||
@ -293,7 +294,5 @@ class SearchFragment : Fragment() {
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ import android.widget.Toast
|
|||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
@ -25,26 +24,31 @@ import androidx.preference.ListPreference
|
|||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import org.json.JSONObject
|
|
||||||
import org.json.JSONTokener
|
|
||||||
import retrofit2.HttpException
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
|
import org.json.JSONObject
|
||||||
|
import org.json.JSONTokener
|
||||||
|
import retrofit2.HttpException
|
||||||
|
|
||||||
class SettingsActivity : AppCompatActivity(),
|
class SettingsActivity :
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener{
|
AppCompatActivity(),
|
||||||
|
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
DynamicColors.applyToActivityIfAvailable(this)
|
DynamicColors.applyToActivityIfAvailable(this)
|
||||||
|
updateAccentColor(this)
|
||||||
|
updateThemeMode(this)
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
overridePendingTransition(50, 50);
|
overridePendingTransition(50, 50)
|
||||||
}
|
}
|
||||||
val view = this.findViewById<View>(android.R.id.content)
|
val view = this.findViewById<View>(android.R.id.content)
|
||||||
view.setAlpha(0F);
|
view.alpha = 0F
|
||||||
view.animate().alpha(1F).setDuration(300);
|
view.animate().alpha(1F).duration = 300
|
||||||
|
|
||||||
setContentView(R.layout.activity_settings)
|
setContentView(R.layout.activity_settings)
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
supportFragmentManager
|
supportFragmentManager
|
||||||
@ -55,12 +59,10 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(this)
|
PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
.registerOnSharedPreferenceChangeListener(this)
|
.registerOnSharedPreferenceChangeListener(this)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, rootKey: String?) {}
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, rootKey: String?) {}
|
||||||
|
|
||||||
|
|
||||||
class SettingsFragment : PreferenceFragmentCompat() {
|
class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
val TAG = "Settings"
|
val TAG = "Settings"
|
||||||
|
|
||||||
@ -70,7 +72,6 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
|
getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
|
||||||
|
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
try {
|
try {
|
||||||
// Open a specific media item using ParcelFileDescriptor.
|
// Open a specific media item using ParcelFileDescriptor.
|
||||||
@ -80,23 +81,23 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
|
|
||||||
// "rw" for read-and-write;
|
// "rw" for read-and-write;
|
||||||
// "rwt" for truncating or overwriting existing file contents.
|
// "rwt" for truncating or overwriting existing file contents.
|
||||||
//val readOnlyMode = "r"
|
// val readOnlyMode = "r"
|
||||||
// uri - I have got from onActivityResult
|
// uri - I have got from onActivityResult
|
||||||
val type = resolver.getType(uri)
|
val type = resolver.getType(uri)
|
||||||
|
|
||||||
var inputStream: InputStream? = resolver.openInputStream(uri)
|
var inputStream: InputStream? = resolver.openInputStream(uri)
|
||||||
val channels = ArrayList<String>()
|
val channels = ArrayList<String>()
|
||||||
if(type == "application/json"){
|
if (type == "application/json") {
|
||||||
val json = inputStream?.bufferedReader()?.readLines()?.get(0)
|
val json = inputStream?.bufferedReader()?.readLines()?.get(0)
|
||||||
val jsonObject = JSONTokener(json).nextValue() as JSONObject
|
val jsonObject = JSONTokener(json).nextValue() as JSONObject
|
||||||
Log.e(TAG,jsonObject.getJSONArray("subscriptions").toString())
|
Log.e(TAG, jsonObject.getJSONArray("subscriptions").toString())
|
||||||
for (i in 0 until jsonObject.getJSONArray("subscriptions").length()) {
|
for (i in 0 until jsonObject.getJSONArray("subscriptions").length()) {
|
||||||
var url = jsonObject.getJSONArray("subscriptions").getJSONObject(i).getString("url")
|
var url = jsonObject.getJSONArray("subscriptions").getJSONObject(i).getString("url")
|
||||||
url = url.replace("https://www.youtube.com/channel/","")
|
url = url.replace("https://www.youtube.com/channel/", "")
|
||||||
Log.e(TAG,url)
|
Log.e(TAG, url)
|
||||||
channels.add(url)
|
channels.add(url)
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
if (type == "application/zip") {
|
if (type == "application/zip") {
|
||||||
val zis = ZipInputStream(inputStream)
|
val zis = ZipInputStream(inputStream)
|
||||||
var entry: ZipEntry? = zis.nextEntry
|
var entry: ZipEntry? = zis.nextEntry
|
||||||
@ -129,8 +130,6 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
}
|
}
|
||||||
@ -165,7 +164,7 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
val sponsorblock = findPreference<Preference>("sponsorblock")
|
val sponsorblock = findPreference<Preference>("sponsorblock")
|
||||||
sponsorblock?.setOnPreferenceClickListener {
|
sponsorblock?.setOnPreferenceClickListener {
|
||||||
val newFragment = SponsorBlockSettings()
|
val newFragment = SponsorBlockSettings()
|
||||||
parentFragmentManager.beginTransaction()
|
parentFragmentManager.beginTransaction()
|
||||||
.replace(R.id.settings, newFragment)
|
.replace(R.id.settings, newFragment)
|
||||||
.commitNow()
|
.commitNow()
|
||||||
true
|
true
|
||||||
@ -175,7 +174,7 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
importFromYt?.setOnPreferenceClickListener {
|
importFromYt?.setOnPreferenceClickListener {
|
||||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
val token = sharedPref?.getString("token", "")!!
|
val token = sharedPref?.getString("token", "")!!
|
||||||
//check StorageAccess
|
// check StorageAccess
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
Log.d("myz", "" + Build.VERSION.SDK_INT)
|
Log.d("myz", "" + Build.VERSION.SDK_INT)
|
||||||
if (ContextCompat.checkSelfPermission(
|
if (ContextCompat.checkSelfPermission(
|
||||||
@ -185,11 +184,13 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
!= PackageManager.PERMISSION_GRANTED
|
!= PackageManager.PERMISSION_GRANTED
|
||||||
) {
|
) {
|
||||||
ActivityCompat.requestPermissions(
|
ActivityCompat.requestPermissions(
|
||||||
this.requireActivity(), arrayOf(
|
this.requireActivity(),
|
||||||
|
arrayOf(
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||||
Manifest.permission.MANAGE_EXTERNAL_STORAGE
|
Manifest.permission.MANAGE_EXTERNAL_STORAGE
|
||||||
), 1
|
),
|
||||||
) //permission request code is just an int
|
1
|
||||||
|
) // permission request code is just an int
|
||||||
} else if (token != "") {
|
} else if (token != "") {
|
||||||
getContent.launch("*/*")
|
getContent.launch("*/*")
|
||||||
} else {
|
} else {
|
||||||
@ -200,9 +201,9 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
requireContext(),
|
requireContext(),
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||||
) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(
|
) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
) != PackageManager.PERMISSION_GRANTED
|
) != PackageManager.PERMISSION_GRANTED
|
||||||
) {
|
) {
|
||||||
ActivityCompat.requestPermissions(
|
ActivityCompat.requestPermissions(
|
||||||
this.requireActivity(),
|
this.requireActivity(),
|
||||||
@ -223,11 +224,15 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
|
|
||||||
val themeToggle = findPreference<ListPreference>("theme_togglee")
|
val themeToggle = findPreference<ListPreference>("theme_togglee")
|
||||||
themeToggle?.setOnPreferenceChangeListener { _, newValue ->
|
themeToggle?.setOnPreferenceChangeListener { _, newValue ->
|
||||||
when (newValue.toString()) {
|
val refresh = Intent(context, SettingsActivity::class.java)
|
||||||
"A" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
startActivity(refresh)
|
||||||
"L" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
true
|
||||||
"D" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
}
|
||||||
}
|
|
||||||
|
val accentColor = findPreference<Preference>("accent_color")
|
||||||
|
accentColor?.setOnPreferenceChangeListener { _, _ ->
|
||||||
|
val refresh = Intent(context, SettingsActivity::class.java)
|
||||||
|
startActivity(refresh)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,16 +260,16 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
|
|
||||||
val license = findPreference<Preference>("license")
|
val license = findPreference<Preference>("license")
|
||||||
license?.setOnPreferenceClickListener {
|
license?.setOnPreferenceClickListener {
|
||||||
val licenseString = view?.context?.assets!!.open("gpl3.html").bufferedReader().use{
|
val licenseString = view?.context?.assets!!.open("gpl3.html").bufferedReader().use {
|
||||||
it.readText()
|
it.readText()
|
||||||
}
|
}
|
||||||
val licenseHtml = if (Build.VERSION.SDK_INT >= 24) {
|
val licenseHtml = if (Build.VERSION.SDK_INT >= 24) {
|
||||||
Html.fromHtml(licenseString,1)
|
Html.fromHtml(licenseString, 1)
|
||||||
} else {
|
} else {
|
||||||
Html.fromHtml(licenseString)
|
Html.fromHtml(licenseString)
|
||||||
}
|
}
|
||||||
AlertDialog.Builder(view?.context!!)
|
AlertDialog.Builder(view?.context!!)
|
||||||
.setPositiveButton(getString(R.string.okay), DialogInterface.OnClickListener{ _,_ -> })
|
.setPositiveButton(getString(R.string.okay), DialogInterface.OnClickListener { _, _ -> })
|
||||||
.setMessage(licenseHtml)
|
.setMessage(licenseHtml)
|
||||||
.create()
|
.create()
|
||||||
.show()
|
.show()
|
||||||
@ -318,7 +323,6 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
activity?.runOnUiThread(action)
|
activity?.runOnUiThread(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun subscribe(channels: List<String>) {
|
private fun subscribe(channels: List<String>) {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
|
@ -3,13 +3,10 @@ package com.github.libretube
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.Log
|
|
||||||
import android.view.GestureDetector
|
import android.view.GestureDetector
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.constraintlayout.motion.widget.MotionLayout
|
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -20,7 +17,7 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
class SingleViewTouchableMotionLayout(context: Context, attributeSet: AttributeSet? = null) : MotionLayout(context, attributeSet) {
|
class SingleViewTouchableMotionLayout(context: Context, attributeSet: AttributeSet? = null) : MotionLayout(context, attributeSet) {
|
||||||
|
|
||||||
private val viewToDetectTouch by lazy {
|
private val viewToDetectTouch by lazy {
|
||||||
findViewById<View>(R.id.main_container) //TODO move to Attributes
|
findViewById<View>(R.id.main_container) // TODO move to Attributes
|
||||||
}
|
}
|
||||||
private val viewRect = Rect()
|
private val viewRect = Rect()
|
||||||
private var touchStarted = false
|
private var touchStarted = false
|
||||||
@ -33,7 +30,6 @@ class SingleViewTouchableMotionLayout(context: Context, attributeSet: AttributeS
|
|||||||
startId: Int,
|
startId: Int,
|
||||||
endId: Int
|
endId: Int
|
||||||
) {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
|
override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
|
||||||
@ -49,7 +45,6 @@ class SingleViewTouchableMotionLayout(context: Context, attributeSet: AttributeS
|
|||||||
positive: Boolean,
|
positive: Boolean,
|
||||||
progress: Float
|
progress: Float
|
||||||
) {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -59,7 +54,6 @@ class SingleViewTouchableMotionLayout(context: Context, attributeSet: AttributeS
|
|||||||
startId: Int,
|
startId: Int,
|
||||||
endId: Int
|
endId: Int
|
||||||
) {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
|
override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
|
||||||
@ -78,7 +72,6 @@ class SingleViewTouchableMotionLayout(context: Context, attributeSet: AttributeS
|
|||||||
positive: Boolean,
|
positive: Boolean,
|
||||||
progress: Float
|
progress: Float
|
||||||
) {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -91,15 +84,18 @@ class SingleViewTouchableMotionLayout(context: Context, attributeSet: AttributeS
|
|||||||
transitionListenerList += listener
|
transitionListenerList += listener
|
||||||
}
|
}
|
||||||
|
|
||||||
private val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
|
private val gestureDetector = GestureDetector(
|
||||||
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
|
context,
|
||||||
transitionToEnd()
|
object : GestureDetector.SimpleOnGestureListener() {
|
||||||
return false
|
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
|
||||||
|
transitionToEnd()
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
|
|
||||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||||
//gestureDetector.onTouchEvent(event)
|
// gestureDetector.onTouchEvent(event)
|
||||||
when (event.actionMasked) {
|
when (event.actionMasked) {
|
||||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||||
touchStarted = false
|
touchStarted = false
|
||||||
|
@ -3,29 +3,28 @@ package com.github.libretube
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import com.github.libretube.adapters.SubscriptionAdapter
|
import com.github.libretube.adapters.SubscriptionAdapter
|
||||||
import com.github.libretube.adapters.SubscriptionChannelAdapter
|
import com.github.libretube.adapters.SubscriptionChannelAdapter
|
||||||
|
import java.io.IOException
|
||||||
import org.chromium.base.ThreadUtils.runOnUiThread
|
import org.chromium.base.ThreadUtils.runOnUiThread
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
class Subscriptions : Fragment() {
|
class Subscriptions : Fragment() {
|
||||||
val TAG = "SubFragment"
|
val TAG = "SubFragment"
|
||||||
lateinit var token: String
|
lateinit var token: String
|
||||||
var isLoaded = false
|
var isLoaded = false
|
||||||
private var subscriptionAdapter: SubscriptionAdapter? =null
|
private var subscriptionAdapter: SubscriptionAdapter? = null
|
||||||
private var refreshLayout: SwipeRefreshLayout? = null
|
private var refreshLayout: SwipeRefreshLayout? = null
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -34,7 +33,8 @@ class Subscriptions : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
@ -44,14 +44,14 @@ class Subscriptions : Fragment() {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
token = sharedPref?.getString("token","")!!
|
token = sharedPref?.getString("token", "")!!
|
||||||
refreshLayout = view.findViewById(R.id.sub_refresh)
|
refreshLayout = view.findViewById(R.id.sub_refresh)
|
||||||
if(token!=""){
|
if (token != "") {
|
||||||
view.findViewById<RelativeLayout>(R.id.loginOrRegister).visibility=View.GONE
|
view.findViewById<RelativeLayout>(R.id.loginOrRegister).visibility = View.GONE
|
||||||
refreshLayout?.isEnabled = true
|
refreshLayout?.isEnabled = true
|
||||||
|
|
||||||
var progressBar = view.findViewById<ProgressBar>(R.id.sub_progress)
|
var progressBar = view.findViewById<ProgressBar>(R.id.sub_progress)
|
||||||
progressBar.visibility=View.VISIBLE
|
progressBar.visibility = View.VISIBLE
|
||||||
|
|
||||||
var channelRecView = view.findViewById<RecyclerView>(R.id.sub_channels)
|
var channelRecView = view.findViewById<RecyclerView>(R.id.sub_channels)
|
||||||
|
|
||||||
@ -78,8 +78,7 @@ class Subscriptions : Fragment() {
|
|||||||
}
|
}
|
||||||
channelRecView.visibility = View.VISIBLE
|
channelRecView.visibility = View.VISIBLE
|
||||||
feedRecView.visibility = View.GONE
|
feedRecView.visibility = View.GONE
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
channelRecView.visibility = View.GONE
|
channelRecView.visibility = View.GONE
|
||||||
feedRecView.visibility = View.VISIBLE
|
feedRecView.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
@ -89,14 +88,14 @@ class Subscriptions : Fragment() {
|
|||||||
scrollView.viewTreeObserver
|
scrollView.viewTreeObserver
|
||||||
.addOnScrollChangedListener {
|
.addOnScrollChangedListener {
|
||||||
if (scrollView.getChildAt(0).bottom
|
if (scrollView.getChildAt(0).bottom
|
||||||
== (scrollView.height + scrollView.scrollY)) {
|
== (scrollView.height + scrollView.scrollY)
|
||||||
//scroll view is at bottom
|
) {
|
||||||
if(isLoaded){
|
// scroll view is at bottom
|
||||||
|
if (isLoaded) {
|
||||||
refreshLayout?.isRefreshing = true
|
refreshLayout?.isRefreshing = true
|
||||||
subscriptionAdapter?.updateItems()
|
subscriptionAdapter?.updateItems()
|
||||||
refreshLayout?.isRefreshing = false
|
refreshLayout?.isRefreshing = false
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -109,8 +108,8 @@ class Subscriptions : Fragment() {
|
|||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.getFeed(token)
|
RetrofitInstance.api.getFeed(token)
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.e(TAG,e.toString())
|
Log.e(TAG, e.toString())
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
@ -119,25 +118,25 @@ class Subscriptions : Fragment() {
|
|||||||
} finally {
|
} finally {
|
||||||
refreshLayout?.isRefreshing = false
|
refreshLayout?.isRefreshing = false
|
||||||
}
|
}
|
||||||
if (response.isNotEmpty()){
|
if (response.isNotEmpty()) {
|
||||||
subscriptionAdapter = SubscriptionAdapter(response)
|
subscriptionAdapter = SubscriptionAdapter(response)
|
||||||
feedRecView?.adapter= subscriptionAdapter
|
feedRecView?.adapter = subscriptionAdapter
|
||||||
subscriptionAdapter?.updateItems()
|
subscriptionAdapter?.updateItems()
|
||||||
}else{
|
} else {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
with(view.findViewById<ImageView>(R.id.boogh)){
|
with(view.findViewById<ImageView>(R.id.boogh)) {
|
||||||
visibility=View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
setImageResource(R.drawable.ic_list)
|
setImageResource(R.drawable.ic_list)
|
||||||
}
|
}
|
||||||
with(view.findViewById<TextView>(R.id.textLike)){
|
with(view.findViewById<TextView>(R.id.textLike)) {
|
||||||
visibility=View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
text = getString(R.string.emptyList)
|
text = getString(R.string.emptyList)
|
||||||
}
|
}
|
||||||
view.findViewById<RelativeLayout>(R.id.loginOrRegister).visibility=View.VISIBLE
|
view.findViewById<RelativeLayout>(R.id.loginOrRegister).visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
progressBar.visibility=View.GONE
|
progressBar.visibility = View.GONE
|
||||||
isLoaded=true
|
isLoaded = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
@ -148,8 +147,8 @@ class Subscriptions : Fragment() {
|
|||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.subscriptions(token)
|
RetrofitInstance.api.subscriptions(token)
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.e(TAG,e.toString())
|
Log.e(TAG, e.toString())
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
@ -158,25 +157,24 @@ class Subscriptions : Fragment() {
|
|||||||
} finally {
|
} finally {
|
||||||
refreshLayout?.isRefreshing = false
|
refreshLayout?.isRefreshing = false
|
||||||
}
|
}
|
||||||
if (response.isNotEmpty()){
|
if (response.isNotEmpty()) {
|
||||||
channelRecView?.adapter=SubscriptionChannelAdapter(response.toMutableList())
|
channelRecView?.adapter = SubscriptionChannelAdapter(response.toMutableList())
|
||||||
}else{
|
} else {
|
||||||
Toast.makeText(context,R.string.subscribeIsEmpty, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.subscribeIsEmpty, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
}
|
}
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
Log.e(TAG,"Destroyed")
|
Log.e(TAG, "Destroyed")
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
subscriptionAdapter = null
|
subscriptionAdapter = null
|
||||||
view?.findViewById<RecyclerView>(R.id.sub_feed)?.adapter=null
|
view?.findViewById<RecyclerView>(R.id.sub_feed)?.adapter = null
|
||||||
}
|
}
|
||||||
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
||||||
this ?: return
|
this ?: return
|
||||||
if (!isAdded) return // Fragment not attached to an Activity
|
if (!isAdded) return // Fragment not attached to an Activity
|
||||||
activity?.runOnUiThread(action)
|
activity?.runOnUiThread(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
53
app/src/main/java/com/github/libretube/ThemeChanger.kt
Normal file
53
app/src/main/java/com/github/libretube/ThemeChanger.kt
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package com.github.libretube
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun updateAccentColor(context: Context) {
|
||||||
|
val colorAccent = PreferenceManager.getDefaultSharedPreferences(context).getString("accent_color", "red")
|
||||||
|
when (colorAccent) {
|
||||||
|
"my" -> context.setTheme(R.style.Theme_MY)
|
||||||
|
"red" -> context.setTheme(R.style.Theme_Red)
|
||||||
|
"blue" -> context.setTheme(R.style.Theme_Blue)
|
||||||
|
"yellow" -> context.setTheme(R.style.Theme_Yellow)
|
||||||
|
"green" -> context.setTheme(R.style.Theme_Green)
|
||||||
|
"purple" -> context.setTheme(R.style.Theme_Purple)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateThemeMode(context: Context) {
|
||||||
|
val themeMode = PreferenceManager.getDefaultSharedPreferences(context).getString("theme_togglee", "A")
|
||||||
|
when (themeMode) {
|
||||||
|
"A" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||||
|
"L" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
||||||
|
"D" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
||||||
|
"O" -> oledMode(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun oledMode(context: Context) {
|
||||||
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
||||||
|
context.setTheme(R.style.Theme_OLED)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateLanguage(context: Context) {
|
||||||
|
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
|
val languageName = sharedPreferences.getString("language", "sys")
|
||||||
|
if (languageName != "") {
|
||||||
|
var locale = if (languageName != "sys" && "$languageName".length < 3) {
|
||||||
|
Locale(languageName)
|
||||||
|
} else if ("$languageName".length > 3) {
|
||||||
|
Locale(languageName?.substring(0, 2), languageName?.substring(4, 6))
|
||||||
|
} else {
|
||||||
|
Locale.getDefault()
|
||||||
|
}
|
||||||
|
val res = context.resources
|
||||||
|
val dm = res.displayMetrics
|
||||||
|
val conf = res.configuration
|
||||||
|
conf.setLocale(locale)
|
||||||
|
Locale.setDefault(locale)
|
||||||
|
res.updateConfiguration(conf, dm)
|
||||||
|
}
|
||||||
|
}
|
@ -15,31 +15,31 @@ import com.github.libretube.formatShort
|
|||||||
import com.github.libretube.obj.StreamItem
|
import com.github.libretube.obj.StreamItem
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
|
||||||
class ChannelAdapter(private val videoFeed: MutableList<StreamItem>): RecyclerView.Adapter<ChannelViewHolder>() {
|
class ChannelAdapter(private val videoFeed: MutableList<StreamItem>) : RecyclerView.Adapter<ChannelViewHolder>() {
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return videoFeed.size
|
return videoFeed.size
|
||||||
}
|
}
|
||||||
fun updateItems(newItems: List<StreamItem>){
|
fun updateItems(newItems: List<StreamItem>) {
|
||||||
videoFeed.addAll(newItems)
|
videoFeed.addAll(newItems)
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChannelViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChannelViewHolder {
|
||||||
val layoutInflater = LayoutInflater.from(parent.context)
|
val layoutInflater = LayoutInflater.from(parent.context)
|
||||||
val cell = layoutInflater.inflate(R.layout.video_channel_row,parent,false)
|
val cell = layoutInflater.inflate(R.layout.video_channel_row, parent, false)
|
||||||
return ChannelViewHolder(cell)
|
return ChannelViewHolder(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ChannelViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ChannelViewHolder, position: Int) {
|
||||||
val trending = videoFeed[position]
|
val trending = videoFeed[position]
|
||||||
holder.v.findViewById<TextView>(R.id.channel_description).text = trending.title
|
holder.v.findViewById<TextView>(R.id.channel_description).text = trending.title
|
||||||
holder.v.findViewById<TextView>(R.id.channel_views).text = trending.views.formatShort()+" • "+ DateUtils.getRelativeTimeSpanString(trending.uploaded!!)
|
holder.v.findViewById<TextView>(R.id.channel_views).text = trending.views.formatShort() + " • " + DateUtils.getRelativeTimeSpanString(trending.uploaded!!)
|
||||||
holder.v.findViewById<TextView>(R.id.channel_duration).text = DateUtils.formatElapsedTime(trending.duration!!)
|
holder.v.findViewById<TextView>(R.id.channel_duration).text = DateUtils.formatElapsedTime(trending.duration!!)
|
||||||
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.channel_thumbnail)
|
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.channel_thumbnail)
|
||||||
Picasso.get().load(trending.thumbnail).into(thumbnailImage)
|
Picasso.get().load(trending.thumbnail).into(thumbnailImage)
|
||||||
holder.v.setOnClickListener{
|
holder.v.setOnClickListener {
|
||||||
var bundle = Bundle()
|
var bundle = Bundle()
|
||||||
bundle.putString("videoId",trending.url!!.replace("/watch?v=",""))
|
bundle.putString("videoId", trending.url!!.replace("/watch?v=", ""))
|
||||||
var frag = PlayerFragment()
|
var frag = PlayerFragment()
|
||||||
frag.arguments = bundle
|
frag.arguments = bundle
|
||||||
val activity = holder.v.context as AppCompatActivity
|
val activity = holder.v.context as AppCompatActivity
|
||||||
@ -52,7 +52,7 @@ class ChannelAdapter(private val videoFeed: MutableList<StreamItem>): RecyclerVi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ChannelViewHolder(val v: View): RecyclerView.ViewHolder(v){
|
class ChannelViewHolder(val v: View) : RecyclerView.ViewHolder(v) {
|
||||||
init {
|
init {
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package com.github.libretube.adapters
|
package com.github.libretube.adapters
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -15,9 +14,9 @@ import com.github.libretube.formatShort
|
|||||||
import com.github.libretube.obj.Comment
|
import com.github.libretube.obj.Comment
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
|
||||||
class CommentsAdapter(private val comments: MutableList<Comment>): RecyclerView.Adapter<ViewHolder>(){
|
class CommentsAdapter(private val comments: MutableList<Comment>) : RecyclerView.Adapter<ViewHolder>() {
|
||||||
|
|
||||||
fun updateItems(newItems: List<Comment>){
|
fun updateItems(newItems: List<Comment>) {
|
||||||
var commentsSize = comments.size
|
var commentsSize = comments.size
|
||||||
comments.addAll(newItems)
|
comments.addAll(newItems)
|
||||||
notifyItemRangeInserted(commentsSize, newItems.size)
|
notifyItemRangeInserted(commentsSize, newItems.size)
|
||||||
@ -43,7 +42,7 @@ class CommentsAdapter(private val comments: MutableList<Comment>): RecyclerView
|
|||||||
if (comments[position].hearted == true) {
|
if (comments[position].hearted == true) {
|
||||||
holder.v.findViewById<ImageView>(R.id.hearted_imageView).visibility = View.VISIBLE
|
holder.v.findViewById<ImageView>(R.id.hearted_imageView).visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
channelImage.setOnClickListener{
|
channelImage.setOnClickListener {
|
||||||
val activity = holder.v.context as MainActivity
|
val activity = holder.v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to comments[position].commentorUrl)
|
val bundle = bundleOf("channel_id" to comments[position].commentorUrl)
|
||||||
activity.navController.navigate(R.id.channel, bundle)
|
activity.navController.navigate(R.id.channel, bundle)
|
||||||
@ -53,8 +52,7 @@ class CommentsAdapter(private val comments: MutableList<Comment>): RecyclerView
|
|||||||
mainMotionLayout.transitionToEnd()
|
mainMotionLayout.transitionToEnd()
|
||||||
activity.findViewById<MotionLayout>(R.id.playerMotionLayout).transitionToEnd()
|
activity.findViewById<MotionLayout>(R.id.playerMotionLayout).transitionToEnd()
|
||||||
}
|
}
|
||||||
}catch (e: Exception){
|
} catch (e: Exception) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,10 +60,9 @@ class CommentsAdapter(private val comments: MutableList<Comment>): RecyclerView
|
|||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return comments.size
|
return comments.size
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewHolder(val v: View): RecyclerView.ViewHolder(v){
|
class ViewHolder(val v: View) : RecyclerView.ViewHolder(v) {
|
||||||
init {
|
init {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,24 +18,29 @@ import com.github.libretube.RetrofitInstance
|
|||||||
import com.github.libretube.obj.PlaylistId
|
import com.github.libretube.obj.PlaylistId
|
||||||
import com.github.libretube.obj.StreamItem
|
import com.github.libretube.obj.StreamItem
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
import java.io.IOException
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
class PlaylistAdapter(private val videoFeed: MutableList<StreamItem>, private val playlistId: String, private val isOwner: Boolean, private val activity: Activity): RecyclerView.Adapter<PlaylistViewHolder>() {
|
class PlaylistAdapter(
|
||||||
|
private val videoFeed: MutableList<StreamItem>,
|
||||||
|
private val playlistId: String,
|
||||||
|
private val isOwner: Boolean,
|
||||||
|
private val activity: Activity
|
||||||
|
) : RecyclerView.Adapter<PlaylistViewHolder>() {
|
||||||
private val TAG = "PlaylistAdapter"
|
private val TAG = "PlaylistAdapter"
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return videoFeed.size
|
return videoFeed.size
|
||||||
}
|
}
|
||||||
fun updateItems(newItems: List<StreamItem>){
|
fun updateItems(newItems: List<StreamItem>) {
|
||||||
videoFeed.addAll(newItems)
|
videoFeed.addAll(newItems)
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlaylistViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlaylistViewHolder {
|
||||||
val layoutInflater = LayoutInflater.from(parent.context)
|
val layoutInflater = LayoutInflater.from(parent.context)
|
||||||
val cell = layoutInflater.inflate(R.layout.playlist_row,parent,false)
|
val cell = layoutInflater.inflate(R.layout.playlist_row, parent, false)
|
||||||
return PlaylistViewHolder(cell)
|
return PlaylistViewHolder(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,9 +51,9 @@ class PlaylistAdapter(private val videoFeed: MutableList<StreamItem>, private va
|
|||||||
holder.v.findViewById<TextView>(R.id.playlist_duration).text = DateUtils.formatElapsedTime(streamItem.duration!!)
|
holder.v.findViewById<TextView>(R.id.playlist_duration).text = DateUtils.formatElapsedTime(streamItem.duration!!)
|
||||||
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.playlist_thumbnail)
|
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.playlist_thumbnail)
|
||||||
Picasso.get().load(streamItem.thumbnail).into(thumbnailImage)
|
Picasso.get().load(streamItem.thumbnail).into(thumbnailImage)
|
||||||
holder.v.setOnClickListener{
|
holder.v.setOnClickListener {
|
||||||
var bundle = Bundle()
|
var bundle = Bundle()
|
||||||
bundle.putString("videoId",streamItem.url!!.replace("/watch?v=",""))
|
bundle.putString("videoId", streamItem.url!!.replace("/watch?v=", ""))
|
||||||
var frag = PlayerFragment()
|
var frag = PlayerFragment()
|
||||||
frag.arguments = bundle
|
frag.arguments = bundle
|
||||||
val activity = holder.v.context as AppCompatActivity
|
val activity = holder.v.context as AppCompatActivity
|
||||||
@ -59,34 +64,33 @@ class PlaylistAdapter(private val videoFeed: MutableList<StreamItem>, private va
|
|||||||
.replace(R.id.container, frag)
|
.replace(R.id.container, frag)
|
||||||
.commitNow()
|
.commitNow()
|
||||||
}
|
}
|
||||||
if(isOwner){
|
if (isOwner) {
|
||||||
val delete = holder.v.findViewById<ImageView>(R.id.delete_playlist)
|
val delete = holder.v.findViewById<ImageView>(R.id.delete_playlist)
|
||||||
delete.visibility = View.VISIBLE
|
delete.visibility = View.VISIBLE
|
||||||
delete.setOnClickListener {
|
delete.setOnClickListener {
|
||||||
val sharedPref = holder.v.context.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = holder.v.context.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
val token = sharedPref?.getString("token","")!!
|
val token = sharedPref?.getString("token", "")!!
|
||||||
removeFromPlaylist(token, position)
|
removeFromPlaylist(token, position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun removeFromPlaylist(token: String, position: Int) {
|
private fun removeFromPlaylist(token: String, position: Int) {
|
||||||
fun run() {
|
fun run() {
|
||||||
GlobalScope.launch{
|
GlobalScope.launch {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.removeFromPlaylist(token, PlaylistId(playlistId = playlistId, index = position))
|
RetrofitInstance.api.removeFromPlaylist(token, PlaylistId(playlistId = playlistId, index = position))
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
return@launch
|
return@launch
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
Log.e(TAG, "HttpException, unexpected response")
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
return@launch
|
return@launch
|
||||||
}finally {
|
} finally {
|
||||||
|
|
||||||
}
|
}
|
||||||
try{
|
try {
|
||||||
if(response.message == "ok"){
|
if (response.message == "ok") {
|
||||||
Log.d(TAG,"deleted!")
|
Log.d(TAG, "deleted!")
|
||||||
videoFeed.removeAt(position)
|
videoFeed.removeAt(position)
|
||||||
// FIXME: This needs to run on UI thread?
|
// FIXME: This needs to run on UI thread?
|
||||||
activity.runOnUiThread { notifyDataSetChanged() }
|
activity.runOnUiThread { notifyDataSetChanged() }
|
||||||
@ -95,17 +99,15 @@ class PlaylistAdapter(private val videoFeed: MutableList<StreamItem>, private va
|
|||||||
view.findViewById<ImageView>(R.id.boogh2).visibility=View.VISIBLE
|
view.findViewById<ImageView>(R.id.boogh2).visibility=View.VISIBLE
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
}catch (e:Exception){
|
} catch (e: Exception) {
|
||||||
Log.e(TAG,e.toString())
|
Log.e(TAG, e.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class PlaylistViewHolder(val v: View): RecyclerView.ViewHolder(v){
|
class PlaylistViewHolder(val v: View) : RecyclerView.ViewHolder(v) {
|
||||||
init {
|
init {
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,25 +17,27 @@ import com.github.libretube.RetrofitInstance
|
|||||||
import com.github.libretube.obj.PlaylistId
|
import com.github.libretube.obj.PlaylistId
|
||||||
import com.github.libretube.obj.Playlists
|
import com.github.libretube.obj.Playlists
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
import java.io.IOException
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
|
class PlaylistsAdapter(
|
||||||
class PlaylistsAdapter(private val playlists: MutableList<Playlists>, private val activity: Activity): RecyclerView.Adapter<PlaylistsViewHolder>() {
|
private val playlists: MutableList<Playlists>,
|
||||||
|
private val activity: Activity
|
||||||
|
) : RecyclerView.Adapter<PlaylistsViewHolder>() {
|
||||||
val TAG = "PlaylistsAdapter"
|
val TAG = "PlaylistsAdapter"
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return playlists.size
|
return playlists.size
|
||||||
}
|
}
|
||||||
fun updateItems(newItems: List<Playlists>){
|
fun updateItems(newItems: List<Playlists>) {
|
||||||
playlists.addAll(newItems)
|
playlists.addAll(newItems)
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlaylistsViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlaylistsViewHolder {
|
||||||
val layoutInflater = LayoutInflater.from(parent.context)
|
val layoutInflater = LayoutInflater.from(parent.context)
|
||||||
val cell = layoutInflater.inflate(R.layout.playlists_row,parent,false)
|
val cell = layoutInflater.inflate(R.layout.playlists_row, parent, false)
|
||||||
return PlaylistsViewHolder(cell)
|
return PlaylistsViewHolder(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +52,7 @@ class PlaylistsAdapter(private val playlists: MutableList<Playlists>, private va
|
|||||||
builder.setMessage(R.string.areYouSure)
|
builder.setMessage(R.string.areYouSure)
|
||||||
builder.setPositiveButton(R.string.yes) { dialog, which ->
|
builder.setPositiveButton(R.string.yes) { dialog, which ->
|
||||||
val sharedPref = holder.v.context.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = holder.v.context.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
val token = sharedPref?.getString("token","")!!
|
val token = sharedPref?.getString("token", "")!!
|
||||||
deletePlaylist(playlist.id!!, token, position)
|
deletePlaylist(playlist.id!!, token, position)
|
||||||
}
|
}
|
||||||
builder.setNegativeButton(R.string.cancel) { dialog, which ->
|
builder.setNegativeButton(R.string.cancel) { dialog, which ->
|
||||||
@ -58,31 +60,29 @@ class PlaylistsAdapter(private val playlists: MutableList<Playlists>, private va
|
|||||||
builder.show()
|
builder.show()
|
||||||
}
|
}
|
||||||
holder.v.setOnClickListener {
|
holder.v.setOnClickListener {
|
||||||
//playlists clicked
|
// playlists clicked
|
||||||
val activity = holder.v.context as MainActivity
|
val activity = holder.v.context as MainActivity
|
||||||
val bundle = bundleOf("playlist_id" to playlist.id)
|
val bundle = bundleOf("playlist_id" to playlist.id)
|
||||||
activity.navController.navigate(R.id.playlistFragment,bundle)
|
activity.navController.navigate(R.id.playlistFragment, bundle)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
private fun deletePlaylist(id: String, token: String, position: Int) {
|
private fun deletePlaylist(id: String, token: String, position: Int) {
|
||||||
fun run() {
|
fun run() {
|
||||||
GlobalScope.launch{
|
GlobalScope.launch {
|
||||||
val response = try {
|
val response = try {
|
||||||
RetrofitInstance.api.deletePlaylist(token, PlaylistId(id))
|
RetrofitInstance.api.deletePlaylist(token, PlaylistId(id))
|
||||||
}catch(e: IOException) {
|
} catch (e: IOException) {
|
||||||
println(e)
|
println(e)
|
||||||
Log.e(TAG, "IOException, you might not have internet connection")
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
return@launch
|
return@launch
|
||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
Log.e(TAG, "HttpException, unexpected response")
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
return@launch
|
return@launch
|
||||||
}finally {
|
} finally {
|
||||||
|
|
||||||
}
|
}
|
||||||
try{
|
try {
|
||||||
if(response.message == "ok"){
|
if (response.message == "ok") {
|
||||||
Log.d(TAG,"deleted!")
|
Log.d(TAG, "deleted!")
|
||||||
playlists.removeAt(position)
|
playlists.removeAt(position)
|
||||||
// FIXME: This needs to run on UI thread?
|
// FIXME: This needs to run on UI thread?
|
||||||
activity.runOnUiThread { notifyDataSetChanged() }
|
activity.runOnUiThread { notifyDataSetChanged() }
|
||||||
@ -91,18 +91,15 @@ class PlaylistsAdapter(private val playlists: MutableList<Playlists>, private va
|
|||||||
view.findViewById<ImageView>(R.id.boogh2).visibility=View.VISIBLE
|
view.findViewById<ImageView>(R.id.boogh2).visibility=View.VISIBLE
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
}catch (e:Exception){
|
} catch (e: Exception) {
|
||||||
Log.e(TAG,e.toString())
|
Log.e(TAG, e.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run()
|
run()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
class PlaylistsViewHolder(val v: View): RecyclerView.ViewHolder(v){
|
class PlaylistsViewHolder(val v: View) : RecyclerView.ViewHolder(v) {
|
||||||
init {
|
init {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,9 @@ import com.github.libretube.formatShort
|
|||||||
import com.github.libretube.obj.SearchItem
|
import com.github.libretube.obj.SearchItem
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
|
||||||
|
class SearchAdapter(private val searchItems: MutableList<SearchItem>) : RecyclerView.Adapter<CustomViewHolder1>() {
|
||||||
|
|
||||||
class SearchAdapter(private val searchItems: MutableList<SearchItem>): RecyclerView.Adapter<CustomViewHolder1>() {
|
fun updateItems(newItems: List<SearchItem>) {
|
||||||
|
|
||||||
fun updateItems(newItems: List<SearchItem>){
|
|
||||||
var searchItemsSize = searchItems.size
|
var searchItemsSize = searchItems.size
|
||||||
searchItems.addAll(newItems)
|
searchItems.addAll(newItems)
|
||||||
notifyItemRangeInserted(searchItemsSize, newItems.size)
|
notifyItemRangeInserted(searchItemsSize, newItems.size)
|
||||||
@ -38,7 +37,7 @@ class SearchAdapter(private val searchItems: MutableList<SearchItem>): RecyclerV
|
|||||||
else -> throw IllegalArgumentException("Invalid type")
|
else -> throw IllegalArgumentException("Invalid type")
|
||||||
}
|
}
|
||||||
val layoutInflater = LayoutInflater.from(parent.context)
|
val layoutInflater = LayoutInflater.from(parent.context)
|
||||||
val cell = layoutInflater.inflate(layout,parent,false)
|
val cell = layoutInflater.inflate(layout, parent, false)
|
||||||
return CustomViewHolder1(cell)
|
return CustomViewHolder1(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,14 +47,14 @@ class SearchAdapter(private val searchItems: MutableList<SearchItem>): RecyclerV
|
|||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
return when {
|
return when {
|
||||||
searchItems[position].url!!.startsWith("/watch",false) -> 0
|
searchItems[position].url!!.startsWith("/watch", false) -> 0
|
||||||
searchItems[position].url!!.startsWith("/channel",false) -> 1
|
searchItems[position].url!!.startsWith("/channel", false) -> 1
|
||||||
searchItems[position].url!!.startsWith("/playlist",false) -> 2
|
searchItems[position].url!!.startsWith("/playlist", false) -> 2
|
||||||
else -> 3
|
else -> 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class CustomViewHolder1(private val v: View): RecyclerView.ViewHolder(v){
|
class CustomViewHolder1(private val v: View) : RecyclerView.ViewHolder(v) {
|
||||||
|
|
||||||
private fun bindWatch(item: SearchItem) {
|
private fun bindWatch(item: SearchItem) {
|
||||||
val thumbnailImage = v.findViewById<ImageView>(R.id.search_thumbnail)
|
val thumbnailImage = v.findViewById<ImageView>(R.id.search_thumbnail)
|
||||||
@ -72,9 +71,9 @@ class CustomViewHolder1(private val v: View): RecyclerView.ViewHolder(v){
|
|||||||
views.text = if (viewsString != "" && uploadDate != "") viewsString + " • " + uploadDate else viewsString + uploadDate
|
views.text = if (viewsString != "" && uploadDate != "") viewsString + " • " + uploadDate else viewsString + uploadDate
|
||||||
val channelName = v.findViewById<TextView>(R.id.search_channel_name)
|
val channelName = v.findViewById<TextView>(R.id.search_channel_name)
|
||||||
channelName.text = item.uploaderName
|
channelName.text = item.uploaderName
|
||||||
v.setOnClickListener{
|
v.setOnClickListener {
|
||||||
var bundle = Bundle()
|
var bundle = Bundle()
|
||||||
bundle.putString("videoId",item.url!!.replace("/watch?v=",""))
|
bundle.putString("videoId", item.url!!.replace("/watch?v=", ""))
|
||||||
var frag = PlayerFragment()
|
var frag = PlayerFragment()
|
||||||
frag.arguments = bundle
|
frag.arguments = bundle
|
||||||
val activity = v.context as AppCompatActivity
|
val activity = v.context as AppCompatActivity
|
||||||
@ -101,9 +100,9 @@ class CustomViewHolder1(private val v: View): RecyclerView.ViewHolder(v){
|
|||||||
v.setOnClickListener {
|
v.setOnClickListener {
|
||||||
val activity = v.context as MainActivity
|
val activity = v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to item.url)
|
val bundle = bundleOf("channel_id" to item.url)
|
||||||
activity.navController.navigate(R.id.channel,bundle)
|
activity.navController.navigate(R.id.channel, bundle)
|
||||||
}
|
}
|
||||||
//todo sub button
|
// todo sub button
|
||||||
}
|
}
|
||||||
private fun bindPlaylist(item: SearchItem) {
|
private fun bindPlaylist(item: SearchItem) {
|
||||||
val playlistImage = v.findViewById<ImageView>(R.id.search_thumbnail)
|
val playlistImage = v.findViewById<ImageView>(R.id.search_thumbnail)
|
||||||
@ -117,18 +116,18 @@ class CustomViewHolder1(private val v: View): RecyclerView.ViewHolder(v){
|
|||||||
val playlistVideosNumber = v.findViewById<TextView>(R.id.search_playlist_videos)
|
val playlistVideosNumber = v.findViewById<TextView>(R.id.search_playlist_videos)
|
||||||
if (item.videos?.toInt() != -1) playlistVideosNumber.text = v.context.getString(R.string.videoCount, item.videos.toString())
|
if (item.videos?.toInt() != -1) playlistVideosNumber.text = v.context.getString(R.string.videoCount, item.videos.toString())
|
||||||
v.setOnClickListener {
|
v.setOnClickListener {
|
||||||
//playlist clicked
|
// playlist clicked
|
||||||
val activity = v.context as MainActivity
|
val activity = v.context as MainActivity
|
||||||
val bundle = bundleOf("playlist_id" to item.url)
|
val bundle = bundleOf("playlist_id" to item.url)
|
||||||
activity.navController.navigate(R.id.playlistFragment,bundle)
|
activity.navController.navigate(R.id.playlistFragment, bundle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bind(searchItem: SearchItem) {
|
fun bind(searchItem: SearchItem) {
|
||||||
when {
|
when {
|
||||||
searchItem.url!!.startsWith("/watch",false) -> bindWatch(searchItem)
|
searchItem.url!!.startsWith("/watch", false) -> bindWatch(searchItem)
|
||||||
searchItem.url!!.startsWith("/channel",false) -> bindChannel(searchItem)
|
searchItem.url!!.startsWith("/channel", false) -> bindChannel(searchItem)
|
||||||
searchItem.url!!.startsWith("/playlist",false) -> bindPlaylist(searchItem)
|
searchItem.url!!.startsWith("/playlist", false) -> bindPlaylist(searchItem)
|
||||||
else -> {
|
else -> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,16 +11,17 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import com.github.libretube.R
|
import com.github.libretube.R
|
||||||
import com.google.android.material.imageview.ShapeableImageView
|
import com.google.android.material.imageview.ShapeableImageView
|
||||||
|
|
||||||
|
class SearchHistoryAdapter(
|
||||||
class SearchHistoryAdapter(private val context: Context, private var historyList: List<String> , private val editText : AutoCompleteTextView) :
|
private val context: Context,
|
||||||
|
private var historyList: List<String>,
|
||||||
|
private val editText: AutoCompleteTextView
|
||||||
|
) :
|
||||||
RecyclerView.Adapter<SearchHistoryViewHolder>() {
|
RecyclerView.Adapter<SearchHistoryViewHolder>() {
|
||||||
|
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return historyList.size
|
return historyList.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchHistoryViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchHistoryViewHolder {
|
||||||
val layoutInflater = LayoutInflater.from(parent.context)
|
val layoutInflater = LayoutInflater.from(parent.context)
|
||||||
val cell = layoutInflater.inflate(R.layout.searchhistory_row, parent, false)
|
val cell = layoutInflater.inflate(R.layout.searchhistory_row, parent, false)
|
||||||
@ -31,7 +32,6 @@ class SearchHistoryAdapter(private val context: Context, private var historyList
|
|||||||
val history = historyList[position]
|
val history = historyList[position]
|
||||||
holder.v.findViewById<TextView>(R.id.history_text).text = history
|
holder.v.findViewById<TextView>(R.id.history_text).text = history
|
||||||
|
|
||||||
|
|
||||||
holder.v.findViewById<ShapeableImageView>(R.id.delete_history).setOnClickListener {
|
holder.v.findViewById<ShapeableImageView>(R.id.delete_history).setOnClickListener {
|
||||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
|
|
||||||
|
@ -18,35 +18,35 @@ import com.github.libretube.formatShort
|
|||||||
import com.github.libretube.obj.StreamItem
|
import com.github.libretube.obj.StreamItem
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
|
||||||
class SubscriptionAdapter(private val videoFeed: List<StreamItem>): RecyclerView.Adapter<SubscriptionViewHolder>() {
|
class SubscriptionAdapter(private val videoFeed: List<StreamItem>) : RecyclerView.Adapter<SubscriptionViewHolder>() {
|
||||||
//private var limitedVideoFeed: MutableList<String> = [""].toMutableList()
|
// private var limitedVideoFeed: MutableList<String> = [""].toMutableList()
|
||||||
var i = 0
|
var i = 0
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateItems(){
|
fun updateItems() {
|
||||||
//limitedVideoFeed.add("")
|
// limitedVideoFeed.add("")
|
||||||
i += 10
|
i += 10
|
||||||
if(i>videoFeed.size)
|
if (i > videoFeed.size)
|
||||||
i=videoFeed.size
|
i = videoFeed.size
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubscriptionViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubscriptionViewHolder {
|
||||||
val layoutInflater = LayoutInflater.from(parent.context)
|
val layoutInflater = LayoutInflater.from(parent.context)
|
||||||
val cell = layoutInflater.inflate(R.layout.trending_row,parent,false)
|
val cell = layoutInflater.inflate(R.layout.trending_row, parent, false)
|
||||||
return SubscriptionViewHolder(cell)
|
return SubscriptionViewHolder(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: SubscriptionViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: SubscriptionViewHolder, position: Int) {
|
||||||
val trending = videoFeed[position]
|
val trending = videoFeed[position]
|
||||||
holder.v.findViewById<TextView>(R.id.textView_title).text = trending.title
|
holder.v.findViewById<TextView>(R.id.textView_title).text = trending.title
|
||||||
holder.v.findViewById<TextView>(R.id.textView_channel).text = trending.uploaderName +" • "+ trending.views.formatShort()+" • "+ DateUtils.getRelativeTimeSpanString(trending.uploaded!!)
|
holder.v.findViewById<TextView>(R.id.textView_channel).text = trending.uploaderName + " • " + trending.views.formatShort() + " • " + DateUtils.getRelativeTimeSpanString(trending.uploaded!!)
|
||||||
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.thumbnail)
|
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.thumbnail)
|
||||||
holder.v.findViewById<TextView>(R.id.thumbnail_duration).text = DateUtils.formatElapsedTime(trending.duration!!)
|
holder.v.findViewById<TextView>(R.id.thumbnail_duration).text = DateUtils.formatElapsedTime(trending.duration!!)
|
||||||
val channelImage = holder.v.findViewById<ImageView>(R.id.channel_image)
|
val channelImage = holder.v.findViewById<ImageView>(R.id.channel_image)
|
||||||
channelImage.setOnClickListener{
|
channelImage.setOnClickListener {
|
||||||
val activity = holder.v.context as MainActivity
|
val activity = holder.v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to trending.uploaderUrl)
|
val bundle = bundleOf("channel_id" to trending.uploaderUrl)
|
||||||
activity.navController.navigate(R.id.channel, bundle)
|
activity.navController.navigate(R.id.channel, bundle)
|
||||||
@ -56,15 +56,14 @@ class SubscriptionAdapter(private val videoFeed: List<StreamItem>): RecyclerView
|
|||||||
mainMotionLayout.transitionToEnd()
|
mainMotionLayout.transitionToEnd()
|
||||||
activity.findViewById<MotionLayout>(R.id.playerMotionLayout).transitionToEnd()
|
activity.findViewById<MotionLayout>(R.id.playerMotionLayout).transitionToEnd()
|
||||||
}
|
}
|
||||||
}catch (e: Exception){
|
} catch (e: Exception) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Picasso.get().load(trending.thumbnail).into(thumbnailImage)
|
Picasso.get().load(trending.thumbnail).into(thumbnailImage)
|
||||||
Picasso.get().load(trending.uploaderAvatar).into(channelImage)
|
Picasso.get().load(trending.uploaderAvatar).into(channelImage)
|
||||||
holder.v.setOnClickListener{
|
holder.v.setOnClickListener {
|
||||||
var bundle = Bundle()
|
var bundle = Bundle()
|
||||||
bundle.putString("videoId",trending.url!!.replace("/watch?v=",""))
|
bundle.putString("videoId", trending.url!!.replace("/watch?v=", ""))
|
||||||
var frag = PlayerFragment()
|
var frag = PlayerFragment()
|
||||||
frag.arguments = bundle
|
frag.arguments = bundle
|
||||||
val activity = holder.v.context as AppCompatActivity
|
val activity = holder.v.context as AppCompatActivity
|
||||||
@ -77,7 +76,7 @@ class SubscriptionAdapter(private val videoFeed: List<StreamItem>): RecyclerView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class SubscriptionViewHolder(val v: View): RecyclerView.ViewHolder(v){
|
class SubscriptionViewHolder(val v: View) : RecyclerView.ViewHolder(v) {
|
||||||
init {
|
init {
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,30 +12,30 @@ import com.github.libretube.R
|
|||||||
import com.github.libretube.obj.Subscription
|
import com.github.libretube.obj.Subscription
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
|
||||||
class SubscriptionChannelAdapter(private val subscriptions: MutableList<Subscription>): RecyclerView.Adapter<SubscriptionChannelViewHolder>() {
|
class SubscriptionChannelAdapter(private val subscriptions: MutableList<Subscription>) : RecyclerView.Adapter<SubscriptionChannelViewHolder>() {
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return subscriptions.size
|
return subscriptions.size
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubscriptionChannelViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubscriptionChannelViewHolder {
|
||||||
val layoutInflater = LayoutInflater.from(parent.context)
|
val layoutInflater = LayoutInflater.from(parent.context)
|
||||||
val cell = layoutInflater.inflate(R.layout.channel_subscription_row,parent,false)
|
val cell = layoutInflater.inflate(R.layout.channel_subscription_row, parent, false)
|
||||||
return SubscriptionChannelViewHolder(cell)
|
return SubscriptionChannelViewHolder(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: SubscriptionChannelViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: SubscriptionChannelViewHolder, position: Int) {
|
||||||
val subscription = subscriptions[position]
|
val subscription = subscriptions[position]
|
||||||
holder.v.findViewById<TextView>(R.id.subscription_channel_name).text=subscription.name
|
holder.v.findViewById<TextView>(R.id.subscription_channel_name).text = subscription.name
|
||||||
val avatar = holder.v.findViewById<ImageView>(R.id.subscription_channel_image)
|
val avatar = holder.v.findViewById<ImageView>(R.id.subscription_channel_image)
|
||||||
Picasso.get().load(subscription.avatar).into(avatar)
|
Picasso.get().load(subscription.avatar).into(avatar)
|
||||||
holder.v.setOnClickListener{
|
holder.v.setOnClickListener {
|
||||||
val activity = holder.v.context as MainActivity
|
val activity = holder.v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to subscription.url)
|
val bundle = bundleOf("channel_id" to subscription.url)
|
||||||
activity.navController.navigate(R.id.channel,bundle)
|
activity.navController.navigate(R.id.channel, bundle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class SubscriptionChannelViewHolder(val v: View): RecyclerView.ViewHolder(v){
|
class SubscriptionChannelViewHolder(val v: View) : RecyclerView.ViewHolder(v) {
|
||||||
init {
|
init {
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,25 +18,25 @@ import com.github.libretube.formatShort
|
|||||||
import com.github.libretube.obj.StreamItem
|
import com.github.libretube.obj.StreamItem
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
|
||||||
class TrendingAdapter(private val videoFeed: List<StreamItem>): RecyclerView.Adapter<CustomViewHolder>() {
|
class TrendingAdapter(private val videoFeed: List<StreamItem>) : RecyclerView.Adapter<CustomViewHolder>() {
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return videoFeed.size
|
return videoFeed.size
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
|
||||||
val layoutInflater = LayoutInflater.from(parent.context)
|
val layoutInflater = LayoutInflater.from(parent.context)
|
||||||
val cell = layoutInflater.inflate(R.layout.trending_row,parent,false)
|
val cell = layoutInflater.inflate(R.layout.trending_row, parent, false)
|
||||||
return CustomViewHolder(cell)
|
return CustomViewHolder(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
|
||||||
val trending = videoFeed[position]
|
val trending = videoFeed[position]
|
||||||
holder.v.findViewById<TextView>(R.id.textView_title).text = trending.title
|
holder.v.findViewById<TextView>(R.id.textView_title).text = trending.title
|
||||||
holder.v.findViewById<TextView>(R.id.textView_channel).text = trending.uploaderName +" • "+ trending.views.formatShort()+" • "+DateUtils.getRelativeTimeSpanString(trending.uploaded!!)
|
holder.v.findViewById<TextView>(R.id.textView_channel).text = trending.uploaderName + " • " + trending.views.formatShort() + " • " + DateUtils.getRelativeTimeSpanString(trending.uploaded!!)
|
||||||
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.thumbnail)
|
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.thumbnail)
|
||||||
holder.v.findViewById<TextView>(R.id.thumbnail_duration).text = DateUtils.formatElapsedTime(trending.duration!!)
|
holder.v.findViewById<TextView>(R.id.thumbnail_duration).text = DateUtils.formatElapsedTime(trending.duration!!)
|
||||||
val channelImage = holder.v.findViewById<ImageView>(R.id.channel_image)
|
val channelImage = holder.v.findViewById<ImageView>(R.id.channel_image)
|
||||||
channelImage.setOnClickListener{
|
channelImage.setOnClickListener {
|
||||||
val activity = holder.v.context as MainActivity
|
val activity = holder.v.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to trending.uploaderUrl)
|
val bundle = bundleOf("channel_id" to trending.uploaderUrl)
|
||||||
activity.navController.navigate(R.id.channel, bundle)
|
activity.navController.navigate(R.id.channel, bundle)
|
||||||
@ -46,23 +46,21 @@ class TrendingAdapter(private val videoFeed: List<StreamItem>): RecyclerView.Ada
|
|||||||
mainMotionLayout.transitionToEnd()
|
mainMotionLayout.transitionToEnd()
|
||||||
activity.findViewById<MotionLayout>(R.id.playerMotionLayout).transitionToEnd()
|
activity.findViewById<MotionLayout>(R.id.playerMotionLayout).transitionToEnd()
|
||||||
}
|
}
|
||||||
}catch (e: Exception){
|
} catch (e: Exception) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (trending.thumbnail!!.isEmpty()) {
|
if (trending.thumbnail!!.isEmpty()) {
|
||||||
} else{
|
} else {
|
||||||
Picasso.get().load(trending.thumbnail).into(thumbnailImage)
|
Picasso.get().load(trending.thumbnail).into(thumbnailImage)
|
||||||
}
|
}
|
||||||
if (trending.uploaderAvatar!!.isEmpty()) {
|
if (trending.uploaderAvatar!!.isEmpty()) {
|
||||||
} else{
|
} else {
|
||||||
Picasso.get().load(trending.uploaderAvatar).into(channelImage)
|
Picasso.get().load(trending.uploaderAvatar).into(channelImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
holder.v.setOnClickListener {
|
||||||
holder.v.setOnClickListener{
|
|
||||||
var bundle = Bundle()
|
var bundle = Bundle()
|
||||||
bundle.putString("videoId",trending.url!!.replace("/watch?v=",""))
|
bundle.putString("videoId", trending.url!!.replace("/watch?v=", ""))
|
||||||
var frag = PlayerFragment()
|
var frag = PlayerFragment()
|
||||||
frag.arguments = bundle
|
frag.arguments = bundle
|
||||||
val activity = holder.v.context as AppCompatActivity
|
val activity = holder.v.context as AppCompatActivity
|
||||||
@ -75,7 +73,7 @@ class TrendingAdapter(private val videoFeed: List<StreamItem>): RecyclerView.Ada
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class CustomViewHolder(val v: View): RecyclerView.ViewHolder(v){
|
class CustomViewHolder(val v: View) : RecyclerView.ViewHolder(v) {
|
||||||
init {
|
init {
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,6 +2,4 @@ package com.github.libretube
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
|
||||||
class myApp : Application() {
|
class myApp : Application()
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -7,6 +7,6 @@ data class ChapterSegment(
|
|||||||
var title: String?,
|
var title: String?,
|
||||||
var image: String?,
|
var image: String?,
|
||||||
var start: Int?
|
var start: Int?
|
||||||
){
|
) {
|
||||||
constructor(): this("","",-1)
|
constructor() : this("", "", -1)
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ data class Comment(
|
|||||||
val pinned: Boolean?,
|
val pinned: Boolean?,
|
||||||
val thumbnail: String?,
|
val thumbnail: String?,
|
||||||
val verified: Boolean?
|
val verified: Boolean?
|
||||||
){
|
) {
|
||||||
constructor(): this("", "","","","",null,0,null,"",null)
|
constructor() : this("", "", "", "", "", null, 0, null, "", null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
|||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
data class CommentsPage(
|
data class CommentsPage(
|
||||||
val comments: MutableList<Comment> = arrayListOf(),
|
val comments: MutableList<Comment> = arrayListOf(),
|
||||||
val disabled: Boolean? = null,
|
val disabled: Boolean? = null,
|
||||||
val nextpage: String? = "",
|
val nextpage: String? = "",
|
||||||
){
|
) {
|
||||||
constructor(): this(arrayListOf(),null,"")
|
constructor() : this(arrayListOf(), null, "")
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,6 @@ data class PipedStream(
|
|||||||
var width: Int?,
|
var width: Int?,
|
||||||
var height: Int?,
|
var height: Int?,
|
||||||
var fps: Int?
|
var fps: Int?
|
||||||
){
|
) {
|
||||||
constructor(): this("","","","","",null,-1,-1,-1,-1,-1,-1,-1,-1)
|
constructor() : this("", "", "", "", "", null, -1, -1, -1, -1, -1, -1, -1, -1)
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ data class SearchItem(
|
|||||||
var uploaderName: String?,
|
var uploaderName: String?,
|
||||||
var uploaded: Long?,
|
var uploaded: Long?,
|
||||||
var shortDescription: String?,
|
var shortDescription: String?,
|
||||||
//Video only attributes
|
// Video only attributes
|
||||||
var title: String?,
|
var title: String?,
|
||||||
var uploaderUrl: String?,
|
var uploaderUrl: String?,
|
||||||
var uploaderAvatar: String?,
|
var uploaderAvatar: String?,
|
||||||
@ -17,12 +17,12 @@ data class SearchItem(
|
|||||||
var duration: Long?,
|
var duration: Long?,
|
||||||
var views: Long?,
|
var views: Long?,
|
||||||
var uploaderVerified: Boolean?,
|
var uploaderVerified: Boolean?,
|
||||||
//Channel and Playlist attributes
|
// Channel and Playlist attributes
|
||||||
var name: String? = null,
|
var name: String? = null,
|
||||||
var description: String? = null,
|
var description: String? = null,
|
||||||
var subscribers: Long? = -1,
|
var subscribers: Long? = -1,
|
||||||
var videos: Long? = -1,
|
var videos: Long? = -1,
|
||||||
var verified: Boolean? = null
|
var verified: Boolean? = null
|
||||||
){
|
) {
|
||||||
constructor() : this("","","",0,"","","","","",0,0,null)
|
constructor() : this("", "", "", 0, "", "", "", "", "", 0, 0, null)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
|||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
data class SearchResult(
|
data class SearchResult(
|
||||||
val items: MutableList<SearchItem>? = arrayListOf(),
|
val items: MutableList<SearchItem>? = arrayListOf(),
|
||||||
val nextpage: String? ="",
|
val nextpage: String? = "",
|
||||||
val suggestion: String?="",
|
val suggestion: String? = "",
|
||||||
val corrected: Boolean? = null
|
val corrected: Boolean? = null
|
||||||
)
|
)
|
||||||
|
@ -7,6 +7,6 @@ data class Segment(
|
|||||||
val actionType: String?,
|
val actionType: String?,
|
||||||
val category: String?,
|
val category: String?,
|
||||||
val segment: List<Float>?
|
val segment: List<Float>?
|
||||||
){
|
) {
|
||||||
constructor(): this("", "", arrayListOf())
|
constructor() : this("", "", arrayListOf())
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
|||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
data class Segments(
|
data class Segments(
|
||||||
val segments: MutableList<Segment> = arrayListOf()
|
val segments: MutableList<Segment> = arrayListOf()
|
||||||
){
|
) {
|
||||||
constructor(): this(arrayListOf())
|
constructor() : this(arrayListOf())
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,6 @@ data class StreamItem(
|
|||||||
var uploaderVerified: Boolean?,
|
var uploaderVerified: Boolean?,
|
||||||
var uploaded: Long?,
|
var uploaded: Long?,
|
||||||
var shortDescription: String?
|
var shortDescription: String?
|
||||||
){
|
) {
|
||||||
constructor() : this("","","","","","","",0,0,null,0,"")
|
constructor() : this("", "", "", "", "", "", "", 0, 0, null, 0, "")
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,9 @@ data class Streams(
|
|||||||
val livestream: Boolean?,
|
val livestream: Boolean?,
|
||||||
val proxyUrl: String?,
|
val proxyUrl: String?,
|
||||||
val chapters: List<ChapterSegment>?
|
val chapters: List<ChapterSegment>?
|
||||||
){
|
) {
|
||||||
constructor(): this("","","","","","","","","","",null,-1,-1,-1,-1, emptyList(), emptyList(),
|
constructor() : this(
|
||||||
emptyList(), emptyList(), null,"", emptyList())
|
"", "", "", "", "", "", "", "", "", "", null, -1, -1, -1, -1, emptyList(), emptyList(),
|
||||||
|
emptyList(), emptyList(), null, "", emptyList()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,6 @@ data class Subtitle(
|
|||||||
val name: String?,
|
val name: String?,
|
||||||
val code: String?,
|
val code: String?,
|
||||||
val autoGenerated: Boolean?
|
val autoGenerated: Boolean?
|
||||||
){
|
) {
|
||||||
constructor(): this("","","","",null)
|
constructor() : this("", "", "", "", null)
|
||||||
}
|
}
|
||||||
|
10
app/src/main/res/drawable/ic_color.xml
Normal file
10
app/src/main/res/drawable/ic_color.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="M12,3c-4.97,0 -9,4.03 -9,9s4.03,9 9,9c0.83,0 1.5,-0.67 1.5,-1.5 0,-0.39 -0.15,-0.74 -0.39,-1.01 -0.23,-0.26 -0.38,-0.61 -0.38,-0.99 0,-0.83 0.67,-1.5 1.5,-1.5L16,16c2.76,0 5,-2.24 5,-5 0,-4.42 -4.03,-8 -9,-8zM6.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,9 6.5,9 8,9.67 8,10.5 7.33,12 6.5,12zM9.5,8C8.67,8 8,7.33 8,6.5S8.67,5 9.5,5s1.5,0.67 1.5,1.5S10.33,8 9.5,8zM14.5,8c-0.83,0 -1.5,-0.67 -1.5,-1.5S13.67,5 14.5,5s1.5,0.67 1.5,1.5S15.33,8 14.5,8zM17.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S16.67,9 17.5,9s1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5z"/>
|
||||||
|
</vector>
|
@ -50,7 +50,7 @@
|
|||||||
android:layout_marginStart="24dp"
|
android:layout_marginStart="24dp"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:text="@string/subscribe"
|
android:text="@string/subscribe"
|
||||||
android:textColor="@color/colorPrimary"
|
android:textColor="?attr/colorPrimary"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintStart_toEndOf="@+id/search_channel_image" />
|
app:layout_constraintStart_toEndOf="@+id/search_channel_image" />
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_marginEnd="10dp"
|
||||||
android:layout_marginBottom="15dp"
|
android:layout_marginBottom="15dp"
|
||||||
android:text="" />
|
android:text="" />
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:backgroundTint="?android:attr/colorBackground"
|
android:backgroundTint="?attr/colorOnPrimary"
|
||||||
android:drawableLeft="@drawable/ic_bell"
|
android:drawableLeft="@drawable/ic_bell"
|
||||||
android:drawableTint="?android:attr/textColorPrimary"
|
android:drawableTint="?android:attr/textColorPrimary"
|
||||||
android:text="@string/subscribe"
|
android:text="@string/subscribe"
|
||||||
|
@ -1,36 +1,104 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<style name="Theme.LibreTube" parent="Theme.Material3.Dark.NoActionBar">
|
<style name="Theme.MY" parent="Theme.Material3.Dark.NoActionBar"></style>
|
||||||
<item name="colorPrimary">@color/md_theme_dark_primary</item>
|
|
||||||
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
|
<style name="Theme.Red" parent="Theme.Material3.Dark.NoActionBar">
|
||||||
<item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>
|
|
||||||
<item name="colorOnPrimaryContainer">@color/md_theme_dark_onPrimaryContainer</item>
|
<item name="colorPrimary">@color/red_dark_accentLight</item> // container
|
||||||
<item name="colorSecondary">@color/md_theme_dark_secondary</item>
|
<item name="colorOnPrimary">@color/red_dark_accentDark</item> // title
|
||||||
<item name="colorOnSecondary">@color/md_theme_dark_onSecondary</item>
|
<item name="colorPrimaryContainer">@color/red_dark_accentLight</item> //
|
||||||
<item name="colorSecondaryContainer">@color/md_theme_dark_secondaryContainer</item>
|
<item name="colorOnPrimaryContainer">@color/red_dark_accentLight</item> //
|
||||||
<item name="colorOnSecondaryContainer">@color/md_theme_dark_onSecondaryContainer</item>
|
<item name="colorSecondary">@color/red_dark_accentLight</item> // Settings Categories
|
||||||
<item name="colorTertiary">@color/md_theme_dark_tertiary</item>
|
<item name="colorOnSecondary">@color/red_dark_accentDark</item> //
|
||||||
<item name="colorOnTertiary">@color/md_theme_dark_onTertiary</item>
|
<item name="colorSecondaryContainer">@color/red_dark_accentDark</item> // navbar surround
|
||||||
<item name="colorTertiaryContainer">@color/md_theme_dark_tertiaryContainer</item>
|
<!-- <item name="colorOnSecondaryContainer">@color/red_dark_background</item> --> // navbar icon fill
|
||||||
<item name="colorOnTertiaryContainer">@color/md_theme_dark_onTertiaryContainer</item>
|
<item name="android:colorBackground">@color/red_dark_background</item> // background
|
||||||
<item name="colorError">@color/md_theme_dark_error</item>
|
<item name="colorOnBackground">@color/red_dark_background</item>
|
||||||
<item name="colorErrorContainer">@color/md_theme_dark_errorContainer</item>
|
|
||||||
<item name="colorOnError">@color/md_theme_dark_onError</item>
|
|
||||||
<item name="colorOnErrorContainer">@color/md_theme_dark_onErrorContainer</item>
|
|
||||||
<item name="android:colorBackground">@color/md_theme_dark_background</item>
|
|
||||||
<item name="colorOnBackground">@color/md_theme_dark_onBackground</item>
|
|
||||||
<item name="colorSurface">@color/md_theme_dark_surface</item>
|
|
||||||
<item name="colorOnSurface">@color/md_theme_dark_onSurface</item>
|
|
||||||
<item name="colorSurfaceVariant">@color/md_theme_dark_surfaceVariant</item>
|
|
||||||
<item name="colorOnSurfaceVariant">@color/md_theme_dark_onSurfaceVariant</item>
|
|
||||||
<item name="colorOutline">@color/md_theme_dark_outline</item>
|
|
||||||
<item name="colorOnSurfaceInverse">@color/md_theme_dark_inverseOnSurface</item>
|
|
||||||
<item name="colorSurfaceInverse">@color/md_theme_dark_inverseSurface</item>
|
|
||||||
<item name="colorPrimaryInverse">@color/md_theme_dark_primaryInverse</item>
|
|
||||||
|
|
||||||
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
|
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
|
||||||
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
|
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
|
||||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Blue" parent="Theme.Material3.Dark.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/blue_dark_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/blue_dark_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/blue_dark_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/blue_dark_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/blue_dark_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/blue_dark_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/blue_dark_accentDark</item> // navbar surround
|
||||||
|
<!-- <item name="colorOnSecondaryContainer">@color/blue_dark_background</item> --> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/blue_dark_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/blue_dark_background</item>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Yellow" parent="Theme.Material3.Dark.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/yellow_dark_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/yellow_dark_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/yellow_dark_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/yellow_dark_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/yellow_dark_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/yellow_dark_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/yellow_dark_accentDark</item> // navbar surround
|
||||||
|
<!-- <item name="colorOnSecondaryContainer">@color/yellow_dark_background</item> --> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/yellow_dark_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/yellow_dark_background</item>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Green" parent="Theme.Material3.Dark.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/green_dark_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/green_dark_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/green_dark_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/green_dark_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/green_dark_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/green_dark_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/green_dark_accentDark</item> // navbar surround
|
||||||
|
<!-- <item name="colorOnSecondaryContainer">@color/green_dark_background</item> --> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/green_dark_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/green_dark_background</item>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Purple" parent="Theme.Material3.Dark.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/purple_dark_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/purple_dark_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/purple_dark_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/purple_dark_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/purple_dark_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/purple_dark_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/purple_dark_accentDark</item> // navbar surround
|
||||||
|
<!-- <item name="colorOnSecondaryContainer">@color/purple_dark_background</item> --> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/purple_dark_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/purple_dark_background</item>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.OLED" parent="Theme.Material3.Dark.NoActionBar">
|
||||||
|
<item name="android:colorBackground">@color/black</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -1,37 +1,100 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<style name="Theme.LibreTube" parent="Theme.Material3.Light.NoActionBar">
|
<style name="Theme.MY" parent="Theme.Material3.Light.NoActionBar"></style>
|
||||||
<item name="colorPrimary">@color/md_theme_light_primary</item>
|
|
||||||
<item name="colorOnPrimary">@color/md_theme_light_onPrimary</item>
|
<style name="Theme.Red" parent="Theme.Material3.Light.NoActionBar">
|
||||||
<item name="colorPrimaryContainer">@color/md_theme_light_primaryContainer</item>
|
|
||||||
<item name="colorOnPrimaryContainer">@color/md_theme_light_onPrimaryContainer</item>
|
<item name="colorPrimary">@color/red_light_accentLight</item> // container
|
||||||
<item name="colorSecondary">@color/md_theme_light_secondary</item>
|
<item name="colorOnPrimary">@color/red_light_accentDark</item> // title
|
||||||
<item name="colorOnSecondary">@color/md_theme_light_onSecondary</item>
|
<item name="colorPrimaryContainer">@color/red_light_accentLight</item> //
|
||||||
<item name="colorSecondaryContainer">@color/md_theme_light_secondaryContainer</item>
|
<item name="colorOnPrimaryContainer">@color/red_light_accentLight</item> //
|
||||||
<item name="colorOnSecondaryContainer">@color/md_theme_light_onSecondaryContainer</item>
|
<item name="colorSecondary">@color/red_light_accentLight</item> // Settings Categories
|
||||||
<item name="colorTertiary">@color/md_theme_light_tertiary</item>
|
<item name="colorOnSecondary">@color/red_light_accentDark</item> //
|
||||||
<item name="colorOnTertiary">@color/md_theme_light_onTertiary</item>
|
<item name="colorSecondaryContainer">@color/red_light_accentDark</item> // navbar surround
|
||||||
<item name="colorTertiaryContainer">@color/md_theme_light_tertiaryContainer</item>
|
<item name="colorOnSecondaryContainer">@color/red_light_background</item> // navbar icon fill
|
||||||
<item name="colorOnTertiaryContainer">@color/md_theme_light_onTertiaryContainer</item>
|
<item name="android:colorBackground">@color/red_light_background</item> // background
|
||||||
<item name="colorError">@color/md_theme_light_error</item>
|
<item name="colorOnBackground">@color/red_light_background</item>
|
||||||
<item name="colorErrorContainer">@color/md_theme_light_errorContainer</item>
|
|
||||||
<item name="colorOnError">@color/md_theme_light_onError</item>
|
|
||||||
<item name="colorOnErrorContainer">@color/md_theme_light_onErrorContainer</item>
|
|
||||||
<item name="android:colorBackground">@color/md_theme_light_background</item>
|
|
||||||
<item name="colorOnBackground">@color/md_theme_light_onBackground</item>
|
|
||||||
<item name="colorSurface">@color/md_theme_light_surface</item>
|
|
||||||
<item name="colorOnSurface">@color/md_theme_light_onSurface</item>
|
|
||||||
<item name="colorSurfaceVariant">@color/md_theme_light_surfaceVariant</item>
|
|
||||||
<item name="colorOnSurfaceVariant">@color/md_theme_light_onSurfaceVariant</item>
|
|
||||||
<item name="colorOutline">@color/md_theme_light_outline</item>
|
|
||||||
<item name="colorOnSurfaceInverse">@color/md_theme_light_inverseOnSurface</item>
|
|
||||||
<item name="colorSurfaceInverse">@color/md_theme_light_inverseSurface</item>
|
|
||||||
<item name="colorPrimaryInverse">@color/md_theme_light_primaryInverse</item>
|
|
||||||
|
|
||||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
<item name="android:windowLightStatusBar">true</item>
|
<item name="android:windowLightStatusBar">true</item>
|
||||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Blue" parent="Theme.Material3.Light.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/blue_light_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/blue_light_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/blue_light_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/blue_light_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/blue_light_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/blue_light_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/blue_light_accentDark</item> // navbar surround
|
||||||
|
<item name="colorOnSecondaryContainer">@color/blue_light_background</item> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/blue_light_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/blue_light_background</item>
|
||||||
|
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:windowLightStatusBar">true</item>
|
||||||
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Yellow" parent="Theme.Material3.Light.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/yellow_light_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/yellow_light_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/yellow_light_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/yellow_light_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/yellow_light_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/yellow_light_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/yellow_light_accentDark</item> // navbar surround
|
||||||
|
<item name="colorOnSecondaryContainer">@color/yellow_light_background</item> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/yellow_light_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/yellow_light_background</item>
|
||||||
|
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:windowLightStatusBar">true</item>
|
||||||
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Green" parent="Theme.Material3.Light.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/green_light_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/green_light_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/green_light_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/green_light_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/green_light_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/green_light_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/green_light_accentDark</item> // navbar surround
|
||||||
|
<item name="colorOnSecondaryContainer">@color/green_light_background</item> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/green_light_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/green_light_background</item>
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:windowLightStatusBar">true</item>
|
||||||
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Purple" parent="Theme.Material3.Light.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/purple_light_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/purple_light_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/purple_light_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/purple_light_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/purple_light_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/purple_light_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/purple_light_accentDark</item> // navbar surround
|
||||||
|
<item name="colorOnSecondaryContainer">@color/purple_light_background</item> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/purple_light_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/purple_light_background</item>
|
||||||
|
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:windowLightStatusBar">true</item>
|
||||||
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -463,12 +463,32 @@
|
|||||||
<item>@string/systemDefault</item>
|
<item>@string/systemDefault</item>
|
||||||
<item>@string/lightTheme</item>
|
<item>@string/lightTheme</item>
|
||||||
<item>@string/darkTheme</item>
|
<item>@string/darkTheme</item>
|
||||||
|
<item>@string/oledTheme</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="themesValue">
|
<string-array name="themesValue">
|
||||||
<item>A</item>
|
<item>A</item>
|
||||||
<item>L</item>
|
<item>L</item>
|
||||||
<item>D</item>
|
<item>D</item>
|
||||||
|
<item>O</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="accents">
|
||||||
|
<item>@string/material_you</item>
|
||||||
|
<item>@string/color_red</item>
|
||||||
|
<item>@string/color_blue</item>
|
||||||
|
<item>@string/color_yellow</item>
|
||||||
|
<item>@string/color_green</item>
|
||||||
|
<item>@string/color_purple</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="accentsValue">
|
||||||
|
<item>my</item>
|
||||||
|
<item>red</item>
|
||||||
|
<item>blue</item>
|
||||||
|
<item>yellow</item>
|
||||||
|
<item>green</item>
|
||||||
|
<item>purple</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="tabs">
|
<string-array name="tabs">
|
||||||
|
@ -6,59 +6,44 @@
|
|||||||
<color name="duration_background_color">#AA000000</color>
|
<color name="duration_background_color">#AA000000</color>
|
||||||
<color name="duration_text_color">#EEFFFFFF</color>
|
<color name="duration_text_color">#EEFFFFFF</color>
|
||||||
|
|
||||||
<color name="colorPrimary">#B81B3B</color>
|
<color name="red_light_accentLight">#F1395E</color>
|
||||||
<color name="md_theme_light_primary">#B81B3B</color>
|
<color name="red_light_accentDark">#B81B3B</color>
|
||||||
<color name="md_theme_light_onPrimary">#FFFFFF</color>
|
<color name="red_light_background">#FFC3C3</color>
|
||||||
<color name="md_theme_light_primaryContainer">#FFDADC</color>
|
|
||||||
<color name="md_theme_light_onPrimaryContainer">#40000B</color>
|
<color name="red_dark_accentLight">#F1395E</color>
|
||||||
<color name="md_theme_light_secondary">#9C4145</color>
|
<color name="red_dark_accentDark">#8F001D</color>
|
||||||
<color name="md_theme_light_onSecondary">#FFFFFF</color>
|
<color name="red_dark_background">#1E0D0D</color>
|
||||||
<color name="md_theme_light_secondaryContainer">#FFD9DA</color>
|
|
||||||
<color name="md_theme_light_onSecondaryContainer">#400008</color>
|
<color name="blue_light_accentLight">#2196F3</color>
|
||||||
<color name="md_theme_light_tertiary">#98470F</color>
|
<color name="blue_light_accentDark">#0E4B67</color>
|
||||||
<color name="md_theme_light_onTertiary">#FFFFFF</color>
|
<color name="blue_light_background">#DDF0FF</color>
|
||||||
<color name="md_theme_light_tertiaryContainer">#FFDBC8</color>
|
|
||||||
<color name="md_theme_light_onTertiaryContainer">#341100</color>
|
<color name="blue_dark_accentLight">#2196F3</color>
|
||||||
<color name="md_theme_light_error">#BA1B1B</color>
|
<color name="blue_dark_accentDark">#0E4B67</color>
|
||||||
<color name="md_theme_light_errorContainer">#FFDAD4</color>
|
<color name="blue_dark_background">#080C20</color>
|
||||||
<color name="md_theme_light_onError">#FFFFFF</color>
|
|
||||||
<color name="md_theme_light_onErrorContainer">#410001</color>
|
<color name="yellow_light_accentLight">#F3E570</color>
|
||||||
<color name="md_theme_light_background">#FCFCFC</color>
|
<color name="yellow_light_accentDark">#EDE06A</color>
|
||||||
<color name="md_theme_light_onBackground">#201A1A</color>
|
<color name="yellow_light_background">#FFF9C8</color>
|
||||||
<color name="md_theme_light_surface">#FCFCFC</color>
|
|
||||||
<color name="md_theme_light_onSurface">#201A1A</color>
|
<color name="yellow_dark_accentLight">#E2EF55</color>
|
||||||
<color name="md_theme_light_surfaceVariant">#F4DDDD</color>
|
<color name="yellow_dark_accentDark">#999520</color>
|
||||||
<color name="md_theme_light_onSurfaceVariant">#524343</color>
|
<color name="yellow_dark_background">#1C1A05</color>
|
||||||
<color name="md_theme_light_outline">#847373</color>
|
|
||||||
<color name="md_theme_light_inverseOnSurface">#FBEDED</color>
|
<color name="green_light_accentLight">#8BC34A</color>
|
||||||
<color name="md_theme_light_inverseSurface">#362F2F</color>
|
<color name="green_light_accentDark">#5BD861</color>
|
||||||
<color name="md_theme_light_primaryInverse">#FFB3B8</color>
|
<color name="green_light_background">#E8FFCE</color>
|
||||||
<color name="md_theme_dark_primary">#FFB3B8</color>
|
|
||||||
<color name="md_theme_dark_onPrimary">#680018</color>
|
<color name="green_dark_accentLight">#8BC34A</color>
|
||||||
<color name="md_theme_dark_primaryContainer">#920026</color>
|
<color name="green_dark_accentDark">#155C1B</color>
|
||||||
<color name="md_theme_dark_onPrimaryContainer">#FFDADC</color>
|
<color name="green_dark_background">#131C09</color>
|
||||||
<color name="md_theme_dark_secondary">#FFB2B3</color>
|
|
||||||
<color name="md_theme_dark_onSecondary">#60131B</color>
|
<color name="purple_light_accentLight">#db1fb6</color>
|
||||||
<color name="md_theme_dark_secondaryContainer">#7D2A2F</color>
|
<color name="purple_light_accentDark">#d42cb2</color>
|
||||||
<color name="md_theme_dark_onSecondaryContainer">#FFD9DA</color>
|
<color name="purple_light_background">#FFDAE6</color>
|
||||||
<color name="md_theme_dark_tertiary">#FFB68C</color>
|
|
||||||
<color name="md_theme_dark_onTertiary">#552100</color>
|
<color name="purple_dark_accentLight">#9621AA</color>
|
||||||
<color name="md_theme_dark_tertiaryContainer">#783200</color>
|
<color name="purple_dark_accentDark">#371377</color>
|
||||||
<color name="md_theme_dark_onTertiaryContainer">#FFDBC8</color>
|
<color name="purple_dark_background">#120B20</color>
|
||||||
<color name="md_theme_dark_error">#FFB4A9</color>
|
|
||||||
<color name="md_theme_dark_errorContainer">#930006</color>
|
|
||||||
<color name="md_theme_dark_onError">#680003</color>
|
|
||||||
<color name="md_theme_dark_onErrorContainer">#FFDAD4</color>
|
|
||||||
<color name="md_theme_dark_background">#201A1A</color>
|
|
||||||
<color name="md_theme_dark_onBackground">#ECDFDF</color>
|
|
||||||
<color name="md_theme_dark_surface">#201A1A</color>
|
|
||||||
<color name="md_theme_dark_onSurface">#ECDFDF</color>
|
|
||||||
<color name="md_theme_dark_surfaceVariant">#524343</color>
|
|
||||||
<color name="md_theme_dark_onSurfaceVariant">#D7C2C2</color>
|
|
||||||
<color name="md_theme_dark_outline">#9F8C8C</color>
|
|
||||||
<color name="md_theme_dark_inverseOnSurface">#201A1A</color>
|
|
||||||
<color name="md_theme_dark_inverseSurface">#ECDFDF</color>
|
|
||||||
<color name="md_theme_dark_primaryInverse">#B81B3B</color>
|
|
||||||
<color name="seed">#BD1F3E</color>
|
|
||||||
<color name="error">#BA1B1B</color>
|
|
||||||
</resources>
|
</resources>
|
@ -101,4 +101,12 @@
|
|||||||
<string name="category_outro">Endcards/Credits</string>
|
<string name="category_outro">Endcards/Credits</string>
|
||||||
<string name="category_outro_description">Credits or when the YouTube endcards appear. Not for conclusions with information.</string>
|
<string name="category_outro_description">Credits or when the YouTube endcards appear. Not for conclusions with information.</string>
|
||||||
<string name="license">License</string>
|
<string name="license">License</string>
|
||||||
|
<string name="color_accent">Color Accent</string>
|
||||||
|
<string name="color_red">Red</string>
|
||||||
|
<string name="color_blue">Blue</string>
|
||||||
|
<string name="color_yellow">Yellow</string>
|
||||||
|
<string name="color_green">Green</string>
|
||||||
|
<string name="color_purple">Purple</string>
|
||||||
|
<string name="oledTheme">OLED Theme</string>
|
||||||
|
<string name="material_you">Material You</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,33 +1,89 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<style name="Theme.LibreTube" parent="Theme.Material3.Light.NoActionBar">
|
<style name="Theme.MY" parent="Theme.Material3.Light.NoActionBar"></style>
|
||||||
<item name="colorPrimary">@color/md_theme_light_primary</item>
|
|
||||||
<item name="colorOnPrimary">@color/md_theme_light_onPrimary</item>
|
<style name="Theme.Red" parent="Theme.Material3.Light.NoActionBar">
|
||||||
<item name="colorPrimaryContainer">@color/md_theme_light_primaryContainer</item>
|
|
||||||
<item name="colorOnPrimaryContainer">@color/md_theme_light_onPrimaryContainer</item>
|
<item name="colorPrimary">@color/red_light_accentLight</item> // container
|
||||||
<item name="colorSecondary">@color/md_theme_light_secondary</item>
|
<item name="colorOnPrimary">@color/red_light_accentDark</item> // title
|
||||||
<item name="colorOnSecondary">@color/md_theme_light_onSecondary</item>
|
<item name="colorPrimaryContainer">@color/red_light_accentLight</item> //
|
||||||
<item name="colorSecondaryContainer">@color/md_theme_light_secondaryContainer</item>
|
<item name="colorOnPrimaryContainer">@color/red_light_accentLight</item> //
|
||||||
<item name="colorOnSecondaryContainer">@color/md_theme_light_onSecondaryContainer</item>
|
<item name="colorSecondary">@color/red_light_accentLight</item> // Settings Categories
|
||||||
<item name="colorTertiary">@color/md_theme_light_tertiary</item>
|
<item name="colorOnSecondary">@color/red_light_accentDark</item> //
|
||||||
<item name="colorOnTertiary">@color/md_theme_light_onTertiary</item>
|
<item name="colorSecondaryContainer">@color/red_light_accentDark</item> // navbar surround
|
||||||
<item name="colorTertiaryContainer">@color/md_theme_light_tertiaryContainer</item>
|
<item name="colorOnSecondaryContainer">@color/red_light_background</item> // navbar icon fill
|
||||||
<item name="colorOnTertiaryContainer">@color/md_theme_light_onTertiaryContainer</item>
|
<item name="android:colorBackground">@color/red_light_background</item> // background
|
||||||
<item name="colorError">@color/md_theme_light_error</item>
|
<item name="colorOnBackground">@color/red_light_background</item>
|
||||||
<item name="colorErrorContainer">@color/md_theme_light_errorContainer</item>
|
|
||||||
<item name="colorOnError">@color/md_theme_light_onError</item>
|
|
||||||
<item name="colorOnErrorContainer">@color/md_theme_light_onErrorContainer</item>
|
|
||||||
<item name="android:colorBackground">@color/md_theme_light_background</item>
|
|
||||||
<item name="colorOnBackground">@color/md_theme_light_onBackground</item>
|
|
||||||
<item name="colorSurface">@color/md_theme_light_surface</item>
|
|
||||||
<item name="colorOnSurface">@color/md_theme_light_onSurface</item>
|
|
||||||
<item name="colorSurfaceVariant">@color/md_theme_light_surfaceVariant</item>
|
|
||||||
<item name="colorOnSurfaceVariant">@color/md_theme_light_onSurfaceVariant</item>
|
|
||||||
<item name="colorOutline">@color/md_theme_light_outline</item>
|
|
||||||
<item name="colorOnSurfaceInverse">@color/md_theme_light_inverseOnSurface</item>
|
|
||||||
<item name="colorSurfaceInverse">@color/md_theme_light_inverseSurface</item>
|
|
||||||
<item name="colorPrimaryInverse">@color/md_theme_light_primaryInverse</item>
|
|
||||||
|
|
||||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Blue" parent="Theme.Material3.Light.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/blue_light_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/blue_light_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/blue_light_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/blue_light_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/blue_light_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/blue_light_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/blue_light_accentDark</item> // navbar surround
|
||||||
|
<item name="colorOnSecondaryContainer">@color/blue_light_background</item> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/blue_light_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/blue_light_background</item>
|
||||||
|
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Yellow" parent="Theme.Material3.Light.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/yellow_light_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/yellow_light_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/yellow_light_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/yellow_light_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/yellow_light_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/yellow_light_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/yellow_light_accentDark</item> // navbar surround
|
||||||
|
<item name="colorOnSecondaryContainer">@color/yellow_light_background</item> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/yellow_light_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/yellow_light_background</item>
|
||||||
|
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Green" parent="Theme.Material3.Light.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/green_light_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/green_light_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/green_light_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/green_light_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/green_light_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/green_light_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/green_light_accentDark</item> // navbar surround
|
||||||
|
<item name="colorOnSecondaryContainer">@color/green_light_background</item> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/green_light_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/green_light_background</item>
|
||||||
|
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.Purple" parent="Theme.Material3.Light.NoActionBar">
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/purple_light_accentLight</item> // container
|
||||||
|
<item name="colorOnPrimary">@color/purple_light_accentDark</item> // title
|
||||||
|
<item name="colorPrimaryContainer">@color/purple_light_accentLight</item> //
|
||||||
|
<item name="colorOnPrimaryContainer">@color/purple_light_accentLight</item> //
|
||||||
|
<item name="colorSecondary">@color/purple_light_accentLight</item> // Settings Categories
|
||||||
|
<item name="colorOnSecondary">@color/purple_light_accentDark</item> //
|
||||||
|
<item name="colorSecondaryContainer">@color/purple_light_accentDark</item> // navbar surround
|
||||||
|
<item name="colorOnSecondaryContainer">@color/purple_light_background</item> // navbar icon fill
|
||||||
|
<item name="android:colorBackground">@color/purple_light_background</item> // background
|
||||||
|
<item name="colorOnBackground">@color/purple_light_background</item>
|
||||||
|
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -71,6 +71,15 @@
|
|||||||
android:icon="@drawable/ic_theme"
|
android:icon="@drawable/ic_theme"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
app:title="@string/color_accent"
|
||||||
|
app:key="accent_color"
|
||||||
|
app:entries="@array/accents"
|
||||||
|
app:entryValues="@array/accentsValue"
|
||||||
|
app:defaultValue="red"
|
||||||
|
android:icon="@drawable/ic_color"
|
||||||
|
/>
|
||||||
|
|
||||||
<androidx.preference.Preference
|
<androidx.preference.Preference
|
||||||
app:title="@string/sponsorblock"
|
app:title="@string/sponsorblock"
|
||||||
app:key="sponsorblock"
|
app:key="sponsorblock"
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package com.github.libretube
|
package com.github.libretube
|
||||||
|
|
||||||
import org.junit.Test
|
|
||||||
|
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.*
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example local unit test, which will execute on the development machine (host).
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
Loading…
Reference in New Issue
Block a user