Merge branch 'libre-tube:master' into master

This commit is contained in:
ձռօռყ_սռĸռօառ 2022-06-24 23:05:05 +05:30 committed by GitHub
commit 0eca8e3986
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 181 additions and 106 deletions

View File

@ -62,3 +62,4 @@ WARNING: THIS IS A BETA VERSION, THEREFORE YOU MAY ENCOUNTER BUGS. IF YOU DO, OP
## Mirrors (read-only) ## Mirrors (read-only)
<a href="https://gitlab.com/libretube/LibreTube">GitLab</a></p> <a href="https://gitlab.com/libretube/LibreTube">GitLab</a></p>
<a href="https://notabug.org/LibreTube/LibreTube">NotABug</a></p>

View File

@ -69,7 +69,6 @@ class DownloadService : Service() {
} }
private fun downloadManager() { private fun downloadManager() {
// create folder for temporary files // create folder for temporary files
tempDir = File( tempDir = File(
applicationContext.getExternalFilesDir(DIRECTORY_DOWNLOADS), applicationContext.getExternalFilesDir(DIRECTORY_DOWNLOADS),
@ -255,7 +254,8 @@ class DownloadService : Service() {
if (returnCode.toString() != "0") downloadFailedNotification() if (returnCode.toString() != "0") downloadFailedNotification()
else downloadSucceededNotification() else downloadSucceededNotification()
onDestroy() onDestroy()
}, { },
{
// CALLED WHEN SESSION PRINTS LOGS // CALLED WHEN SESSION PRINTS LOGS
Log.e(TAG, it.message.toString()) Log.e(TAG, it.message.toString())
} }

View File

@ -19,11 +19,11 @@ import com.github.libretube.obj.CommentsPage
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.github.libretube.util.formatShort import com.github.libretube.util.formatShort
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import java.io.IOException
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class CommentsAdapter( class CommentsAdapter(
private val videoId: String, private val videoId: String,

View File

@ -20,11 +20,11 @@ import com.github.libretube.obj.PlaylistId
import com.github.libretube.obj.StreamItem import com.github.libretube.obj.StreamItem
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import java.io.IOException
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class PlaylistAdapter( class PlaylistAdapter(
private val videoFeed: MutableList<StreamItem>, private val videoFeed: MutableList<StreamItem>,

View File

@ -17,10 +17,10 @@ import com.github.libretube.obj.Playlists
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
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 playlists: MutableList<Playlists>,

View File

@ -85,10 +85,11 @@ class SearchViewHolder(
val viewsString = if (item.views?.toInt() != -1) item.views.formatShort() else "" val viewsString = if (item.views?.toInt() != -1) item.views.formatShort() else ""
val uploadDate = if (item.uploadedDate != null) item.uploadedDate else "" val uploadDate = if (item.uploadedDate != null) item.uploadedDate else ""
views.text = views.text =
if (viewsString != "" && uploadDate != "") if (viewsString != "" && uploadDate != "") {
"$viewsString$uploadDate" "$viewsString$uploadDate"
else } else {
viewsString + uploadDate 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 {
@ -145,9 +146,10 @@ class SearchViewHolder(
val playlistChannelName = v.findViewById<TextView>(R.id.search_name) val playlistChannelName = v.findViewById<TextView>(R.id.search_name)
playlistChannelName.text = item.uploaderName playlistChannelName.text = item.uploaderName
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) if (item.videos?.toInt() != -1) {
playlistVideosNumber.text = playlistVideosNumber.text =
v.context.getString(R.string.videoCount, item.videos.toString()) 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

View File

@ -34,8 +34,9 @@ class SubscriptionAdapter(
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()
} }

View File

@ -15,11 +15,11 @@ import com.github.libretube.obj.Subscribe
import com.github.libretube.obj.Subscription import com.github.libretube.obj.Subscription
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import java.io.IOException
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class SubscriptionChannelAdapter(private val subscriptions: MutableList<Subscription>) : class SubscriptionChannelAdapter(private val subscriptions: MutableList<Subscription>) :
RecyclerView.Adapter<SubscriptionChannelViewHolder>() { RecyclerView.Adapter<SubscriptionChannelViewHolder>() {

View File

@ -19,8 +19,8 @@ import com.github.libretube.R
import com.github.libretube.obj.PlaylistId import com.github.libretube.obj.PlaylistId
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.IOException
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class AddtoPlaylistDialog : DialogFragment() { class AddtoPlaylistDialog : DialogFragment() {
private val TAG = "AddToPlaylistDialog" private val TAG = "AddToPlaylistDialog"

View File

@ -19,8 +19,8 @@ import com.github.libretube.obj.Playlists
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import java.io.IOException
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class CreatePlaylistDialog : DialogFragment() { class CreatePlaylistDialog : DialogFragment() {
val TAG = "CreatePlaylistDialog" val TAG = "CreatePlaylistDialog"

View File

@ -52,13 +52,17 @@ class CustomInstanceDialog : DialogFragment() {
} catch (e: Exception) { } catch (e: Exception) {
// invalid URL // invalid URL
Toast.makeText( Toast.makeText(
context, getString(R.string.invalid_url), Toast.LENGTH_SHORT context,
getString(R.string.invalid_url),
Toast.LENGTH_SHORT
).show() ).show()
} }
} else { } else {
// at least one empty input // at least one empty input
Toast.makeText( Toast.makeText(
context, context?.getString(R.string.empty_instance), Toast.LENGTH_SHORT context,
context?.getString(R.string.empty_instance),
Toast.LENGTH_SHORT
).show() ).show()
} }
} }

View File

@ -17,8 +17,8 @@ import com.github.libretube.R
import com.github.libretube.obj.Login import com.github.libretube.obj.Login
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.IOException
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class LoginDialog : DialogFragment() { class LoginDialog : DialogFragment() {
private val TAG = "LoginDialog" private val TAG = "LoginDialog"

View File

@ -11,11 +11,11 @@ import com.github.libretube.R
import com.github.libretube.obj.PlaylistId import com.github.libretube.obj.PlaylistId
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.IOException
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class PlaylistOptionsDialog( class PlaylistOptionsDialog(
private val playlistId: String, private val playlistId: String,

View File

@ -22,8 +22,8 @@ import com.github.libretube.util.RetrofitInstance
import com.github.libretube.util.formatShort import com.github.libretube.util.formatShort
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 java.io.IOException
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class ChannelFragment : Fragment() { class ChannelFragment : Fragment() {
@ -201,7 +201,10 @@ class ChannelFragment : Fragment() {
channelName.text = response.name channelName.text = response.name
if (response.verified) { if (response.verified) {
channelName.setCompoundDrawablesWithIntrinsicBounds( channelName.setCompoundDrawablesWithIntrinsicBounds(
0, 0, R.drawable.ic_verified, 0 0,
0,
R.drawable.ic_verified,
0
) )
} }
view.findViewById<TextView>(R.id.channel_subs).text = resources.getString( view.findViewById<TextView>(R.id.channel_subs).text = resources.getString(
@ -231,7 +234,6 @@ class ChannelFragment : Fragment() {
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!!)

View File

@ -16,8 +16,8 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.adapters.TrendingAdapter import com.github.libretube.adapters.TrendingAdapter
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import java.io.IOException
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class Home : Fragment() { class Home : Fragment() {
@ -34,7 +34,6 @@ class Home : Fragment() {
container: ViewGroup?, 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)
} }

View File

@ -19,8 +19,8 @@ import com.github.libretube.adapters.PlaylistsAdapter
import com.github.libretube.dialogs.CreatePlaylistDialog import com.github.libretube.dialogs.CreatePlaylistDialog
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
import java.io.IOException
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class Library : Fragment() { class Library : Fragment() {

View File

@ -18,6 +18,7 @@ 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
import android.widget.Button
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.ImageView import android.widget.ImageView
@ -84,11 +85,11 @@ import com.google.android.material.button.MaterialButton
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
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.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
@ -118,6 +119,7 @@ class PlayerFragment : Fragment() {
private lateinit var segmentData: Segments private lateinit var segmentData: Segments
private var relatedStreams: List<StreamItem>? = arrayListOf() private var relatedStreams: List<StreamItem>? = arrayListOf()
private var relatedStreamsEnabled = true private var relatedStreamsEnabled = true
private var isPlayerLocked: Boolean = false
private lateinit var relDownloadVideo: LinearLayout private lateinit var relDownloadVideo: LinearLayout
@ -182,6 +184,7 @@ class PlayerFragment : Fragment() {
val mainMotionLayout = val mainMotionLayout =
mainActivity.findViewById<MotionLayout>(R.id.mainMotionLayout) mainActivity.findViewById<MotionLayout>(R.id.mainMotionLayout)
mainMotionLayout.progress = abs(progress) mainMotionLayout.progress = abs(progress)
exoPlayerView.hideController()
eId = endId eId = endId
sId = startId sId = startId
} }
@ -192,13 +195,11 @@ class PlayerFragment : Fragment() {
val mainMotionLayout = val mainMotionLayout =
mainActivity.findViewById<MotionLayout>(R.id.mainMotionLayout) mainActivity.findViewById<MotionLayout>(R.id.mainMotionLayout)
if (currentId == eId) { if (currentId == eId) {
exoPlayerView.hideController()
exoPlayerView.useController = false exoPlayerView.useController = false
mainMotionLayout.progress = 1.toFloat() mainMotionLayout.progress = 1F
} else if (currentId == sId) { } else if (currentId == sId) {
exoPlayerView.showController()
exoPlayerView.useController = true exoPlayerView.useController = true
mainMotionLayout.progress = 0.toFloat() mainMotionLayout.progress = 0F
} }
} }
@ -259,8 +260,9 @@ class PlayerFragment : Fragment() {
} }
// FullScreen button trigger // FullScreen button trigger
view.findViewById<ImageButton>(R.id.fullscreen).setOnClickListener { val fullScreenButton = view.findViewById<ImageButton>(R.id.fullscreen)
// remember to hide everything when new thing added fullScreenButton.setOnClickListener {
exoPlayerView.hideController()
if (!isFullScreen) { if (!isFullScreen) {
with(motionLayout) { with(motionLayout) {
getConstraintSet(R.id.start).constrainHeight(R.id.player, -1) getConstraintSet(R.id.start).constrainHeight(R.id.player, -1)
@ -268,6 +270,7 @@ class PlayerFragment : Fragment() {
} }
view.findViewById<ConstraintLayout>(R.id.main_container).isClickable = true view.findViewById<ConstraintLayout>(R.id.main_container).isClickable = true
view.findViewById<LinearLayout>(R.id.linLayout).visibility = View.GONE view.findViewById<LinearLayout>(R.id.linLayout).visibility = View.GONE
fullScreenButton.setImageResource(R.drawable.ic_fullscreen_exit)
val mainActivity = activity as MainActivity val mainActivity = activity as MainActivity
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
isFullScreen = true isFullScreen = true
@ -278,6 +281,7 @@ class PlayerFragment : Fragment() {
} }
view.findViewById<ConstraintLayout>(R.id.main_container).isClickable = false view.findViewById<ConstraintLayout>(R.id.main_container).isClickable = false
view.findViewById<LinearLayout>(R.id.linLayout).visibility = View.VISIBLE view.findViewById<LinearLayout>(R.id.linLayout).visibility = View.VISIBLE
fullScreenButton.setImageResource(R.drawable.ic_fullscreen)
val mainActivity = activity as MainActivity val mainActivity = activity as MainActivity
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
isFullScreen = false isFullScreen = false
@ -295,6 +299,23 @@ class PlayerFragment : Fragment() {
} }
} }
// lock and unlock the player
val lockPlayerButton = view.findViewById<ImageButton>(R.id.lock_player)
lockPlayerButton.setOnClickListener {
// change the locked/unlocked icon
if (!isPlayerLocked) {
lockPlayerButton.setImageResource(R.drawable.ic_locked)
} else {
lockPlayerButton.setImageResource(R.drawable.ic_unlocked)
}
// show/hide all the controls
lockPlayer(isPlayerLocked)
// change locked status
isPlayerLocked = !isPlayerLocked
}
val scrollView = view.findViewById<ScrollView>(R.id.player_scrollView) val scrollView = view.findViewById<ScrollView>(R.id.player_scrollView)
scrollView.viewTreeObserver scrollView.viewTreeObserver
.addOnScrollChangedListener { .addOnScrollChangedListener {
@ -362,8 +383,9 @@ class PlayerFragment : Fragment() {
exoPlayerView.postDelayed(this::checkForSegments, 100) exoPlayerView.postDelayed(this::checkForSegments, 100)
if (!::segmentData.isInitialized || segmentData.segments.isEmpty()) if (!::segmentData.isInitialized || 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()
@ -458,7 +480,6 @@ class PlayerFragment : Fragment() {
} }
if (categories.size > 0) { if (categories.size > 0) {
segmentData = try { segmentData = try {
RetrofitInstance.api.getSegments( RetrofitInstance.api.getSegments(
videoId!!, videoId!!,
"[\"" + TextUtils.join("\",\"", categories) + "\"]" "[\"" + TextUtils.join("\",\"", categories) + "\"]"
@ -523,7 +544,6 @@ class PlayerFragment : Fragment() {
playWhenReady: Boolean, playWhenReady: Boolean,
playbackState: Int playbackState: Int
) { ) {
exoPlayerView.keepScreenOn = !( exoPlayerView.keepScreenOn = !(
playbackState == Player.STATE_IDLE || playbackState == Player.STATE_IDLE ||
playbackState == Player.STATE_ENDED || playbackState == Player.STATE_ENDED ||
@ -627,7 +647,6 @@ class PlayerFragment : Fragment() {
} }
view.findViewById<RelativeLayout>(R.id.player_channel).setOnClickListener { view.findViewById<RelativeLayout>(R.id.player_channel).setOnClickListener {
val activity = view.context as MainActivity val activity = view.context as MainActivity
val bundle = bundleOf("channel_id" to response.uploaderUrl) val bundle = bundleOf("channel_id" to response.uploaderUrl)
activity.navController.navigate(R.id.channel, bundle) activity.navController.navigate(R.id.channel, bundle)
@ -717,7 +736,6 @@ class PlayerFragment : Fragment() {
} }
for (vid in response.videoStreams!!) { for (vid in response.videoStreams!!) {
Log.e(TAG, vid.toString())
// append quality to list if it has the preferred format (e.g. MPEG) // append quality to list if it has the preferred format (e.g. MPEG)
if (vid.format.equals(videoFormatPreference)) { // preferred format if (vid.format.equals(videoFormatPreference)) { // preferred format
videosNameArray += vid.quality!! videosNameArray += vid.quality!!
@ -863,7 +881,6 @@ class PlayerFragment : Fragment() {
} }
private fun initializePlayerNotification(c: Context) { private fun initializePlayerNotification(c: Context) {
mediaSession = MediaSessionCompat(c, this.javaClass.name) mediaSession = MediaSessionCompat(c, this.javaClass.name)
mediaSession.apply { mediaSession.apply {
isActive = true isActive = true
@ -887,6 +904,15 @@ class PlayerFragment : Fragment() {
} }
} }
private fun lockPlayer(isLocked: Boolean) {
val visibility = if (isLocked) View.VISIBLE else View.GONE
exoPlayerView.findViewById<LinearLayout>(R.id.controls_top_right).visibility = visibility
exoPlayerView.findViewById<ImageButton>(R.id.exo_play_pause).visibility = visibility
exoPlayerView.findViewById<Button>(R.id.exo_ffwd_with_amount).visibility = visibility
exoPlayerView.findViewById<Button>(R.id.exo_rew_with_amount).visibility = visibility
exoPlayerView.findViewById<FrameLayout>(R.id.exo_bottom_bar).visibility = visibility
}
private fun isSubscribed(button: MaterialButton, channel_id: String) { private fun isSubscribed(button: MaterialButton, channel_id: String) {
@SuppressLint("ResourceAsColor") @SuppressLint("ResourceAsColor")
fun run() { fun run() {

View File

@ -16,8 +16,8 @@ import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.adapters.PlaylistAdapter import com.github.libretube.adapters.PlaylistAdapter
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import java.io.IOException
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class PlaylistFragment : Fragment() { class PlaylistFragment : Fragment() {
private val TAG = "PlaylistFragment" private val TAG = "PlaylistFragment"
@ -113,7 +113,6 @@ class PlaylistFragment : Fragment() {
private fun fetchNextPage() { private fun fetchNextPage() {
fun run() { fun run() {
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
val response = try { val response = try {
RetrofitInstance.api.getPlaylistNextPage(playlistId!!, nextPage!!) RetrofitInstance.api.getPlaylistNextPage(playlistId!!, nextPage!!)

View File

@ -29,10 +29,10 @@ import com.github.libretube.adapters.SearchSuggestionsAdapter
import com.github.libretube.hideKeyboard import com.github.libretube.hideKeyboard
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
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 SearchFragment : Fragment() { class SearchFragment : Fragment() {
private val TAG = "SearchFragment" private val TAG = "SearchFragment"
@ -94,7 +94,7 @@ class SearchFragment : Fragment() {
tempSelectedItem = id tempSelectedItem = id
} }
.setPositiveButton( .setPositiveButton(
getString(R.string.okay), getString(R.string.okay)
) { _, _ -> ) { _, _ ->
selectedFilter = tempSelectedItem selectedFilter = tempSelectedItem
apiSearchFilter = when (selectedFilter) { apiSearchFilter = when (selectedFilter) {

View File

@ -24,8 +24,8 @@ import com.github.libretube.R
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 com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import java.io.IOException
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class Subscriptions : Fragment() { class Subscriptions : Fragment() {
val TAG = "SubFragment" val TAG = "SubFragment"
@ -65,7 +65,8 @@ class Subscriptions : Fragment() {
var feedRecView = view.findViewById<RecyclerView>(R.id.sub_feed) var feedRecView = view.findViewById<RecyclerView>(R.id.sub_feed)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
val grid = sharedPreferences.getString( val grid = sharedPreferences.getString(
"grid", resources.getInteger(R.integer.grid_items).toString() "grid",
resources.getInteger(R.integer.grid_items).toString()
)!! )!!
feedRecView.layoutManager = GridLayoutManager(view.context, grid.toInt()) feedRecView.layoutManager = GridLayoutManager(view.context, grid.toInt())
fetchFeed(feedRecView, progressBar, view) fetchFeed(feedRecView, progressBar, view)

View File

@ -6,7 +6,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
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, "")
} }

View File

@ -12,5 +12,5 @@ data class Playlist(
var uploaderUrl: String? = null, var uploaderUrl: String? = null,
var uploaderAvatar: String? = null, var uploaderAvatar: String? = null,
var videos: Int? = 0, var videos: Int? = 0,
var relatedStreams: List<StreamItem>? = null, var relatedStreams: List<StreamItem>? = null
) )

View File

@ -6,5 +6,5 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
data class PlaylistId( data class PlaylistId(
var playlistId: String? = null, var playlistId: String? = null,
var videoId: String? = null, var videoId: String? = null,
var index: Int = -1, var index: Int = -1
) )

View File

@ -7,5 +7,5 @@ data class Playlists(
var id: String? = null, var id: String? = null,
var name: String? = null, var name: String? = null,
var shortDescription: String? = null, var shortDescription: String? = null,
var thumbnail: String? = null, var thumbnail: String? = null
) )

View File

@ -25,13 +25,13 @@ import com.github.libretube.dialogs.CustomInstanceDialog
import com.github.libretube.dialogs.LoginDialog import com.github.libretube.dialogs.LoginDialog
import com.github.libretube.requireMainActivityRestart import com.github.libretube.requireMainActivityRestart
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
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 InstanceSettings : PreferenceFragmentCompat() { class InstanceSettings : PreferenceFragmentCompat() {
val TAG = "InstanceSettings" val TAG = "InstanceSettings"
@ -85,11 +85,12 @@ class InstanceSettings : PreferenceFragmentCompat() {
inputStream?.bufferedReader()?.readLines()?.forEach { inputStream?.bufferedReader()?.readLines()?.forEach {
if (it.isNotBlank()) { if (it.isNotBlank()) {
val channelId = it.substringBefore(",") val channelId = it.substringBefore(",")
if (channelId.length == 24) if (channelId.length == 24) {
channels.add(channelId) channels.add(channelId)
} }
} }
} }
}
inputStream?.close() inputStream?.close()
subscribe(channels) subscribe(channels)

View File

@ -82,7 +82,10 @@ class DescriptionAdapter(
*/ */
return try { return try {
val resizedBitmap = Bitmap.createScaledBitmap( val resizedBitmap = Bitmap.createScaledBitmap(
bitmap, 1080, 1080, false bitmap,
1080,
1080,
false
) )
resizedBitmap resizedBitmap
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -7,12 +7,12 @@ import com.github.libretube.GITHUB_API_URL
import com.github.libretube.dialogs.NoUpdateAvailableDialog import com.github.libretube.dialogs.NoUpdateAvailableDialog
import com.github.libretube.dialogs.UpdateAvailableDialog import com.github.libretube.dialogs.UpdateAvailableDialog
import com.github.libretube.obj.UpdateInfo import com.github.libretube.obj.UpdateInfo
import org.json.JSONArray
import org.json.JSONObject
import java.io.BufferedReader import java.io.BufferedReader
import java.io.InputStreamReader import java.io.InputStreamReader
import java.net.URL import java.net.URL
import javax.net.ssl.HttpsURLConnection import javax.net.ssl.HttpsURLConnection
import org.json.JSONArray
import org.json.JSONObject
fun checkUpdate(childFragmentManager: FragmentManager) { fun checkUpdate(childFragmentManager: FragmentManager) {
var updateInfo: UpdateInfo? = UpdateInfo("", "") var updateInfo: UpdateInfo? = UpdateInfo("", "")

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="@android:color/white"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M7,14L5,14v5h5v-2L7,17v-3zM5,10h2L7,7h3L10,5L5,5v5zM17,17h-3v2h5v-5h-2v3zM14,5v2h3v3h2L19,5h-5z" />
</vector>

View File

@ -0,0 +1,10 @@
<vector android:height="24dp"
android:tint="@android:color/white"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M5,16h3v3h2v-5L5,14v2zM8,8L5,8v2h5L10,5L8,5v3zM14,19h2v-3h3v-2h-5v5zM16,8L16,5h-2v5h5L19,8h-3z" />
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="@android:color/holo_green_dark"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM15.1,8L8.9,8L8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2z" />
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="@android:color/white"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6h1.9c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM18,20L6,20L6,10h12v10z" />
</vector>

View File

@ -46,16 +46,27 @@
android:layoutDirection="ltr"> android:layoutDirection="ltr">
<ImageButton <ImageButton
android:visibility="gone"
android:id="@+id/close_imageButton" android:id="@+id/close_imageButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@drawable/ic_close" android:src="@drawable/ic_close"
android:padding="@dimen/exo_icon_padding" android:padding="@dimen/exo_icon_padding"
android:background="#00FFFFFF" android:background="#00FFFFFF"
app:tint="@android:color/white" /> app:tint="@android:color/white"
android:layout_marginRight="10dp"/>
<ImageButton
android:id="@+id/lock_player"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_unlocked"
android:padding="@dimen/exo_icon_padding"
android:background="#00FFFFFF" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/controls_top_right"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingStart="@dimen/exo_styled_bottom_bar_time_padding" android:paddingStart="@dimen/exo_styled_bottom_bar_time_padding"
@ -136,14 +147,6 @@
android:layout_marginBottom="10dp" android:layout_marginBottom="10dp"
android:layoutDirection="ltr"> android:layoutDirection="ltr">
<ImageButton
android:id="@id/exo_vr"
style="@style/ExoStyledControls.Button.Bottom.VR" />
<ImageButton
android:id="@id/exo_shuffle"
style="@style/ExoStyledControls.Button.Bottom.Shuffle" />
<ImageButton <ImageButton
android:id="@id/exo_repeat_toggle" android:id="@id/exo_repeat_toggle"
style="@style/ExoStyledControls.Button.Bottom.RepeatToggle" /> style="@style/ExoStyledControls.Button.Bottom.RepeatToggle" />
@ -158,15 +161,8 @@
<ImageButton <ImageButton
android:id="@+id/fullscreen" android:id="@+id/fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen" /> style="@style/ExoStyledControls.Button.Bottom.FullScreen"
android:src="@drawable/ic_fullscreen"/>
<ImageButton
android:id="@id/exo_fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen" />
<ImageButton
android:id="@id/exo_overflow_show"
style="@style/ExoStyledControls.Button.Bottom.OverflowShow" />
</LinearLayout> </LinearLayout>
@ -191,8 +187,6 @@
</HorizontalScrollView> </HorizontalScrollView>
</FrameLayout>
<LinearLayout <LinearLayout
android:id="@+id/progress_bar" android:id="@+id/progress_bar"
android:layout_gravity="bottom" android:layout_gravity="bottom"
@ -216,6 +210,8 @@
</LinearLayout> </LinearLayout>
</FrameLayout>
<LinearLayout <LinearLayout
android:id="@id/exo_minimal_controls" android:id="@id/exo_minimal_controls"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -226,10 +222,6 @@
android:gravity="center_vertical" android:gravity="center_vertical"
android:layoutDirection="ltr"> android:layoutDirection="ltr">
<ImageButton
android:id="@id/exo_minimal_fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
@ -244,18 +236,22 @@
<Button <Button
android:id="@id/exo_rew_with_amount" android:id="@id/exo_rew_with_amount"
android:paddingLeft="4dp" android:layout_marginRight="25dp"
android:paddingRight="4dp" android:scaleX="1.1"
android:scaleY="1.1"
style="@style/ExoStyledControls.Button.Center.RewWithAmount" /> style="@style/ExoStyledControls.Button.Center.RewWithAmount" />
<ImageButton <ImageButton
android:id="@id/exo_play_pause" android:id="@id/exo_play_pause"
android:scaleX="1.1"
android:scaleY="1.1"
style="@style/ExoStyledControls.Button.Center.PlayPause" /> style="@style/ExoStyledControls.Button.Center.PlayPause" />
<Button <Button
android:id="@id/exo_ffwd_with_amount" android:id="@id/exo_ffwd_with_amount"
android:paddingLeft="4dp" android:layout_marginLeft="25dp"
android:paddingRight="4dp" android:scaleX="1.1"
android:scaleY="1.1"
style="@style/ExoStyledControls.Button.Center.FfwdWithAmount" /> style="@style/ExoStyledControls.Button.Center.FfwdWithAmount" />
</LinearLayout> </LinearLayout>