Merge pull request #1069 from Bnyro/master

max image cache pref
This commit is contained in:
Bnyro 2022-08-15 10:48:02 +02:00 committed by GitHub
commit 7a8346584e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 197 additions and 108 deletions

View File

@ -9,7 +9,6 @@ import android.os.StrictMode
import android.os.StrictMode.VmPolicy import android.os.StrictMode.VmPolicy
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.ExistingPeriodicWorkPolicy
import coil.ImageLoader
import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import com.github.libretube.api.CronetHelper import com.github.libretube.api.CronetHelper
@ -19,8 +18,8 @@ import com.github.libretube.db.obj.WatchHistoryItem
import com.github.libretube.db.obj.WatchPosition import com.github.libretube.db.obj.WatchPosition
import com.github.libretube.preferences.PreferenceHelper import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys import com.github.libretube.preferences.PreferenceKeys
import com.github.libretube.util.ConnectionHelper
import com.github.libretube.util.ExceptionHandler import com.github.libretube.util.ExceptionHandler
import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NotificationHelper import com.github.libretube.util.NotificationHelper
class MyApp : Application() { class MyApp : Application() {
@ -93,9 +92,7 @@ class MyApp : Application() {
RetrofitInstance.url RetrofitInstance.url
} }
CronetHelper.initCronet(this) CronetHelper.initCronet(this)
ConnectionHelper.imageLoader = ImageLoader.Builder(this) ImageHelper.initializeImageLoader(this)
.callFactory(CronetHelper.callFactory)
.build()
} }
/** /**

View File

@ -36,8 +36,8 @@ import com.github.libretube.models.SearchViewModel
import com.github.libretube.preferences.PreferenceHelper import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys import com.github.libretube.preferences.PreferenceKeys
import com.github.libretube.services.ClosingService import com.github.libretube.services.ClosingService
import com.github.libretube.util.ConnectionHelper
import com.github.libretube.util.LocaleHelper import com.github.libretube.util.LocaleHelper
import com.github.libretube.util.NetworkHelper
import com.github.libretube.util.ThemeHelper import com.github.libretube.util.ThemeHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.elevation.SurfaceColors import com.google.android.material.elevation.SurfaceColors
@ -73,7 +73,7 @@ class MainActivity : BaseActivity() {
} }
// show noInternet Activity if no internet available on app startup // show noInternet Activity if no internet available on app startup
if (!ConnectionHelper.isNetworkAvailable(this)) { if (!NetworkHelper.isNetworkAvailable(this)) {
val noInternetIntent = Intent(this, NoInternetActivity::class.java) val noInternetIntent = Intent(this, NoInternetActivity::class.java)
startActivity(noInternetIntent) startActivity(noInternetIntent)
finish() finish()

View File

@ -6,7 +6,7 @@ import com.github.libretube.R
import com.github.libretube.databinding.ActivityNointernetBinding import com.github.libretube.databinding.ActivityNointernetBinding
import com.github.libretube.extensions.BaseActivity import com.github.libretube.extensions.BaseActivity
import com.github.libretube.extensions.showSnackBar import com.github.libretube.extensions.showSnackBar
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.NetworkHelper
import com.github.libretube.util.ThemeHelper import com.github.libretube.util.ThemeHelper
class NoInternetActivity : BaseActivity() { class NoInternetActivity : BaseActivity() {
@ -18,7 +18,7 @@ class NoInternetActivity : BaseActivity() {
binding = ActivityNointernetBinding.inflate(layoutInflater) binding = ActivityNointernetBinding.inflate(layoutInflater)
// retry button // retry button
binding.retryButton.setOnClickListener { binding.retryButton.setOnClickListener {
if (ConnectionHelper.isNetworkAvailable(this)) { if (NetworkHelper.isNetworkAvailable(this)) {
ThemeHelper.restartMainActivity(this) ThemeHelper.restartMainActivity(this)
} else { } else {
binding.root.showSnackBar(R.string.turnInternetOn) binding.root.showSnackBar(R.string.turnInternetOn)

View File

@ -8,7 +8,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.databinding.VideoRowBinding import com.github.libretube.databinding.VideoRowBinding
import com.github.libretube.dialogs.VideoOptionsDialog import com.github.libretube.dialogs.VideoOptionsDialog
import com.github.libretube.obj.StreamItem import com.github.libretube.obj.StreamItem
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.formatShort import com.github.libretube.util.formatShort
import com.github.libretube.util.setWatchProgressLength import com.github.libretube.util.setWatchProgressLength
@ -45,7 +45,7 @@ class ChannelAdapter(
DateUtils.getRelativeTimeSpanString(trending.uploaded!!) DateUtils.getRelativeTimeSpanString(trending.uploaded!!)
thumbnailDuration.text = thumbnailDuration.text =
DateUtils.formatElapsedTime(trending.duration!!) DateUtils.formatElapsedTime(trending.duration!!)
ConnectionHelper.loadImage(trending.thumbnail, thumbnail) ImageHelper.loadImage(trending.thumbnail, thumbnail)
root.setOnClickListener { root.setOnClickListener {
NavigationHelper.navigateVideo(root.context, trending.url) NavigationHelper.navigateVideo(root.context, trending.url)
} }

View File

@ -6,7 +6,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.databinding.ChapterColumnBinding import com.github.libretube.databinding.ChapterColumnBinding
import com.github.libretube.obj.ChapterSegment import com.github.libretube.obj.ChapterSegment
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.ThemeHelper import com.github.libretube.util.ThemeHelper
import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.ExoPlayer
@ -25,7 +25,7 @@ class ChaptersAdapter(
override fun onBindViewHolder(holder: ChaptersViewHolder, position: Int) { override fun onBindViewHolder(holder: ChaptersViewHolder, position: Int) {
val chapter = chapters[position] val chapter = chapters[position]
holder.binding.apply { holder.binding.apply {
ConnectionHelper.loadImage(chapter.image, chapterImage) ImageHelper.loadImage(chapter.image, chapterImage)
chapterTitle.text = chapter.title chapterTitle.text = chapter.title
if (selectedPosition == position) { if (selectedPosition == position) {

View File

@ -13,7 +13,7 @@ import com.github.libretube.databinding.CommentsRowBinding
import com.github.libretube.extensions.TAG import com.github.libretube.extensions.TAG
import com.github.libretube.obj.Comment import com.github.libretube.obj.Comment
import com.github.libretube.obj.CommentsPage import com.github.libretube.obj.CommentsPage
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.formatShort import com.github.libretube.util.formatShort
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -51,7 +51,7 @@ class CommentsAdapter(
"" + comment.commentedTime.toString() "" + comment.commentedTime.toString()
commentText.text = commentText.text =
comment.commentText.toString() comment.commentText.toString()
ConnectionHelper.loadImage(comment.thumbnail, commentorImage) ImageHelper.loadImage(comment.thumbnail, commentorImage)
likesTextView.text = likesTextView.text =
comment.likeCount?.toLong().formatShort() comment.likeCount?.toLong().formatShort()
if (comment.verified == true) { if (comment.verified == true) {

View File

@ -15,7 +15,7 @@ import com.github.libretube.extensions.setFormattedDuration
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.github.libretube.preferences.PreferenceHelper import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.setWatchProgressLength import com.github.libretube.util.setWatchProgressLength
import com.github.libretube.util.toID import com.github.libretube.util.toID
@ -54,7 +54,7 @@ class PlaylistAdapter(
playlistTitle.text = streamItem.title playlistTitle.text = streamItem.title
playlistDescription.text = streamItem.uploaderName playlistDescription.text = streamItem.uploaderName
thumbnailDuration.setFormattedDuration(streamItem.duration!!) thumbnailDuration.setFormattedDuration(streamItem.duration!!)
ConnectionHelper.loadImage(streamItem.thumbnail, playlistThumbnail) ImageHelper.loadImage(streamItem.thumbnail, playlistThumbnail)
root.setOnClickListener { root.setOnClickListener {
NavigationHelper.navigateVideo(root.context, streamItem.url, playlistId) NavigationHelper.navigateVideo(root.context, streamItem.url, playlistId)
} }

View File

@ -14,7 +14,7 @@ import com.github.libretube.extensions.TAG
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.github.libretube.preferences.PreferenceHelper import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper import com.github.libretube.util.NavigationHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -52,7 +52,7 @@ class PlaylistsAdapter(
playlistThumbnail.setImageResource(R.drawable.ic_empty_playlist) playlistThumbnail.setImageResource(R.drawable.ic_empty_playlist)
playlistThumbnail.setBackgroundColor(R.attr.colorSurface) playlistThumbnail.setBackgroundColor(R.attr.colorSurface)
} else { } else {
ConnectionHelper.loadImage(playlist.thumbnail, playlistThumbnail) ImageHelper.loadImage(playlist.thumbnail, playlistThumbnail)
} }
playlistTitle.text = playlist.name playlistTitle.text = playlist.name
deletePlaylist.setOnClickListener { deletePlaylist.setOnClickListener {

View File

@ -6,7 +6,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.databinding.RepliesRowBinding import com.github.libretube.databinding.RepliesRowBinding
import com.github.libretube.obj.Comment import com.github.libretube.obj.Comment
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.formatShort import com.github.libretube.util.formatShort
@ -40,7 +40,7 @@ class RepliesAdapter(
"" + reply.commentedTime.toString() "" + reply.commentedTime.toString()
commentText.text = commentText.text =
reply.commentText.toString() reply.commentText.toString()
ConnectionHelper.loadImage(reply.thumbnail, commentorImage) ImageHelper.loadImage(reply.thumbnail, commentorImage)
likesTextView.text = likesTextView.text =
reply.likeCount?.toLong().formatShort() reply.likeCount?.toLong().formatShort()
if (reply.verified == true) { if (reply.verified == true) {

View File

@ -14,7 +14,7 @@ import com.github.libretube.dialogs.PlaylistOptionsDialog
import com.github.libretube.dialogs.VideoOptionsDialog import com.github.libretube.dialogs.VideoOptionsDialog
import com.github.libretube.extensions.setFormattedDuration import com.github.libretube.extensions.setFormattedDuration
import com.github.libretube.obj.SearchItem import com.github.libretube.obj.SearchItem
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.formatShort import com.github.libretube.util.formatShort
import com.github.libretube.util.setWatchProgressLength import com.github.libretube.util.setWatchProgressLength
@ -79,9 +79,9 @@ class SearchAdapter(
private fun bindWatch(item: SearchItem, binding: VideoRowBinding) { private fun bindWatch(item: SearchItem, binding: VideoRowBinding) {
binding.apply { binding.apply {
ConnectionHelper.loadImage(item.thumbnail, thumbnail) ImageHelper.loadImage(item.thumbnail, thumbnail)
thumbnailDuration.setFormattedDuration(item.duration!!) thumbnailDuration.setFormattedDuration(item.duration!!)
ConnectionHelper.loadImage(item.uploaderAvatar, channelImage) ImageHelper.loadImage(item.uploaderAvatar, channelImage)
videoTitle.text = item.title videoTitle.text = item.title
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 ""
@ -110,7 +110,7 @@ class SearchAdapter(
private fun bindChannel(item: SearchItem, binding: ChannelRowBinding) { private fun bindChannel(item: SearchItem, binding: ChannelRowBinding) {
binding.apply { binding.apply {
ConnectionHelper.loadImage(item.thumbnail, searchChannelImage) ImageHelper.loadImage(item.thumbnail, searchChannelImage)
searchChannelName.text = item.name searchChannelName.text = item.name
searchViews.text = root.context.getString( searchViews.text = root.context.getString(
R.string.subscribers, R.string.subscribers,
@ -157,7 +157,7 @@ class SearchAdapter(
private fun bindPlaylist(item: SearchItem, binding: PlaylistSearchRowBinding) { private fun bindPlaylist(item: SearchItem, binding: PlaylistSearchRowBinding) {
binding.apply { binding.apply {
ConnectionHelper.loadImage(item.thumbnail, searchThumbnail) ImageHelper.loadImage(item.thumbnail, searchThumbnail)
if (item.videos?.toInt() != -1) searchPlaylistNumber.text = item.videos.toString() if (item.videos?.toInt() != -1) searchPlaylistNumber.text = item.videos.toString()
searchDescription.text = item.name searchDescription.text = item.name
searchName.text = item.uploaderName searchName.text = item.uploaderName

View File

@ -7,7 +7,7 @@ import com.github.libretube.R
import com.github.libretube.api.SubscriptionHelper import com.github.libretube.api.SubscriptionHelper
import com.github.libretube.databinding.ChannelSubscriptionRowBinding import com.github.libretube.databinding.ChannelSubscriptionRowBinding
import com.github.libretube.obj.Subscription import com.github.libretube.obj.Subscription
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.toID import com.github.libretube.util.toID
@ -31,7 +31,7 @@ class SubscriptionChannelAdapter(private val subscriptions: MutableList<Subscrip
holder.binding.apply { holder.binding.apply {
subscriptionChannelName.text = subscription.name subscriptionChannelName.text = subscription.name
ConnectionHelper.loadImage(subscription.avatar, subscriptionChannelImage) ImageHelper.loadImage(subscription.avatar, subscriptionChannelImage)
root.setOnClickListener { root.setOnClickListener {
NavigationHelper.navigateChannel(root.context, subscription.url) NavigationHelper.navigateChannel(root.context, subscription.url)
} }

View File

@ -9,7 +9,7 @@ import com.github.libretube.databinding.TrendingRowBinding
import com.github.libretube.dialogs.VideoOptionsDialog import com.github.libretube.dialogs.VideoOptionsDialog
import com.github.libretube.extensions.setFormattedDuration import com.github.libretube.extensions.setFormattedDuration
import com.github.libretube.obj.StreamItem import com.github.libretube.obj.StreamItem
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.formatShort import com.github.libretube.util.formatShort
import com.github.libretube.util.setWatchProgressLength import com.github.libretube.util.setWatchProgressLength
@ -52,8 +52,8 @@ class TrendingAdapter(
channelImage.setOnClickListener { channelImage.setOnClickListener {
NavigationHelper.navigateChannel(root.context, trending.uploaderUrl) NavigationHelper.navigateChannel(root.context, trending.uploaderUrl)
} }
ConnectionHelper.loadImage(trending.thumbnail, thumbnail) ImageHelper.loadImage(trending.thumbnail, thumbnail)
ConnectionHelper.loadImage(trending.uploaderAvatar, channelImage) ImageHelper.loadImage(trending.uploaderAvatar, channelImage)
root.setOnClickListener { root.setOnClickListener {
NavigationHelper.navigateVideo(root.context, trending.url) NavigationHelper.navigateVideo(root.context, trending.url)
} }

View File

@ -9,7 +9,7 @@ import com.github.libretube.db.DatabaseHelper
import com.github.libretube.db.obj.WatchHistoryItem import com.github.libretube.db.obj.WatchHistoryItem
import com.github.libretube.dialogs.VideoOptionsDialog import com.github.libretube.dialogs.VideoOptionsDialog
import com.github.libretube.extensions.setFormattedDuration import com.github.libretube.extensions.setFormattedDuration
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NavigationHelper import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.setWatchProgressLength import com.github.libretube.util.setWatchProgressLength
@ -38,8 +38,8 @@ class WatchHistoryAdapter(
channelName.text = video.uploader channelName.text = video.uploader
videoInfo.text = video.uploadDate videoInfo.text = video.uploadDate
thumbnailDuration.setFormattedDuration(video.duration!!) thumbnailDuration.setFormattedDuration(video.duration!!)
ConnectionHelper.loadImage(video.thumbnailUrl, thumbnail) ImageHelper.loadImage(video.thumbnailUrl, thumbnail)
ConnectionHelper.loadImage(video.uploaderAvatar, channelImage) ImageHelper.loadImage(video.uploaderAvatar, channelImage)
channelImage.setOnClickListener { channelImage.setOnClickListener {
NavigationHelper.navigateChannel(root.context, video.uploaderUrl) NavigationHelper.navigateChannel(root.context, video.uploaderUrl)

View File

@ -1,5 +1,6 @@
package com.github.libretube.db package com.github.libretube.db
import com.github.libretube.db.obj.SearchHistoryItem
import com.github.libretube.db.obj.WatchHistoryItem import com.github.libretube.db.obj.WatchHistoryItem
import com.github.libretube.db.obj.WatchPosition import com.github.libretube.db.obj.WatchPosition
import com.github.libretube.obj.Streams import com.github.libretube.obj.Streams
@ -59,4 +60,18 @@ object DatabaseHelper {
) )
}.start() }.start()
} }
fun addToSearchHistory(searchHistoryItem: SearchHistoryItem) {
Thread {
DatabaseHolder.db.searchHistoryDao().insertAll(searchHistoryItem)
val maxHistorySize = 20
// delete the first watch history entry if the limit is reached
val searchHistory = DatabaseHolder.db.searchHistoryDao().getAll()
if (searchHistory.size > maxHistorySize) {
DatabaseHolder.db.searchHistoryDao()
.delete(searchHistory.first())
}
}.start()
}
} }

View File

@ -72,7 +72,8 @@ 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 = index if (playlist.id == viewModel.lastSelectedPlaylistId) selectionIndex =
index
} }
binding.playlistsSpinner.setSelection(selectionIndex) binding.playlistsSpinner.setSelection(selectionIndex)
} }

View File

@ -14,7 +14,7 @@ import com.github.libretube.api.SubscriptionHelper
import com.github.libretube.databinding.FragmentChannelBinding import com.github.libretube.databinding.FragmentChannelBinding
import com.github.libretube.extensions.BaseFragment import com.github.libretube.extensions.BaseFragment
import com.github.libretube.extensions.TAG import com.github.libretube.extensions.TAG
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.formatShort import com.github.libretube.util.formatShort
import com.github.libretube.util.toID import com.github.libretube.util.toID
import retrofit2.HttpException import retrofit2.HttpException
@ -146,8 +146,8 @@ class ChannelFragment : BaseFragment() {
binding.channelDescription.text = response.description?.trim() binding.channelDescription.text = response.description?.trim()
} }
ConnectionHelper.loadImage(response.bannerUrl, binding.channelBanner) ImageHelper.loadImage(response.bannerUrl, binding.channelBanner)
ConnectionHelper.loadImage(response.avatarUrl, binding.channelImage) ImageHelper.loadImage(response.avatarUrl, binding.channelImage)
// recyclerview of the videos by the channel // recyclerview of the videos by the channel
channelAdapter = ChannelAdapter( channelAdapter = ChannelAdapter(

View File

@ -68,8 +68,12 @@ class LibraryFragment : BaseFragment() {
} }
if (token != "") { if (token != "") {
binding.boogh.setImageResource(R.drawable.ic_list)
binding.textLike.text = getString(R.string.emptyList)
binding.loginOrRegister.visibility = View.GONE binding.loginOrRegister.visibility = View.GONE
fetchPlaylists() fetchPlaylists()
binding.playlistRefresh.isEnabled = true binding.playlistRefresh.isEnabled = true
binding.playlistRefresh.setOnRefreshListener { binding.playlistRefresh.setOnRefreshListener {
fetchPlaylists() fetchPlaylists()
@ -123,7 +127,6 @@ class LibraryFragment : BaseFragment() {
playlistsAdapter.registerAdapterDataObserver(object : playlistsAdapter.registerAdapterDataObserver(object :
RecyclerView.AdapterDataObserver() { RecyclerView.AdapterDataObserver() {
override fun onChanged() { override fun onChanged() {
Log.e(TAG(), playlistsAdapter.itemCount.toString())
if (playlistsAdapter.itemCount == 0) { if (playlistsAdapter.itemCount == 0) {
binding.loginOrRegister.visibility = View.VISIBLE binding.loginOrRegister.visibility = View.VISIBLE
} }
@ -135,8 +138,6 @@ class LibraryFragment : BaseFragment() {
} else { } else {
runOnUiThread { runOnUiThread {
binding.loginOrRegister.visibility = View.VISIBLE binding.loginOrRegister.visibility = View.VISIBLE
binding.boogh.setImageResource(R.drawable.ic_list)
binding.textLike.text = getString(R.string.emptyList)
} }
} }
} }

View File

@ -65,7 +65,7 @@ import com.github.libretube.preferences.PreferenceKeys
import com.github.libretube.services.BackgroundMode import com.github.libretube.services.BackgroundMode
import com.github.libretube.util.AutoPlayHelper import com.github.libretube.util.AutoPlayHelper
import com.github.libretube.util.BackgroundHelper import com.github.libretube.util.BackgroundHelper
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NowPlayingNotification import com.github.libretube.util.NowPlayingNotification
import com.github.libretube.util.PlayerHelper import com.github.libretube.util.PlayerHelper
import com.github.libretube.util.formatShort import com.github.libretube.util.formatShort
@ -1017,7 +1017,7 @@ class PlayerFragment : BaseFragment() {
textLike.text = response.likes.formatShort() textLike.text = response.likes.formatShort()
textDislike.text = response.dislikes.formatShort() textDislike.text = response.dislikes.formatShort()
ConnectionHelper.loadImage(response.uploaderAvatar, binding.playerChannelImage) ImageHelper.loadImage(response.uploaderAvatar, binding.playerChannelImage)
playerChannelName.text = response.uploader playerChannelName.text = response.uploader
titleTextView.text = response.title titleTextView.text = response.title

View File

@ -11,11 +11,10 @@ import com.github.libretube.R
import com.github.libretube.adapters.SearchAdapter import com.github.libretube.adapters.SearchAdapter
import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.RetrofitInstance
import com.github.libretube.databinding.FragmentSearchResultBinding import com.github.libretube.databinding.FragmentSearchResultBinding
import com.github.libretube.db.DatabaseHolder import com.github.libretube.db.DatabaseHelper
import com.github.libretube.db.obj.SearchHistoryItem import com.github.libretube.db.obj.SearchHistoryItem
import com.github.libretube.extensions.BaseFragment import com.github.libretube.extensions.BaseFragment
import com.github.libretube.extensions.TAG import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.await
import com.github.libretube.preferences.PreferenceHelper import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys import com.github.libretube.preferences.PreferenceKeys
import com.github.libretube.util.hideKeyboard import com.github.libretube.util.hideKeyboard
@ -135,13 +134,11 @@ class SearchResultFragment : BaseFragment() {
val searchHistoryEnabled = val searchHistoryEnabled =
PreferenceHelper.getBoolean(PreferenceKeys.SEARCH_HISTORY_TOGGLE, true) PreferenceHelper.getBoolean(PreferenceKeys.SEARCH_HISTORY_TOGGLE, true)
if (searchHistoryEnabled && query != "") { if (searchHistoryEnabled && query != "") {
Thread { DatabaseHelper.addToSearchHistory(
DatabaseHolder.db.searchHistoryDao().insertAll( SearchHistoryItem(
SearchHistoryItem( query = query
query = query
)
) )
}.await() )
} }
} }
} }

View File

@ -4,10 +4,12 @@ import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.preference.ListPreference
import androidx.preference.Preference import androidx.preference.Preference
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.activities.SettingsActivity import com.github.libretube.activities.SettingsActivity
import com.github.libretube.util.BackupHelper import com.github.libretube.util.BackupHelper
import com.github.libretube.util.ImageHelper
import com.github.libretube.views.MaterialPreferenceFragment import com.github.libretube.views.MaterialPreferenceFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
@ -40,6 +42,12 @@ class AdvancedSettings : MaterialPreferenceFragment() {
val settingsActivity = activity as SettingsActivity val settingsActivity = activity as SettingsActivity
settingsActivity.changeTopBarText(getString(R.string.advanced)) settingsActivity.changeTopBarText(getString(R.string.advanced))
val maxImageCache = findPreference<ListPreference>(PreferenceKeys.MAX_IMAGE_CACHE)
maxImageCache?.setOnPreferenceChangeListener { _, _ ->
ImageHelper.initializeImageLoader(requireContext())
true
}
val resetSettings = findPreference<Preference>(PreferenceKeys.RESET_SETTINGS) val resetSettings = findPreference<Preference>(PreferenceKeys.RESET_SETTINGS)
resetSettings?.setOnPreferenceClickListener { resetSettings?.setOnPreferenceClickListener {
showResetDialog() showResetDialog()

View File

@ -9,7 +9,7 @@ import com.github.libretube.activities.SettingsActivity
import com.github.libretube.dialogs.UpdateDialog import com.github.libretube.dialogs.UpdateDialog
import com.github.libretube.extensions.showSnackBar import com.github.libretube.extensions.showSnackBar
import com.github.libretube.update.UpdateChecker import com.github.libretube.update.UpdateChecker
import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.NetworkHelper
import com.github.libretube.views.MaterialPreferenceFragment import com.github.libretube.views.MaterialPreferenceFragment
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -86,7 +86,7 @@ class MainSettings : MaterialPreferenceFragment() {
// checking for update: yes -> dialog, no -> snackBar // checking for update: yes -> dialog, no -> snackBar
update?.setOnPreferenceClickListener { update?.setOnPreferenceClickListener {
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
if (!ConnectionHelper.isNetworkAvailable(requireContext())) { if (!NetworkHelper.isNetworkAvailable(requireContext())) {
(activity as SettingsActivity).binding.root.showSnackBar(R.string.unknown_error) (activity as SettingsActivity).binding.root.showSnackBar(R.string.unknown_error)
return@launch return@launch
} }

View File

@ -39,6 +39,10 @@ object PreferenceHelper {
return settings.getBoolean(key, defValue) return settings.getBoolean(key, defValue)
} }
fun getInt(key: String?, defValue: Int): Int {
return settings.getInt(key, defValue)
}
fun clearPreferences() { fun clearPreferences() {
editor.clear().apply() editor.clear().apply()
} }

View File

@ -92,6 +92,7 @@ object PreferenceKeys {
* Advanced * Advanced
*/ */
const val DATA_SAVER_MODE = "data_saver_mode" const val DATA_SAVER_MODE = "data_saver_mode"
const val MAX_IMAGE_CACHE = ""
const val RESET_SETTINGS = "reset_settings" const val RESET_SETTINGS = "reset_settings"
const val CLEAR_SEARCH_HISTORY = "clear_search_history" const val CLEAR_SEARCH_HISTORY = "clear_search_history"
const val CLEAR_WATCH_HISTORY = "clear_watch_history" const val CLEAR_WATCH_HISTORY = "clear_watch_history"

