add legacy subscriptions view

This commit is contained in:
Bnyro 2022-08-24 17:56:57 +02:00
parent 326573659c
commit 298023b702
29 changed files with 357 additions and 110 deletions

View File

@ -62,8 +62,11 @@ class MainActivity : BaseActivity() {
autoRotationEnabled = PreferenceHelper.getBoolean(PreferenceKeys.AUTO_ROTATION, false) autoRotationEnabled = PreferenceHelper.getBoolean(PreferenceKeys.AUTO_ROTATION, false)
// enable auto rotation if turned on // enable auto rotation if turned on
requestedOrientation = if (autoRotationEnabled) ActivityInfo.SCREEN_ORIENTATION_USER requestedOrientation = if (autoRotationEnabled) {
else ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT ActivityInfo.SCREEN_ORIENTATION_USER
} else {
ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
}
// start service that gets called on closure // start service that gets called on closure
try { try {
@ -98,8 +101,10 @@ class MainActivity : BaseActivity() {
// hide the trending page if enabled // hide the trending page if enabled
val hideTrendingPage = val hideTrendingPage =
PreferenceHelper.getBoolean(PreferenceKeys.HIDE_TRENDING_PAGE, false) PreferenceHelper.getBoolean(PreferenceKeys.HIDE_TRENDING_PAGE, false)
if (hideTrendingPage) binding.bottomNav.menu.findItem(R.id.homeFragment).isVisible = if (hideTrendingPage) {
binding.bottomNav.menu.findItem(R.id.homeFragment).isVisible =
false false
}
// save start tab fragment id // save start tab fragment id
startFragmentId = startFragmentId =
@ -166,14 +171,18 @@ class MainActivity : BaseActivity() {
PreferenceKeys.BREAK_REMINDER_TOGGLE, PreferenceKeys.BREAK_REMINDER_TOGGLE,
false false
) )
) return ) {
return
}
val breakReminderPref = PreferenceHelper.getString( val breakReminderPref = PreferenceHelper.getString(
PreferenceKeys.BREAK_REMINDER, PreferenceKeys.BREAK_REMINDER,
"0" "0"
) )
if (!breakReminderPref.all { Character.isDigit(it) } || if (!breakReminderPref.all { Character.isDigit(it) } ||
breakReminderPref == "" || breakReminderPref == "0" breakReminderPref == "" || breakReminderPref == "0"
) return ) {
return
}
Handler(Looper.getMainLooper()).postDelayed( Handler(Looper.getMainLooper()).postDelayed(
{ {
try { try {
@ -403,8 +412,11 @@ class MainActivity : BaseActivity() {
) { ) {
Log.i(TAG(), "Uri Type: Channel") Log.i(TAG(), "Uri Type: Channel")
val bundle = if (channelId != null) bundleOf("channel_id" to channelId) val bundle = if (channelId != null) {
else bundleOf("channel_name" to channelName) bundleOf("channel_id" to channelId)
} else {
bundleOf("channel_name" to channelName)
}
navController.navigate(R.id.channelFragment, bundle) navController.navigate(R.id.channelFragment, bundle)
} }
@ -452,8 +464,11 @@ class MainActivity : BaseActivity() {
findViewById<LinearLayout>(R.id.linLayout).visibility = View.VISIBLE findViewById<LinearLayout>(R.id.linLayout).visibility = View.VISIBLE
val playerViewModel = ViewModelProvider(this)[PlayerViewModel::class.java] val playerViewModel = ViewModelProvider(this)[PlayerViewModel::class.java]
playerViewModel.isFullscreen.value = false playerViewModel.isFullscreen.value = false
requestedOrientation = if (autoRotationEnabled) ActivityInfo.SCREEN_ORIENTATION_USER requestedOrientation = if (autoRotationEnabled) {
else ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT ActivityInfo.SCREEN_ORIENTATION_USER
} else {
ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
}
} }
override fun onConfigurationChanged(newConfig: Configuration) { override fun onConfigurationChanged(newConfig: Configuration) {

View File

@ -33,7 +33,9 @@ class ChaptersAdapter(
val color = val color =
ThemeHelper.getThemeColor(root.context, android.R.attr.colorControlHighlight) ThemeHelper.getThemeColor(root.context, android.R.attr.colorControlHighlight)
chapterLL.setBackgroundColor(color) chapterLL.setBackgroundColor(color)
} else chapterLL.setBackgroundColor(Color.TRANSPARENT) } else {
chapterLL.setBackgroundColor(Color.TRANSPARENT)
}
root.setOnClickListener { root.setOnClickListener {
updateSelectedPosition(position) updateSelectedPosition(position)
val chapterStart = chapter.start!! * 1000 // s -> ms val chapterStart = chapter.start!! * 1000 // s -> ms

View File

@ -0,0 +1,49 @@
package com.github.libretube.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.databinding.LegacySubscriptionChannelBinding
import com.github.libretube.obj.Subscription
import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.toID
class LegacySubscriptionAdapter(
private val subscriptions: List<Subscription>
) : RecyclerView.Adapter<LegacySubscriptionViewHolder>() {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): LegacySubscriptionViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = LegacySubscriptionChannelBinding.inflate(layoutInflater, parent, false)
return LegacySubscriptionViewHolder(binding)
}
override fun onBindViewHolder(holder: LegacySubscriptionViewHolder, position: Int) {
val subscription = subscriptions[position]
holder.binding.apply {
channelName.text = subscription.name
ImageHelper.loadImage(
subscription.avatar,
channelAvatar
)
root.setOnClickListener {
NavigationHelper.navigateChannel(
root.context,
subscription.url.toID()
)
}
}
}
override fun getItemCount(): Int {
return subscriptions.size
}
}
class LegacySubscriptionViewHolder(
val binding: LegacySubscriptionChannelBinding
) : RecyclerView.ViewHolder(binding.root)

View File

@ -63,9 +63,11 @@ class SearchAdapter(
val channelRowBinding = holder.channelRowBinding val channelRowBinding = holder.channelRowBinding
val playlistRowBinding = holder.playlistRowBinding val playlistRowBinding = holder.playlistRowBinding
if (videoRowBinding != null) bindWatch(searchItem, videoRowBinding) if (videoRowBinding != null) {
else if (channelRowBinding != null) bindChannel(searchItem, channelRowBinding) bindWatch(searchItem, videoRowBinding)
else if (playlistRowBinding != null) bindPlaylist(searchItem, playlistRowBinding) } else if (channelRowBinding != null) {
bindChannel(searchItem, channelRowBinding)
} else if (playlistRowBinding != null) bindPlaylist(searchItem, playlistRowBinding)
} }
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {

View File

@ -24,9 +24,13 @@ class TrendingAdapter(
var index = 10 var index = 10
override fun getItemCount(): Int { override fun getItemCount(): Int {
return if (showAllAtOne) streamItems.size return if (showAllAtOne) {
else if (index >= streamItems.size) streamItems.size - 1 streamItems.size
else index } else if (index >= streamItems.size) {
streamItems.size - 1
} else {
index
}
} }
fun updateItems() { fun updateItems() {

View File

@ -72,9 +72,11 @@ class AddToPlaylistDialog : DialogFragment() {
if (viewModel.lastSelectedPlaylistId != null) { if (viewModel.lastSelectedPlaylistId != null) {
var selectionIndex = 0 var selectionIndex = 0
response.forEachIndexed { index, playlist -> response.forEachIndexed { index, playlist ->
if (playlist.id == viewModel.lastSelectedPlaylistId) selectionIndex = if (playlist.id == viewModel.lastSelectedPlaylistId) {
selectionIndex =
index index
} }
}
binding.playlistsSpinner.setSelection(selectionIndex) binding.playlistsSpinner.setSelection(selectionIndex)
} }
runOnUiThread { runOnUiThread {

View File

@ -56,8 +56,11 @@ class PlaylistOptionsDialog(
context?.getString(R.string.playOnBackground) -> { context?.getString(R.string.playOnBackground) -> {
runBlocking { runBlocking {
val playlist = val playlist =
if (isOwner) RetrofitInstance.authApi.getPlaylist(playlistId) if (isOwner) {
else RetrofitInstance.api.getPlaylist(playlistId) RetrofitInstance.authApi.getPlaylist(playlistId)
} else {
RetrofitInstance.api.getPlaylist(playlistId)
}
BackgroundHelper.playOnBackground( BackgroundHelper.playOnBackground(
context = requireContext(), context = requireContext(),
videoId = playlist.relatedStreams!![0].url.toID(), videoId = playlist.relatedStreams!![0].url.toID(),

View File

@ -8,7 +8,10 @@ fun TextView?.setFormattedDuration(duration: Long) {
val text = if (duration < 0L) { val text = if (duration < 0L) {
this!!.setBackgroundColor(R.attr.colorPrimaryDark) this!!.setBackgroundColor(R.attr.colorPrimaryDark)
this.context.getString(R.string.live) this.context.getString(R.string.live)
} else if (duration == 0L) this!!.context.getString(R.string.yt_shorts) } else if (duration == 0L) {
else DateUtils.formatElapsedTime(duration) this!!.context.getString(R.string.yt_shorts)
} else {
DateUtils.formatElapsedTime(duration)
}
this!!.text = text this!!.text = text
} }

View File

@ -110,8 +110,11 @@ class ChannelFragment : BaseFragment() {
fun run() { fun run() {
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
val response = try { val response = try {
if (channelId != null) RetrofitInstance.api.getChannel(channelId!!) if (channelId != null) {
else RetrofitInstance.api.getChannelByName(channelName!!) RetrofitInstance.api.getChannel(channelId!!)
} else {
RetrofitInstance.api.getChannelByName(channelName!!)
}
} catch (e: IOException) { } catch (e: IOException) {
binding.channelRefresh.isRefreshing = false binding.channelRefresh.isRefreshing = false
println(e) println(e)

View File

@ -53,7 +53,9 @@ class HomeFragment : BaseFragment() {
LocaleHelper LocaleHelper
.getDetectedCountry(requireContext(), "UK") .getDetectedCountry(requireContext(), "UK")
.uppercase() .uppercase()
} else regionPref } else {
regionPref
}
binding.recview.layoutManager = GridLayoutManager(view.context, grid.toInt()) binding.recview.layoutManager = GridLayoutManager(view.context, grid.toInt())
fetchJson() fetchJson()

View File

@ -585,13 +585,18 @@ class PlayerFragment : BaseFragment() {
val bottomSheetFragment = PlayerOptionsBottomSheet().apply { val bottomSheetFragment = PlayerOptionsBottomSheet().apply {
setOnClickListeners(playerOptionsInterface) setOnClickListeners(playerOptionsInterface)
// set the auto play mode // set the auto play mode
currentAutoplayMode = if (autoplayEnabled) context.getString(R.string.enabled) currentAutoplayMode = if (autoplayEnabled) {
else context.getString(R.string.disabled) context.getString(R.string.enabled)
} else {
context.getString(R.string.disabled)
}
// set the current caption language // set the current caption language
currentCaptions = currentCaptions =
if (trackSelector.parameters.preferredTextLanguages.isNotEmpty()) { if (trackSelector.parameters.preferredTextLanguages.isNotEmpty()) {
trackSelector.parameters.preferredTextLanguages[0] trackSelector.parameters.preferredTextLanguages[0]
} else context.getString(R.string.none) } else {
context.getString(R.string.none)
}
// set the playback speed // set the playback speed
val playbackSpeeds = context.resources.getStringArray(R.array.playbackSpeed) val playbackSpeeds = context.resources.getStringArray(R.array.playbackSpeed)
val playbackSpeedValues = val playbackSpeedValues =
@ -603,14 +608,19 @@ class PlayerFragment : BaseFragment() {
val quality = exoPlayer.videoSize.height val quality = exoPlayer.videoSize.height
if (quality != 0) { if (quality != 0) {
currentQuality = currentQuality =
if (isAdaptive) "${context.getString(R.string.hls)}${quality}p" if (isAdaptive) {
else "${quality}p" "${context.getString(R.string.hls)}${quality}p"
} else {
"${quality}p"
}
} }
// set the repeat mode // set the repeat mode
currentRepeatMode = currentRepeatMode =
if (exoPlayer.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) { if (exoPlayer.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) {
context.getString(R.string.repeat_mode_none) context.getString(R.string.repeat_mode_none)
} else context.getString(R.string.repeat_mode_current) } else {
context.getString(R.string.repeat_mode_current)
}
// set the aspect ratio mode // set the aspect ratio mode
currentResizeMode = when (exoPlayerView.resizeMode) { currentResizeMode = when (exoPlayerView.resizeMode) {
AspectRatioFrameLayout.RESIZE_MODE_FIT -> context.getString(R.string.resize_mode_fit) AspectRatioFrameLayout.RESIZE_MODE_FIT -> context.getString(R.string.resize_mode_fit)
@ -729,9 +739,12 @@ class PlayerFragment : BaseFragment() {
"ratio" -> { "ratio" -> {
val videoSize = exoPlayer.videoSize val videoSize = exoPlayer.videoSize
// probably a youtube shorts video // probably a youtube shorts video
if (videoSize.height > videoSize.width) ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT if (videoSize.height > videoSize.width) {
// a video with normal aspect ratio ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
else ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE } // a video with normal aspect ratio
else {
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
}
} }
"auto" -> ActivityInfo.SCREEN_ORIENTATION_SENSOR "auto" -> ActivityInfo.SCREEN_ORIENTATION_SENSOR
"landscape" -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE "landscape" -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
@ -816,8 +829,11 @@ class PlayerFragment : BaseFragment() {
saveWatchPosition() saveWatchPosition()
nowPlayingNotification.destroy() nowPlayingNotification.destroy()
activity?.requestedOrientation = activity?.requestedOrientation =
if ((activity as MainActivity).autoRotationEnabled) ActivityInfo.SCREEN_ORIENTATION_USER if ((activity as MainActivity).autoRotationEnabled) {
else ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT ActivityInfo.SCREEN_ORIENTATION_USER
} else {
ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
}
} catch (e: Exception) { } catch (e: Exception) {
} }
} }
@ -1199,7 +1215,11 @@ class PlayerFragment : BaseFragment() {
// next and previous buttons // next and previous buttons
playerBinding.skipPrev.visibility = if ( playerBinding.skipPrev.visibility = if (
skipButtonsEnabled && Globals.playingQueue.indexOf(videoId!!) != 0 skipButtonsEnabled && Globals.playingQueue.indexOf(videoId!!) != 0
) View.VISIBLE else View.INVISIBLE ) {
View.VISIBLE
} else {
View.INVISIBLE
}
playerBinding.skipNext.visibility = if (skipButtonsEnabled) View.VISIBLE else View.INVISIBLE playerBinding.skipNext.visibility = if (skipButtonsEnabled) View.VISIBLE else View.INVISIBLE
playerBinding.skipPrev.setOnClickListener { playerBinding.skipPrev.setOnClickListener {
@ -1545,7 +1565,11 @@ class PlayerFragment : BaseFragment() {
playerBinding.exoTitle.visibility = playerBinding.exoTitle.visibility =
if (isLocked && if (isLocked &&
viewModel.isFullscreen.value == true viewModel.isFullscreen.value == true
) View.VISIBLE else View.INVISIBLE ) {
View.VISIBLE
} else {
View.INVISIBLE
}
// disable double tap to seek when the player is locked // disable double tap to seek when the player is locked
if (isLocked) { if (isLocked) {

View File

@ -61,8 +61,11 @@ class PlaylistFragment : BaseFragment() {
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
val response = try { val response = try {
// load locally stored playlists with the auth api // load locally stored playlists with the auth api
if (isOwner) RetrofitInstance.authApi.getPlaylist(playlistId!!) if (isOwner) {
else RetrofitInstance.api.getPlaylist(playlistId!!) RetrofitInstance.authApi.getPlaylist(playlistId!!)
} else {
RetrofitInstance.api.getPlaylist(playlistId!!)
}
} 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")
@ -163,13 +166,17 @@ class PlaylistFragment : BaseFragment() {
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
val response = try { val response = try {
// load locally stored playlists with the auth api // load locally stored playlists with the auth api
if (isOwner) RetrofitInstance.authApi.getPlaylistNextPage( if (isOwner) {
playlistId!!, RetrofitInstance.authApi.getPlaylistNextPage(
nextPage!!
) else RetrofitInstance.api.getPlaylistNextPage(
playlistId!!, playlistId!!,
nextPage!! nextPage!!
) )
} else {
RetrofitInstance.api.getPlaylistNextPage(
playlistId!!,
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")

View File

@ -56,8 +56,11 @@ class SearchFragment() : BaseFragment() {
// fetch the search or history // fetch the search or history
binding.historyEmpty.visibility = View.GONE binding.historyEmpty.visibility = View.GONE
binding.suggestionsRecycler.visibility = View.VISIBLE binding.suggestionsRecycler.visibility = View.VISIBLE
if (query == null || query == "") showHistory() if (query == null || query == "") {
else fetchSuggestions(query) showHistory()
} else {
fetchSuggestions(query)
}
} }
private fun fetchSuggestions(query: String) { private fun fetchSuggestions(query: String) {

View File

@ -11,6 +11,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.adapters.LegacySubscriptionAdapter
import com.github.libretube.adapters.SubscriptionChannelAdapter import com.github.libretube.adapters.SubscriptionChannelAdapter
import com.github.libretube.adapters.TrendingAdapter import com.github.libretube.adapters.TrendingAdapter
import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.RetrofitInstance
@ -125,10 +126,13 @@ class SubscriptionsFragment : BaseFragment() {
fun run() { fun run() {
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
feed = try { feed = try {
if (token != "") RetrofitInstance.authApi.getFeed(token) if (token != "") {
else RetrofitInstance.authApi.getUnauthenticatedFeed( RetrofitInstance.authApi.getFeed(token)
} else {
RetrofitInstance.authApi.getUnauthenticatedFeed(
SubscriptionHelper.getFormattedLocalSubscriptions() SubscriptionHelper.getFormattedLocalSubscriptions()
) )
}
} 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")
@ -175,10 +179,13 @@ class SubscriptionsFragment : BaseFragment() {
fun run() { fun run() {
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
val response = try { val response = try {
if (token != "") RetrofitInstance.authApi.subscriptions(token) if (token != "") {
else RetrofitInstance.authApi.unauthenticatedSubscriptions( RetrofitInstance.authApi.subscriptions(token)
} else {
RetrofitInstance.authApi.unauthenticatedSubscriptions(
SubscriptionHelper.getFormattedLocalSubscriptions() SubscriptionHelper.getFormattedLocalSubscriptions()
) )
}
} 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")
@ -191,7 +198,22 @@ class SubscriptionsFragment : BaseFragment() {
} }
if (response.isNotEmpty()) { if (response.isNotEmpty()) {
binding.subChannels.adapter = binding.subChannels.adapter =
if (PreferenceHelper.getBoolean(
PreferenceKeys.LEGACY_SUBSCRIPTIONS,
false
)
) {
binding.subChannels.layoutManager = GridLayoutManager(
context,
PreferenceHelper.getString(
PreferenceKeys.LEGACY_SUBSCRIPTIONS_COLUMNS,
"4"
).toInt()
)
LegacySubscriptionAdapter(response)
} else {
SubscriptionChannelAdapter(response.toMutableList()) 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()
} }

View File

@ -77,6 +77,14 @@ class AppearanceSettings : MaterialPreferenceFragment() {
} }
true true
} }
val legacySubscriptionView = findPreference<SwitchPreferenceCompat>(PreferenceKeys.LEGACY_SUBSCRIPTIONS)
val legacySubscriptionColumns = findPreference<ListPreference>(PreferenceKeys.LEGACY_SUBSCRIPTIONS_COLUMNS)
legacySubscriptionColumns?.isVisible = legacySubscriptionView?.isChecked!!
legacySubscriptionView.setOnPreferenceChangeListener { _, newValue ->
legacySubscriptionColumns?.isVisible = newValue as Boolean
true
}
} }
// remove material you from accent color option if not available // remove material you from accent color option if not available

View File

@ -89,8 +89,11 @@ class InstanceSettings : MaterialPreferenceFragment() {
authInstance.isVisible = newValue == true authInstance.isVisible = newValue == true
logout() logout()
// either use new auth url or the normal api url if auth instance disabled // either use new auth url or the normal api url if auth instance disabled
RetrofitInstance.authUrl = if (newValue == false) RetrofitInstance.url RetrofitInstance.authUrl = if (newValue == false) {
else authInstance.value RetrofitInstance.url
} else {
authInstance.value
}
RetrofitInstance.lazyMgr.reset() RetrofitInstance.lazyMgr.reset()
activity?.recreate() activity?.recreate()
true true
@ -144,9 +147,12 @@ class InstanceSettings : MaterialPreferenceFragment() {
val accessGranted = val accessGranted =
PermissionHelper.isStoragePermissionGranted(requireActivity()) PermissionHelper.isStoragePermissionGranted(requireActivity())
// import subscriptions // import subscriptions
if (accessGranted) getContent.launch("*/*") if (accessGranted) {
// request permissions if not granted getContent.launch("*/*")
else PermissionHelper.requestReadWrite(requireActivity()) } // request permissions if not granted
else {
PermissionHelper.requestReadWrite(requireActivity())
}
true true
} }

View File

@ -79,8 +79,11 @@ class MainSettings : MaterialPreferenceFragment() {
val update = findPreference<Preference>("update") val update = findPreference<Preference>("update")
// set the version of the update preference // set the version of the update preference
val versionString = if (BuildConfig.DEBUG) "${BuildConfig.VERSION_NAME} Debug" val versionString = if (BuildConfig.DEBUG) {
else getString(R.string.version, BuildConfig.VERSION_NAME) "${BuildConfig.VERSION_NAME} Debug"
} else {
getString(R.string.version, BuildConfig.VERSION_NAME)
}
update?.title = versionString update?.title = versionString
// checking for update: yes -> dialog, no -> snackBar // checking for update: yes -> dialog, no -> snackBar

View File

@ -31,6 +31,8 @@ object PreferenceKeys {
const val LABEL_VISIBILITY = "label_visibility" const val LABEL_VISIBILITY = "label_visibility"
const val HIDE_TRENDING_PAGE = "hide_trending_page" const val HIDE_TRENDING_PAGE = "hide_trending_page"
const val APP_ICON = "icon_change" const val APP_ICON = "icon_change"
const val LEGACY_SUBSCRIPTIONS = "legacy_subscriptions"
const val LEGACY_SUBSCRIPTIONS_COLUMNS = "legacy_subscriptions_columns"
/** /**
* Instance * Instance

View File

@ -53,9 +53,13 @@ class DownloadService : Service() {
videoUrl = intent.getStringExtra("videoUrl")!! videoUrl = intent.getStringExtra("videoUrl")!!
audioUrl = intent.getStringExtra("audioUrl")!! audioUrl = intent.getStringExtra("audioUrl")!!
downloadType = if (audioUrl != "") DownloadType.AUDIO downloadType = if (audioUrl != "") {
else if (videoUrl != "") DownloadType.VIDEO DownloadType.AUDIO
else DownloadType.NONE } else if (videoUrl != "") {
DownloadType.VIDEO
} else {
DownloadType.NONE
}
if (downloadType != DownloadType.NONE) { if (downloadType != DownloadType.NONE) {
downloadNotification(intent) downloadNotification(intent)
downloadManager() downloadManager()

View File

@ -23,13 +23,17 @@ class AutoPlayHelper(
return if (Globals.playingQueue.last() != currentVideoId) { return if (Globals.playingQueue.last() != currentVideoId) {
val currentVideoIndex = Globals.playingQueue.indexOf(currentVideoId) val currentVideoIndex = Globals.playingQueue.indexOf(currentVideoId)
Globals.playingQueue[currentVideoIndex + 1] Globals.playingQueue[currentVideoIndex + 1]
} else if (playlistId == null) getNextTrendingVideoId( } else if (playlistId == null) {
getNextTrendingVideoId(
currentVideoId, currentVideoId,
relatedStreams relatedStreams
) else getNextPlaylistVideoId( )
} else {
getNextPlaylistVideoId(
currentVideoId currentVideoId
) )
} }
}
/** /**
* get the id of the next related video * get the id of the next related video
@ -51,8 +55,11 @@ class AutoPlayHelper(
) )
) { ) {
nextStreamId = relatedStreams[index].url.toID() nextStreamId = relatedStreams[index].url.toID()
if (index + 1 < relatedStreams.size) index += 1 if (index + 1 < relatedStreams.size) {
else break index += 1
} else {
break
}
} }
return nextStreamId return nextStreamId
} }
@ -65,19 +72,26 @@ class AutoPlayHelper(
if (playlistStreamIds.contains(currentVideoId)) { if (playlistStreamIds.contains(currentVideoId)) {
val index = playlistStreamIds.indexOf(currentVideoId) val index = playlistStreamIds.indexOf(currentVideoId)
// check whether there's a next video // check whether there's a next video
return if (index + 1 < playlistStreamIds.size) playlistStreamIds[index + 1] return if (index + 1 < playlistStreamIds.size) {
else if (playlistNextPage == null) null playlistStreamIds[index + 1]
else getNextPlaylistVideoId(currentVideoId) } else if (playlistNextPage == null) {
null
} else {
getNextPlaylistVideoId(currentVideoId)
}
} else if (playlistStreamIds.isEmpty() || playlistNextPage != null) { } else if (playlistStreamIds.isEmpty() || playlistNextPage != null) {
// fetch the next page of the playlist // fetch the next page of the playlist
return withContext(Dispatchers.IO) { return withContext(Dispatchers.IO) {
// fetch the playlists or its nextPage's videos // fetch the playlists or its nextPage's videos
val playlist = val playlist =
if (playlistNextPage == null) RetrofitInstance.authApi.getPlaylist(playlistId!!) if (playlistNextPage == null) {
else RetrofitInstance.authApi.getPlaylistNextPage( RetrofitInstance.authApi.getPlaylist(playlistId!!)
} else {
RetrofitInstance.authApi.getPlaylistNextPage(
playlistId!!, playlistId!!,
playlistNextPage!! playlistNextPage!!
) )
}
// save the playlist urls to the list // save the playlist urls to the list
playlistStreamIds += playlist.relatedStreams!!.map { it.url.toID() } playlistStreamIds += playlist.relatedStreams!!.map { it.url.toID() }
// save playlistNextPage for usage if video is not contained // save playlistNextPage for usage if video is not contained
@ -98,6 +112,8 @@ class AutoPlayHelper(
return if (Globals.playingQueue.last() != currentVideoId) { return if (Globals.playingQueue.last() != currentVideoId) {
val currentVideoIndex = Globals.playingQueue.indexOf(currentVideoId) val currentVideoIndex = Globals.playingQueue.indexOf(currentVideoId)
Globals.playingQueue[currentVideoIndex + 1] Globals.playingQueue[currentVideoIndex + 1]
} else null } else {
null
}
} }
} }

View File

@ -66,11 +66,15 @@ class BackupHelper(
// decide for each preference which type it is and save it to the preferences // decide for each preference which type it is and save it to the preferences
for ((key, value) in entries) { for ((key, value) in entries) {
if (value is Boolean) editor.putBoolean(key, value) if (value is Boolean) {
else if (value is Float) editor.putFloat(key, value) editor.putBoolean(key, value)
else if (value is Int) editor.putInt(key, value) } else if (value is Float) {
else if (value is Long) editor.putLong(key, value) editor.putFloat(key, value)
else if (value is String) editor.putString(key, value) } else if (value is Int) {
editor.putInt(key, value)
} else if (value is Long) {
editor.putLong(key, value)
} else if (value is String) editor.putString(key, value)
} }
editor.commit() editor.commit()
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -34,7 +34,9 @@ abstract class DoubleTapListener : View.OnClickListener {
private val runnable = Runnable { private val runnable = Runnable {
if (!isSingleEvent || if (!isSingleEvent ||
SystemClock.elapsedRealtime() - timeStampLastDoubleClick < maximumTimeDifference SystemClock.elapsedRealtime() - timeStampLastDoubleClick < maximumTimeDifference
) return@Runnable ) {
return@Runnable
}
onSingleClick() onSingleClick()
} }
} }

View File

@ -99,10 +99,13 @@ class ImportHelper(
val mapper = ObjectMapper() val mapper = ObjectMapper()
val token = PreferenceHelper.getToken() val token = PreferenceHelper.getToken()
runBlocking { runBlocking {
val subs = if (token != "") RetrofitInstance.authApi.subscriptions(token) val subs = if (token != "") {
else RetrofitInstance.authApi.unauthenticatedSubscriptions( RetrofitInstance.authApi.subscriptions(token)
} else {
RetrofitInstance.authApi.unauthenticatedSubscriptions(
SubscriptionHelper.getFormattedLocalSubscriptions() SubscriptionHelper.getFormattedLocalSubscriptions()
) )
}
val newPipeChannels = mutableListOf<NewPipeSubscription>() val newPipeChannels = mutableListOf<NewPipeSubscription>()
subs.forEach { subs.forEach {
newPipeChannels += NewPipeSubscription( newPipeChannels += NewPipeSubscription(

View File

@ -11,8 +11,9 @@ object LocaleHelper {
fun updateLanguage(context: Context) { fun updateLanguage(context: Context) {
val languageName = PreferenceHelper.getString(PreferenceKeys.LANGUAGE, "sys") val languageName = PreferenceHelper.getString(PreferenceKeys.LANGUAGE, "sys")
if (languageName == "sys") updateLocaleConf(context, Locale.getDefault()) if (languageName == "sys") {
else if (languageName?.contains("-") == true) { updateLocaleConf(context, Locale.getDefault())
} else if (languageName?.contains("-") == true) {
val languageParts = languageName.split("-") val languageParts = languageName.split("-")
val locale = Locale( val locale = Locale(
languageParts[0], languageParts[0],

View File

@ -93,11 +93,14 @@ object NotificationHelper {
val token = PreferenceHelper.getToken() val token = PreferenceHelper.getToken()
runBlocking { runBlocking {
val task = async { val task = async {
if (token != "") RetrofitInstance.authApi.getFeed(token) if (token != "") {
else RetrofitInstance.authApi.getUnauthenticatedFeed( RetrofitInstance.authApi.getFeed(token)
} else {
RetrofitInstance.authApi.getUnauthenticatedFeed(
SubscriptionHelper.getFormattedLocalSubscriptions() SubscriptionHelper.getFormattedLocalSubscriptions()
) )
} }
}
// fetch the users feed // fetch the users feed
val videoFeed = try { val videoFeed = try {
task.await() task.await()
@ -110,8 +113,9 @@ object NotificationHelper {
val latestFeedStreamId = videoFeed[0].url.toID() val latestFeedStreamId = videoFeed[0].url.toID()
// first time notifications enabled // first time notifications enabled
if (lastSeenStreamId == "") PreferenceHelper.setLatestVideoId(lastSeenStreamId) if (lastSeenStreamId == "") {
else if (lastSeenStreamId != latestFeedStreamId) { PreferenceHelper.setLatestVideoId(lastSeenStreamId)
} else if (lastSeenStreamId != latestFeedStreamId) {
// get the index of the last user-seen video // get the index of the last user-seen video
var newStreamIndex = -1 var newStreamIndex = -1
videoFeed.forEachIndexed { index, stream -> videoFeed.forEachIndexed { index, stream ->

View File

@ -43,8 +43,11 @@ object ThemeHelper {
) { ) {
"my" -> { "my" -> {
applyDynamicColors(activity) applyDynamicColors(activity)
if (pureThemeEnabled) R.style.BaseTheme_Pure if (pureThemeEnabled) {
else R.style.BaseTheme R.style.BaseTheme_Pure
} else {
R.style.BaseTheme
}
} }
// set the theme, use the pure theme if enabled // set the theme, use the pure theme if enabled
"red" -> if (pureThemeEnabled) R.style.Theme_Red_Pure else R.style.Theme_Red "red" -> if (pureThemeEnabled) R.style.Theme_Red_Pure else R.style.Theme_Red
@ -85,8 +88,11 @@ object ThemeHelper {
// Disable Old Icon(s) // Disable Old Icon(s)
for (activityAlias in activityAliases) { for (activityAlias in activityAliases) {
val activityClass = "com.github.libretube." + val activityClass = "com.github.libretube." +
if (activityAlias == activityAliases[0]) "activities.MainActivity" // default icon/activity if (activityAlias == activityAliases[0]) {
else activityAlias "activities.MainActivity" // default icon/activity
} else {
activityAlias
}
// remove old icons // remove old icons
context.packageManager.setComponentEnabledSetting( context.packageManager.setComponentEnabledSetting(
@ -98,8 +104,11 @@ object ThemeHelper {
// set the class name for the activity alias // set the class name for the activity alias
val newLogoActivityClass = "com.github.libretube." + val newLogoActivityClass = "com.github.libretube." +
if (newLogoActivityAlias == activityAliases[0]) "activities.MainActivity" // default icon/activity if (newLogoActivityAlias == activityAliases[0]) {
else newLogoActivityAlias "activities.MainActivity" // default icon/activity
} else {
newLogoActivityAlias
}
// Enable New Icon // Enable New Icon
context.packageManager.setComponentEnabledSetting( context.packageManager.setComponentEnabledSetting(
ComponentName(context.packageName, newLogoActivityClass), ComponentName(context.packageName, newLogoActivityClass),

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:orientation="vertical"
android:paddingHorizontal="4dp"
android:paddingVertical="8dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/channel_avatar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center" />
<TextView
android:id="@+id/channel_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="end"
android:maxLines="1" />
</LinearLayout>

View File

@ -311,4 +311,5 @@
<string name="copied_to_clipboard">Copied to clipboard</string> <string name="copied_to_clipboard">Copied to clipboard</string>
<string name="open_copied">Open</string> <string name="open_copied">Open</string>
<string name="break_reminder_time">Minutes before being reminded</string> <string name="break_reminder_time">Minutes before being reminded</string>
<string name="legacy_subscriptions">Legacy subscriptions view</string>
</resources> </resources>

View File

@ -77,4 +77,23 @@
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory app:title="@string/misc">
<SwitchPreferenceCompat
app:defaultValue="false"
app:icon="@drawable/ic_list"
app:key="legacy_subscriptions"
app:title="@string/legacy_subscriptions" />
<ListPreference
android:entries="@array/grid"
android:entryValues="@array/grid"
app:defaultValue="3"
app:icon="@drawable/ic_grid"
app:isPreferenceVisible="false"
app:key="legacy_subscriptions_columns"
app:title="@string/grid" />
</PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>