View File

@ -0,0 +1,46 @@
package com.github.libretube.util
import android.content.Context
import android.widget.ImageView
import coil.ImageLoader
import coil.disk.DiskCache
import coil.load
import com.github.libretube.api.CronetHelper
import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys
object ImageHelper {
lateinit var imageLoader: ImageLoader
/**
* Initialize the image loader
*/
fun initializeImageLoader(context: Context) {
val maxImageCacheSize = PreferenceHelper.getInt(
PreferenceKeys.MAX_IMAGE_CACHE,
128
)
val diskCache = DiskCache.Builder()
.directory(context.filesDir.resolve("coil"))
.maxSizeBytes(maxImageCacheSize * 1024 * 1024L)
.build()
imageLoader = ImageLoader.Builder(context)
.callFactory(CronetHelper.callFactory)
.diskCache(diskCache)
.build()
}
/**
* load an image from a url into an imageView
*/
fun loadImage(url: String?, target: ImageView) {
// only load the image if the data saver mode is disabled
val dataSaverModeEnabled = PreferenceHelper.getBoolean(
PreferenceKeys.DATA_SAVER_MODE,
false
)
if (!dataSaverModeEnabled) target.load(url, imageLoader)
}
}

View File

@ -2,15 +2,11 @@ package com.github.libretube.util
import android.content.Context import android.content.Context
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.widget.ImageView
import coil.ImageLoader
import coil.load
import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys
object ConnectionHelper {
lateinit var imageLoader: ImageLoader
object NetworkHelper {
/**
* Detect whether network is available
*/
fun isNetworkAvailable(context: Context): Boolean { fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager = val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
@ -40,14 +36,4 @@ object ConnectionHelper {
return connectivityManager.activeNetworkInfo?.isConnected ?: false return connectivityManager.activeNetworkInfo?.isConnected ?: false
} }
// load an image from a url into an imageView
fun loadImage(url: String?, target: ImageView) {
// only load the image if the data saver mode is disabled
val dataSaverModeEnabled = PreferenceHelper.getBoolean(
PreferenceKeys.DATA_SAVER_MODE,
false
)
if (!dataSaverModeEnabled) target.load(url, imageLoader)
}
} }

View File

@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="512"
android:viewportHeight="512">
<path
android:fillColor="#FF000000"
android:pathData="M256,428C203.65,428 144.61,416.39 98.07,397 81,389.81 66.38,378.18 54.43,369A4,4 0,0 0,48 372.18v12.58c0,28.07 23.49,53.22 66.14,70.82C152.29,471.33 202.67,480 256,480s103.7,-8.67 141.86,-24.42C440.51,438 464,412.83 464,384.76V372.18a4,4 0,0 0,-6.43 -3.18C445.62,378.17 431,389.81 413.92,397 367.38,416.39 308.35,428 256,428Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M464,126.51c-0.81,-27.65 -24.18,-52.4 -66,-69.85C359.74,40.76 309.34,32 256,32S152.26,40.76 114.09,56.66c-41.78,17.41 -65.15,42.11 -66,69.69L48,144c0,6.41 5.2,16.48 14.63,24.73 11.13,9.73 27.65,19.33 47.78,27.73C153.24,214.36 207.67,225 256,225s102.76,-10.68 145.59,-28.58c20.13,-8.4 36.65,-18 47.78,-27.73C458.8,160.49 464,150.42 464,144Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M413.92,226C367.39,245.43 308.35,257 256,257S144.61,245.43 98.07,226C81,218.85 66.38,207.21 54.43,198A4,4 0,0 0,48 201.22V232c0,6.41 5.2,14.48 14.63,22.73 11.13,9.74 27.65,19.33 47.78,27.74C153.24,300.34 207.67,311 256,311s102.76,-10.68 145.59,-28.57c20.13,-8.41 36.65,-18 47.78,-27.74C458.8,246.47 464,238.41 464,232V201.22a4,4 0,0 0,-6.43 -3.18C445.62,207.21 431,218.85 413.92,226Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M413.92,312C367.38,331.41 308.35,343 256,343S144.61,331.41 98.07,312C81,304.83 66.38,293.19 54.43,284A4,4 0,0 0,48 287.2V317c0,6.41 5.2,14.47 14.62,22.71 11.13,9.74 27.66,19.33 47.79,27.74C153.24,385.32 207.66,396 256,396s102.76,-10.68 145.59,-28.57c20.13,-8.41 36.65,-18 47.78,-27.74C458.8,331.44 464,323.37 464,317V287.2a4,4 0,0 0,-6.43 -3.18C445.62,293.19 431,304.83 413.92,312Z"/>
</vector>

View File

@ -1,11 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" style="@style/ItemRow">
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal">
<de.hdodenhof.circleimageview.CircleImageView <de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/search_channel_image" android:id="@+id/search_channel_image"

View File

@ -4,11 +4,9 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="8dp" android:background="?android:attr/selectableItemBackground"
android:layout_marginTop="4dp" android:paddingHorizontal="8dp"
android:layout_marginRight="8dp" android:paddingVertical="4dp">
android:layout_marginBottom="4dp"
android:background="?android:attr/selectableItemBackground">
<de.hdodenhof.circleimageview.CircleImageView <de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/subscription_channel_image" android:id="@+id/subscription_channel_image"

View File

@ -80,7 +80,7 @@
android:id="@+id/search_recycler" android:id="@+id/search_recycler"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="10dp" /> android:layout_marginVertical="10dp" />
</LinearLayout> </LinearLayout>

View File

@ -30,7 +30,6 @@
android:id="@+id/watchHistoryRecView" android:id="@+id/watchHistoryRecView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="8dp"
android:nestedScrollingEnabled="false" android:nestedScrollingEnabled="false"
android:visibility="gone" /> android:visibility="gone" />

View File

@ -2,12 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/video_search" style="@style/ItemRow">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_marginBottom="16dp"
android:background="?android:attr/selectableItemBackground">
<androidx.constraintlayout.widget.Guideline <androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline" android:id="@+id/guideline"

View File

@ -2,10 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" style="@style/ItemRow">
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:background="?android:attr/selectableItemBackground">
<androidx.constraintlayout.widget.Guideline <androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline" android:id="@+id/guideline"

View File

@ -3,11 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/playlist" android:id="@+id/playlist"
android:layout_width="match_parent" style="@style/ItemRow">
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_marginBottom="16dp"
android:background="?android:attr/selectableItemBackground">
<androidx.constraintlayout.widget.Guideline <androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline" android:id="@+id/guideline"

View File

@ -2,11 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/video_search" style="@style/ItemRow">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:background="?android:attr/selectableItemBackground">
<androidx.constraintlayout.widget.Guideline <androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline" android:id="@+id/guideline"

View File

@ -2,11 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/video_search" style="@style/ItemRow">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:background="?android:attr/selectableItemBackground">
<androidx.constraintlayout.widget.Guideline <androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline" android:id="@+id/guideline"

View File

@ -858,4 +858,22 @@
<item>fill</item> <item>fill</item>
</string-array> </string-array>
<string-array name="cacheSize">
<item>16MB</item>
<item>32MB</item>
<item>64MB</item>
<item>128MB</item>
<item>256MB</item>
<item>512MB</item>
</string-array>
<string-array name="cacheSizeValues">
<item>16</item>
<item>32</item>
<item>64</item>
<item>128</item>
<item>256</item>
<item>512</item>
</string-array>
</resources> </resources>

View File

@ -314,4 +314,5 @@
<string name="backup">Backup</string> <string name="backup">Backup</string>
<string name="picture_in_picture">Picture in Picture</string> <string name="picture_in_picture">Picture in Picture</string>
<string name="player_resize_mode">Resize mode</string> <string name="player_resize_mode">Resize mode</string>
<string name="maximum_image_cache">Max image cache size</string>
</resources> </resources>

View File

@ -162,4 +162,17 @@
</style> </style>
<style name="ItemRow">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:paddingLeft">6dp</item>
<item name="android:paddingRight">6dp</item>
<item name="android:paddingTop">8dp</item>
<item name="android:paddingBottom">8dp</item>
<item name="android:background">?attr/selectableItemBackground</item>
<item name="android:orientation">horizontal</item>
</style>
</resources> </resources>

View File

@ -40,6 +40,15 @@
app:key="data_saver_mode" app:key="data_saver_mode"
app:title="@string/data_saver_mode" /> app:title="@string/data_saver_mode" />
<ListPreference
android:entries="@array/cacheSize"
android:entryValues="@array/cacheSizeValues"
android:icon="@drawable/ic_cache"
app:defaultValue="128"
app:key="image_cache_size"
app:title="@string/maximum_image_cache"
app:useSimpleSummaryProvider="true" />
<Preference <Preference
android:icon="@drawable/ic_reset" android:icon="@drawable/ic_reset"
app:key="reset_settings" app:key="reset_settings"