From 166a21f74eacd239be86aa1f4e60380edc571b12 Mon Sep 17 00:00:00 2001 From: LagradOst <11805592+LagradOst@users.noreply.github.com> Date: Fri, 14 Jul 2023 02:28:49 +0200 Subject: [PATCH] more views -> viewbinding --- .../lagradost/cloudstream3/MainActivity.kt | 1 + .../cloudstream3/ui/EasterEggMonke.kt | 21 +-- .../cloudstream3/ui/WebviewFragment.kt | 33 ++-- .../ui/download/DownloadChildAdapter.kt | 57 +++---- .../ui/download/DownloadHeaderAdapter.kt | 60 +++---- .../ui/home/HomeParentItemAdapter.kt | 25 --- .../ui/library/LoadingPosterAdapter.kt | 8 - .../ui/player/FullScreenPlayer.kt | 6 - .../cloudstream3/ui/player/GeneratorPlayer.kt | 2 +- .../ui/player/PlayerEpisodeAdapter.kt | 158 ------------------ .../cloudstream3/ui/search/SearchAdaptor.kt | 31 ++-- .../cloudstream3/ui/search/SearchFragment.kt | 1 + .../ui/settings/SettingsAccount.kt | 104 ++++++------ .../ui/settings/SettingsFragment.kt | 77 +++++---- .../ui/settings/SettingsGeneral.kt | 27 +-- .../ui/settings/SettingsUpdates.kt | 16 +- .../settings/extensions/ExtensionsFragment.kt | 95 ++++++----- .../ui/settings/extensions/RepoAdapter.kt | 72 ++++++-- .../ui/settings/testing/TestFragment.kt | 120 ++++++------- 19 files changed, 412 insertions(+), 502 deletions(-) delete mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerEpisodeAdapter.kt diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index d054f504..f409c10f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -743,6 +743,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) updateTv() + if (isTvSettings()) { setContentView(R.layout.activity_main_tv) } else { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/EasterEggMonke.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/EasterEggMonke.kt index 556ebd34..c7041776 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/EasterEggMonke.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/EasterEggMonke.kt @@ -16,14 +16,16 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.AppCompatImageView import androidx.core.view.isVisible import com.lagradost.cloudstream3.R -import kotlinx.android.synthetic.main.activity_easter_egg_monke.* -import java.util.* +import com.lagradost.cloudstream3.databinding.ActivityEasterEggMonkeBinding class EasterEggMonke : AppCompatActivity() { + lateinit var binding : ActivityEasterEggMonkeBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_easter_egg_monke) + + binding = ActivityEasterEggMonkeBinding.inflate(layoutInflater) + setContentView(binding.root) val handler = Handler(mainLooper) lateinit var runnable: Runnable @@ -32,15 +34,14 @@ class EasterEggMonke : AppCompatActivity() { handler.postDelayed(runnable, 300) } handler.postDelayed(runnable, 1000) - } private fun shower() { - val containerW = frame.width - val containerH = frame.height - var starW: Float = monke.width.toFloat() - var starH: Float = monke.height.toFloat() + val containerW = binding.frame.width + val containerH = binding.frame.height + var starW: Float = binding.monke.width.toFloat() + var starH: Float = binding.monke.height.toFloat() val newStar = AppCompatImageView(this) val idx = (monkeys.size * Math.random()).toInt() @@ -48,7 +49,7 @@ class EasterEggMonke : AppCompatActivity() { newStar.isVisible = true newStar.layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT) - frame.addView(newStar) + binding.frame.addView(newStar) newStar.scaleX = Math.random().toFloat() * 1.5f + newStar.scaleX newStar.scaleY = newStar.scaleX @@ -70,7 +71,7 @@ class EasterEggMonke : AppCompatActivity() { set.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { - frame.removeView(newStar) + binding.frame.removeView(newStar) } }) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/WebviewFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/WebviewFragment.kt index 19e24f74..9ed58e2c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/WebviewFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/WebviewFragment.kt @@ -12,20 +12,23 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.navigation.fragment.findNavController import com.lagradost.cloudstream3.MainActivity -import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.USER_AGENT +import com.lagradost.cloudstream3.databinding.FragmentWebviewBinding import com.lagradost.cloudstream3.network.WebViewResolver import com.lagradost.cloudstream3.utils.AppUtils.loadRepository -import kotlinx.android.synthetic.main.fragment_webview.* + class WebviewFragment : Fragment() { + + var binding: FragmentWebviewBinding? = null + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val url = arguments?.getString(WEBVIEW_URL) ?: "".also { findNavController().popBackStack() } - web_view.webViewClient = object : WebViewClient() { + binding?.webView?.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading( view: WebView?, request: WebResourceRequest? @@ -40,24 +43,28 @@ class WebviewFragment : Fragment() { return super.shouldOverrideUrlLoading(view, request) } } + binding?.webView?.apply { + WebViewResolver.webViewUserAgent = settings.userAgentString - WebViewResolver.webViewUserAgent = web_view.settings.userAgentString - - web_view.addJavascriptInterface(RepoApi(activity), "RepoApi") - web_view.settings.javaScriptEnabled = true - web_view.settings.userAgentString = USER_AGENT - web_view.settings.domStorageEnabled = true + addJavascriptInterface(RepoApi(activity), "RepoApi") + settings.javaScriptEnabled = true + settings.userAgentString = USER_AGENT + settings.domStorageEnabled = true // WebView.setWebContentsDebuggingEnabled(true) - web_view.loadUrl(url) + loadUrl(url) + } + } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { + ): View { + val localBinding = FragmentWebviewBinding.inflate(inflater, container, false) + binding = localBinding // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_webview, container, false) + return localBinding.root//inflater.inflate(R.layout.fragment_webview, container, false) } companion object { @@ -70,7 +77,7 @@ class WebviewFragment : Fragment() { private class RepoApi(val activity: FragmentActivity?) { @JavascriptInterface - fun installRepo(repoUrl: String) { + fun installRepo(repoUrl: String) { activity?.loadRepository(repoUrl) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildAdapter.kt index a541171b..1a3e2db3 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildAdapter.kt @@ -3,18 +3,13 @@ package com.lagradost.cloudstream3.ui.download import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView -import androidx.cardview.widget.CardView -import androidx.core.widget.ContentLoadingProgressBar import androidx.recyclerview.widget.RecyclerView -import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.databinding.DownloadChildEpisodeBinding import com.lagradost.cloudstream3.utils.AppUtils.getNameFull import com.lagradost.cloudstream3.utils.DataStoreHelper.fixVisual import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos import com.lagradost.cloudstream3.utils.VideoDownloadHelper -import kotlinx.android.synthetic.main.download_child_episode.view.* -import java.util.* +import java.util.Collections const val DOWNLOAD_ACTION_PLAY_FILE = 0 const val DOWNLOAD_ACTION_DELETE_FILE = 1 @@ -68,7 +63,7 @@ class DownloadChildAdapter( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return DownloadChildViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.download_child_episode, parent, false), + DownloadChildEpisodeBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickCallback ) } @@ -88,17 +83,17 @@ class DownloadChildAdapter( class DownloadChildViewHolder constructor( - itemView: View, + val binding: DownloadChildEpisodeBinding, private val clickCallback: (DownloadClickEvent) -> Unit, - ) : RecyclerView.ViewHolder(itemView), DownloadButtonViewHolder { + ) : RecyclerView.ViewHolder(binding.root), DownloadButtonViewHolder { override var downloadButton = EasyDownloadButton() - private val title: TextView = itemView.download_child_episode_text + /*private val title: TextView = itemView.download_child_episode_text private val extraInfo: TextView = itemView.download_child_episode_text_extra private val holder: CardView = itemView.download_child_episode_holder private val progressBar: ContentLoadingProgressBar = itemView.download_child_episode_progress private val progressBarDownload: ContentLoadingProgressBar = itemView.download_child_episode_progress_downloaded - private val downloadImage: ImageView = itemView.download_child_episode_download + private val downloadImage: ImageView = itemView.download_child_episode_download*/ private var localCard: VisualDownloadChildCached? = null @@ -107,29 +102,35 @@ class DownloadChildAdapter( val d = card.data val posDur = getViewPos(d.id) - if (posDur != null) { - val visualPos = posDur.fixVisual() - progressBar.max = (visualPos.duration / 1000).toInt() - progressBar.progress = (visualPos.position / 1000).toInt() - progressBar.visibility = View.VISIBLE - } else { - progressBar.visibility = View.GONE + binding.downloadChildEpisodeProgress.apply { + if (posDur != null) { + val visualPos = posDur.fixVisual() + max = (visualPos.duration / 1000).toInt() + progress = (visualPos.position / 1000).toInt() + visibility = View.VISIBLE + } else { + visibility = View.GONE + } + } + + + binding.downloadChildEpisodeText.apply { + text = context.getNameFull(d.name, d.episode, d.season) + isSelected = true // is needed for text repeating } - title.text = title.context.getNameFull(d.name, d.episode, d.season) - title.isSelected = true // is needed for text repeating downloadButton.setUpButton( card.currentBytes, card.totalBytes, - progressBarDownload, - downloadImage, - extraInfo, + binding.downloadChildEpisodeProgressDownloaded, + binding.downloadChildEpisodeDownload, + binding.downloadChildEpisodeTextExtra, card.data, clickCallback ) - holder.setOnClickListener { + binding.downloadChildEpisodeHolder.setOnClickListener { clickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, d)) } } @@ -141,9 +142,9 @@ class DownloadChildAdapter( downloadButton.setUpButton( card.currentBytes, card.totalBytes, - progressBarDownload, - downloadImage, - extraInfo, + binding.downloadChildEpisodeProgressDownloaded, + binding.downloadChildEpisodeDownload, + binding.downloadChildEpisodeTextExtra, card.data, clickCallback ) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt index 29bb303a..1634009b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt @@ -5,16 +5,12 @@ import android.text.format.Formatter.formatShortFileSize import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView -import androidx.cardview.widget.CardView -import androidx.core.widget.ContentLoadingProgressBar import androidx.recyclerview.widget.RecyclerView import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.databinding.DownloadHeaderEpisodeBinding import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.utils.UIHelper.setImage import com.lagradost.cloudstream3.utils.VideoDownloadHelper -import kotlinx.android.synthetic.main.download_header_episode.view.* import java.util.* data class VisualDownloadHeaderCached( @@ -66,7 +62,7 @@ class DownloadHeaderAdapter( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return DownloadHeaderViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.download_header_episode, parent, false), + DownloadHeaderEpisodeBinding.inflate(LayoutInflater.from(parent.context),parent,false), clickCallback, movieClickCallback ) @@ -87,20 +83,20 @@ class DownloadHeaderAdapter( class DownloadHeaderViewHolder constructor( - itemView: View, + val binding: DownloadHeaderEpisodeBinding, private val clickCallback: (DownloadHeaderClickEvent) -> Unit, private val movieClickCallback: (DownloadClickEvent) -> Unit, - ) : RecyclerView.ViewHolder(itemView), DownloadButtonViewHolder { + ) : RecyclerView.ViewHolder(binding.root), DownloadButtonViewHolder { override var downloadButton = EasyDownloadButton() - private val poster: ImageView? = itemView.download_header_poster + /*private val poster: ImageView? = itemView.download_header_poster private val title: TextView = itemView.download_header_title private val extraInfo: TextView = itemView.download_header_info private val holder: CardView = itemView.episode_holder private val downloadBar: ContentLoadingProgressBar = itemView.download_header_progress_downloaded private val downloadImage: ImageView = itemView.download_header_episode_download - private val normalImage: ImageView = itemView.download_header_goto_child + private val normalImage: ImageView = itemView.download_header_goto_child*/ private var localCard: VisualDownloadHeaderCached? = null @SuppressLint("SetTextI18n") @@ -108,19 +104,24 @@ class DownloadHeaderAdapter( localCard = card val d = card.data - poster?.setImage(d.poster) - poster?.setOnClickListener { - clickCallback.invoke(DownloadHeaderClickEvent(1, d)) + binding.downloadHeaderPoster.apply { + setImage(d.poster) + setOnClickListener { + clickCallback.invoke(DownloadHeaderClickEvent(1, d)) + } } - title.text = d.name + binding.apply { + + binding.downloadHeaderTitle.text = d.name val mbString = formatShortFileSize(itemView.context, card.totalBytes) //val isMovie = d.type.isMovieType() if (card.child != null) { - downloadBar.visibility = View.VISIBLE - downloadImage.visibility = View.VISIBLE - normalImage.visibility = View.GONE + downloadHeaderProgressDownloaded.visibility = View.VISIBLE + + downloadHeaderEpisodeDownload.visibility = View.VISIBLE + binding.downloadHeaderGotoChild.visibility = View.GONE /*setUpButton( card.currentBytes, card.totalBytes, @@ -131,34 +132,35 @@ class DownloadHeaderAdapter( movieClickCallback )*/ - holder.setOnClickListener { + episodeHolder.setOnClickListener { movieClickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, card.child)) } } else { - downloadBar.visibility = View.GONE - downloadImage.visibility = View.GONE - normalImage.visibility = View.VISIBLE + downloadHeaderProgressDownloaded.visibility = View.GONE + downloadHeaderEpisodeDownload.visibility = View.GONE + binding.downloadHeaderGotoChild.visibility = View.VISIBLE try { - extraInfo.text = - extraInfo.context.getString(R.string.extra_info_format).format( + downloadHeaderInfo.text = + downloadHeaderInfo.context.getString(R.string.extra_info_format).format( card.totalDownloads, - if (card.totalDownloads == 1) extraInfo.context.getString(R.string.episode) else extraInfo.context.getString( + if (card.totalDownloads == 1) downloadHeaderInfo.context.getString(R.string.episode) else downloadHeaderInfo.context.getString( R.string.episodes ), mbString ) } catch (t : Throwable) { // you probably formatted incorrectly - extraInfo.text = "Error" + downloadHeaderInfo.text = "Error" logError(t) } - holder.setOnClickListener { + episodeHolder.setOnClickListener { clickCallback.invoke(DownloadHeaderClickEvent(0, d)) } } + } } override fun reattachDownloadButton() { @@ -168,9 +170,9 @@ class DownloadHeaderAdapter( downloadButton.setUpButton( card.currentBytes, card.totalBytes, - downloadBar, - downloadImage, - extraInfo, + binding.downloadHeaderProgressDownloaded, + binding.downloadHeaderEpisodeDownload, + binding.downloadHeaderInfo, card.child, movieClickCallback ) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt index 58c6dbe0..7ce9e67d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt @@ -3,49 +3,24 @@ package com.lagradost.cloudstream3.ui.home import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.FrameLayout -import android.widget.LinearLayout import android.widget.TextView -import androidx.core.content.ContextCompat -import androidx.core.view.isGone -import androidx.core.view.isVisible import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListUpdateCallback import androidx.recyclerview.widget.RecyclerView -import androidx.transition.ChangeBounds -import androidx.transition.TransitionManager -import androidx.viewpager2.widget.ViewPager2 -import com.google.android.material.chip.Chip -import com.google.android.material.chip.ChipDrawable -import com.lagradost.cloudstream3.APIHolder.getId -import com.lagradost.cloudstream3.AcraApplication.Companion.getActivity import com.lagradost.cloudstream3.HomePageList import com.lagradost.cloudstream3.LoadResponse import com.lagradost.cloudstream3.R -import com.lagradost.cloudstream3.SearchResponse -import com.lagradost.cloudstream3.mvvm.Resource -import com.lagradost.cloudstream3.ui.WatchType -import com.lagradost.cloudstream3.ui.result.LinearListLayout -import com.lagradost.cloudstream3.ui.result.ResultViewModel2 -import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST import com.lagradost.cloudstream3.ui.result.setLinearListLayout -import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_LOAD import com.lagradost.cloudstream3.ui.search.SearchClickCallback import com.lagradost.cloudstream3.ui.search.SearchFragment.Companion.filterSearchResponse import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings import com.lagradost.cloudstream3.utils.AppUtils.isRecyclerScrollable -import com.lagradost.cloudstream3.utils.AppUtils.loadResult -import com.lagradost.cloudstream3.utils.DataStoreHelper -import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog -import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarView import kotlinx.android.synthetic.main.activity_main_tv.* import kotlinx.android.synthetic.main.activity_main_tv.view.* import kotlinx.android.synthetic.main.fragment_home.* import kotlinx.android.synthetic.main.fragment_home.view.* import kotlinx.android.synthetic.main.fragment_home_head_tv.* import kotlinx.android.synthetic.main.fragment_home_head_tv.view.* -import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_preview -import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_preview_viewpager import kotlinx.android.synthetic.main.homepage_parent.view.* class LoadClickCallback( diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/library/LoadingPosterAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/library/LoadingPosterAdapter.kt index a637133b..160fbe2b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/library/LoadingPosterAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/library/LoadingPosterAdapter.kt @@ -5,15 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter -import android.widget.FrameLayout -import android.widget.LinearLayout -import android.widget.ListPopupWindow.MATCH_PARENT -import android.widget.RelativeLayout import com.lagradost.cloudstream3.R -import com.lagradost.cloudstream3.utils.UIHelper.toPx -import kotlinx.android.synthetic.main.loading_poster_dynamic.view.* -import kotlin.math.roundToInt -import kotlin.math.sqrt class LoadingPosterAdapter(context: Context, private val itemCount: Int) : BaseAdapter() { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt index 9ff1c52d..37fb0373 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt @@ -97,12 +97,6 @@ open class FullScreenPlayer : AbstractPlayerFragment() { protected var isShowing = false protected var isLocked = false - //private var episodes: List = listOf() - protected fun setEpisodes(ep: List) { - //hasEpisodes = ep.size > 1 // if has 2 episodes or more because you dont want to switch to your current episode - //(player_episode_list?.adapter as? PlayerEpisodeAdapter?)?.updateList(ep) - } - protected var hasEpisodes = false private set //protected val hasEpisodes diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt index fd29d998..4f29468c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt @@ -163,7 +163,7 @@ class GeneratorPlayer : FullScreenPlayer() { currentSelectedLink = link currentMeta = viewModel.getMeta() nextMeta = viewModel.getNextMeta() - setEpisodes(viewModel.getAllMeta() ?: emptyList()) + // setEpisodes(viewModel.getAllMeta() ?: emptyList()) isActive = true setPlayerDimen(null) setTitle() diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerEpisodeAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerEpisodeAdapter.kt deleted file mode 100644 index cfe27a30..00000000 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerEpisodeAdapter.kt +++ /dev/null @@ -1,158 +0,0 @@ -package com.lagradost.cloudstream3.ui.player - -import android.annotation.SuppressLint -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView -import androidx.core.view.isGone -import androidx.core.view.isVisible -import androidx.core.widget.ContentLoadingProgressBar -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.button.MaterialButton -import com.lagradost.cloudstream3.R -import com.lagradost.cloudstream3.ui.result.ResultEpisode -import com.lagradost.cloudstream3.ui.result.getDisplayPosition -import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings -import com.lagradost.cloudstream3.utils.AppUtils.html -import com.lagradost.cloudstream3.utils.UIHelper.setImage -import kotlinx.android.synthetic.main.player_episodes_large.view.episode_holder_large -import kotlinx.android.synthetic.main.player_episodes_large.view.episode_progress -import kotlinx.android.synthetic.main.player_episodes_small.view.episode_holder -import kotlinx.android.synthetic.main.result_episode_large.view.* - - -data class PlayerEpisodeClickEvent(val action: Int, val data: Any) - -class PlayerEpisodeAdapter( - private val items: MutableList = mutableListOf(), - private val clickCallback: (PlayerEpisodeClickEvent) -> Unit, -) : RecyclerView.Adapter() { - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - return PlayerEpisodeCardViewHolder( - LayoutInflater.from(parent.context) - .inflate(R.layout.player_episodes, parent, false), - clickCallback, - ) - } - - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - println("HOLDER $holder $position") - - when (holder) { - is PlayerEpisodeCardViewHolder -> { - holder.bind(items[position]) - } - } - } - - override fun getItemCount(): Int { - return items.size - } - - fun updateList(newList: List) { - println("Updated list $newList") - val diffResult = DiffUtil.calculateDiff(EpisodeDiffCallback(this.items, newList)) - items.clear() - items.addAll(newList) - - diffResult.dispatchUpdatesTo(this) - } - - class PlayerEpisodeCardViewHolder - constructor( - itemView: View, - private val clickCallback: (PlayerEpisodeClickEvent) -> Unit, - ) : RecyclerView.ViewHolder(itemView) { - @SuppressLint("SetTextI18n") - fun bind(card: Any) { - if (card is ResultEpisode) { - val (parentView, otherView) = if (card.poster == null) { - itemView.episode_holder to itemView.episode_holder_large - } else { - itemView.episode_holder_large to itemView.episode_holder - } - - val episodeText: TextView? = parentView.episode_text - val episodeFiller: MaterialButton? = parentView.episode_filler - val episodeRating: TextView? = parentView.episode_rating - val episodeDescript: TextView? = parentView.episode_descript - val episodeProgress: ContentLoadingProgressBar? = parentView.episode_progress - val episodePoster: ImageView? = parentView.episode_poster - - parentView.isVisible = true - otherView.isVisible = false - - - episodeText?.apply { - val name = - if (card.name == null) "${context.getString(R.string.episode)} ${card.episode}" else "${card.episode}. ${card.name}" - - text = name - isSelected = true - } - - episodeFiller?.isVisible = card.isFiller == true - - val displayPos = card.getDisplayPosition() - episodeProgress?.max = (card.duration / 1000).toInt() - episodeProgress?.progress = (displayPos / 1000).toInt() - episodeProgress?.isVisible = displayPos > 0L - episodePoster?.isVisible = episodePoster?.setImage(card.poster) == true - - if (card.rating != null) { - episodeRating?.text = episodeRating?.context?.getString(R.string.rated_format) - ?.format(card.rating.toFloat() / 10f) - } else { - episodeRating?.text = "" - } - - episodeRating?.isGone = episodeRating?.text.isNullOrBlank() - - episodeDescript?.apply { - text = card.description.html() - isGone = text.isNullOrBlank() - //setOnClickListener { - // clickCallback.invoke(PlayerEpisodeClickEvent(ACTION_SHOW_DESCRIPTION, card)) - //} - } - - parentView.setOnClickListener { - clickCallback.invoke(PlayerEpisodeClickEvent(0, card)) - } - - if (isTrueTvSettings()) { - parentView.isFocusable = true - parentView.isFocusableInTouchMode = true - parentView.touchscreenBlocksFocus = false - } - } - } - } -} - -class EpisodeDiffCallback( - private val oldList: List, - private val newList: List -) : - DiffUtil.Callback() { - override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { - val a = oldList[oldItemPosition] - val b = newList[newItemPosition] - return if (a is ResultEpisode && b is ResultEpisode) { - a.id == b.id - } else { - a == b - } - } - - override fun getOldListSize() = oldList.size - - override fun getNewListSize() = newList.size - - override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) = - oldList[oldItemPosition] == newList[newItemPosition] -} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt index 7fdd6e1d..233614dd 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt @@ -4,16 +4,15 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.FrameLayout -import android.widget.ImageView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import com.lagradost.cloudstream3.R +import androidx.viewbinding.ViewBinding import com.lagradost.cloudstream3.SearchResponse +import com.lagradost.cloudstream3.databinding.SearchResultGridBinding +import com.lagradost.cloudstream3.databinding.SearchResultGridExpandedBinding import com.lagradost.cloudstream3.ui.AutofitRecyclerView -import com.lagradost.cloudstream3.utils.Coroutines.main import com.lagradost.cloudstream3.utils.UIHelper.IsBottomLayout import com.lagradost.cloudstream3.utils.UIHelper.toPx -import kotlinx.android.synthetic.main.search_result_compact.view.* import kotlin.math.roundToInt /** Click */ @@ -39,10 +38,23 @@ class SearchAdapter( var hasNext: Boolean = false override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + + val layout = - if (parent.context.IsBottomLayout()) R.layout.search_result_grid_expanded else R.layout.search_result_grid + if (parent.context.IsBottomLayout()) SearchResultGridExpandedBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) else SearchResultGridBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) //R.layout.search_result_grid_expanded else R.layout.search_result_grid + + + return CardViewHolder( - LayoutInflater.from(parent.context).inflate(layout, parent, false), + layout, clickCallback, resView ) @@ -73,12 +85,11 @@ class SearchAdapter( class CardViewHolder constructor( - itemView: View, + val binding: ViewBinding, private val clickCallback: (SearchClickCallback) -> Unit, resView: AutofitRecyclerView ) : - RecyclerView.ViewHolder(itemView) { - private val cardView: ImageView = itemView.imageView + RecyclerView.ViewHolder(binding.root) { private val compactView = false//itemView.context.getGridIsCompact() private val coverHeight: Int = @@ -86,7 +97,7 @@ class SearchAdapter( fun bind(card: SearchResponse, position: Int) { if (!compactView) { - cardView.apply { + binding.root.apply { layoutParams = FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, coverHeight diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt index e0f67d4a..a11dab25 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt @@ -104,6 +104,7 @@ class SearchFragment : Fragment() { val layout = if (isTvSettings()) R.layout.fragment_search_tv else R.layout.fragment_search val root = inflater.inflate(layout, container, false) + // TODO TRYCATCH binding = FragmentSearchBinding.bind(root) return root diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsAccount.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsAccount.kt index acf715b3..a0166409 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsAccount.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsAccount.kt @@ -15,6 +15,9 @@ import androidx.recyclerview.widget.RecyclerView import com.lagradost.cloudstream3.AcraApplication.Companion.openBrowser import com.lagradost.cloudstream3.CommonActivity.showToast import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.databinding.AccountManagmentBinding +import com.lagradost.cloudstream3.databinding.AccountSwitchBinding +import com.lagradost.cloudstream3.databinding.AddAccountInputBinding import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.syncproviders.AccountManager import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.aniListApi @@ -31,9 +34,6 @@ import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard import com.lagradost.cloudstream3.utils.UIHelper.setImage -import kotlinx.android.synthetic.main.account_managment.* -import kotlinx.android.synthetic.main.account_switch.* -import kotlinx.android.synthetic.main.add_account_input.* class SettingsAccount : PreferenceFragmentCompat() { companion object { @@ -43,15 +43,18 @@ class SettingsAccount : PreferenceFragmentCompat() { api: AccountManager, info: AuthAPI.LoginInfo ) { + if (activity == null) return + val binding: AccountManagmentBinding = + AccountManagmentBinding.inflate(activity.layoutInflater, null, false) val builder = - AlertDialog.Builder(activity ?: return, R.style.AlertDialogCustom) - .setView(R.layout.account_managment) + AlertDialog.Builder(activity, R.style.AlertDialogCustom) + .setView(binding.root) val dialog = builder.show() - dialog.account_main_profile_picture_holder?.isVisible = - dialog.account_main_profile_picture?.setImage(info.profilePicture) == true + binding.accountMainProfilePictureHolder.isVisible = + binding.accountMainProfilePicture.setImage(info.profilePicture) - dialog.account_logout?.setOnClickListener { + binding.accountLogout.setOnClickListener { api.logOut() dialog.dismissSafe(activity) } @@ -60,26 +63,28 @@ class SettingsAccount : PreferenceFragmentCompat() { dialog.findViewById(R.id.account_name)?.text = it } - dialog.account_site?.text = api.name - dialog.account_switch_account?.setOnClickListener { + binding.accountSite.text = api.name + binding.accountSwitchAccount.setOnClickListener { dialog.dismissSafe(activity) showAccountSwitch(activity, api) } if (isTvSettings()) { - dialog.account_switch_account?.requestFocus() + binding.accountSwitchAccount.requestFocus() } } - fun showAccountSwitch(activity: FragmentActivity, api: AccountManager) { + private fun showAccountSwitch(activity: FragmentActivity, api: AccountManager) { val accounts = api.getAccounts() ?: return + val binding: AccountSwitchBinding = + AccountSwitchBinding.inflate(activity.layoutInflater, null, false) val builder = AlertDialog.Builder(activity, R.style.AlertDialogCustom) - .setView(R.layout.account_switch) + .setView(binding.root) val dialog = builder.show() - dialog.account_add?.setOnClickListener { + binding.accountAdd.setOnClickListener { addAccount(activity, api) dialog?.dismissSafe(activity) } @@ -111,17 +116,21 @@ class SettingsAccount : PreferenceFragmentCompat() { is OAuth2API -> { api.authenticate(activity) } + is InAppAuthAPI -> { + if (activity == null) return + val binding: AddAccountInputBinding = + AddAccountInputBinding.inflate(activity.layoutInflater, null, false) val builder = - AlertDialog.Builder(activity ?: return, R.style.AlertDialogCustom) - .setView(R.layout.add_account_input) + AlertDialog.Builder(activity, R.style.AlertDialogCustom) + .setView(binding.root) val dialog = builder.show() - val visibilityMap = mapOf( - dialog.login_email_input to api.requiresEmail, - dialog.login_password_input to api.requiresPassword, - dialog.login_server_input to api.requiresServer, - dialog.login_username_input to api.requiresUsername + val visibilityMap = listOf( + binding.loginEmailInput to api.requiresEmail, + binding.loginPasswordInput to api.requiresPassword, + binding.loginServerInput to api.requiresServer, + binding.loginUsernameInput to api.requiresUsername ) if (isTvSettings()) { @@ -145,12 +154,12 @@ class SettingsAccount : PreferenceFragmentCompat() { } } - dialog.login_email_input?.isVisible = api.requiresEmail - dialog.login_password_input?.isVisible = api.requiresPassword - dialog.login_server_input?.isVisible = api.requiresServer - dialog.login_username_input?.isVisible = api.requiresUsername - dialog.create_account?.isGone = api.createAccountUrl.isNullOrBlank() - dialog.create_account?.setOnClickListener { + binding.loginEmailInput.isVisible = api.requiresEmail + binding.loginPasswordInput.isVisible = api.requiresPassword + binding.loginServerInput.isVisible = api.requiresServer + binding.loginUsernameInput.isVisible = api.requiresUsername + binding.createAccount.isGone = api.createAccountUrl.isNullOrBlank() + binding.createAccount.setOnClickListener { openBrowser( api.createAccountUrl ?: return@setOnClickListener, activity @@ -159,43 +168,43 @@ class SettingsAccount : PreferenceFragmentCompat() { } val displayedItems = listOf( - dialog.login_username_input, - dialog.login_email_input, - dialog.login_server_input, - dialog.login_password_input + binding.loginUsernameInput, + binding.loginEmailInput, + binding.loginServerInput, + binding.loginPasswordInput ).filter { it.isVisible } displayedItems.foldRight(displayedItems.firstOrNull()) { item, previous -> - item?.id?.let { previous?.nextFocusDownId = it } - previous?.id?.let { item?.nextFocusUpId = it } + item.id.let { previous?.nextFocusDownId = it } + previous?.id?.let { item.nextFocusUpId = it } item } displayedItems.firstOrNull()?.let { - dialog.create_account?.nextFocusDownId = it.id - it.nextFocusUpId = dialog.create_account.id + binding.createAccount.nextFocusDownId = it.id + it.nextFocusUpId = binding.createAccount.id } - dialog.apply_btt?.id?.let { + binding.applyBtt.id.let { displayedItems.lastOrNull()?.nextFocusDownId = it } - dialog.text1?.text = api.name + binding.text1.text = api.name if (api.storesPasswordInPlainText) { api.getLatestLoginData()?.let { data -> - dialog.login_email_input?.setText(data.email ?: "") - dialog.login_server_input?.setText(data.server ?: "") - dialog.login_username_input?.setText(data.username ?: "") - dialog.login_password_input?.setText(data.password ?: "") + binding.loginEmailInput.setText(data.email ?: "") + binding.loginServerInput.setText(data.server ?: "") + binding.loginUsernameInput.setText(data.username ?: "") + binding.loginPasswordInput.setText(data.password ?: "") } } - dialog.apply_btt?.setOnClickListener { + binding.applyBtt.setOnClickListener { val loginData = InAppAuthAPI.LoginData( - username = if (api.requiresUsername) dialog.login_username_input?.text?.toString() else null, - password = if (api.requiresPassword) dialog.login_password_input?.text?.toString() else null, - email = if (api.requiresEmail) dialog.login_email_input?.text?.toString() else null, - server = if (api.requiresServer) dialog.login_server_input?.text?.toString() else null, + username = if (api.requiresUsername) binding.loginUsernameInput.text?.toString() else null, + password = if (api.requiresPassword) binding.loginPasswordInput.text?.toString() else null, + email = if (api.requiresEmail) binding.loginEmailInput.text?.toString() else null, + server = if (api.requiresServer) binding.loginServerInput.text?.toString() else null, ) ioSafe { val isSuccessful = try { @@ -220,10 +229,11 @@ class SettingsAccount : PreferenceFragmentCompat() { } dialog.dismissSafe(activity) } - dialog.cancel_btt?.setOnClickListener { + binding.cancelBtt.setOnClickListener { dialog.dismissSafe(activity) } } + else -> { throw NotImplementedError("You are trying to add an account that has an unknown login method") } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt index 453f93be..85afc048 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt @@ -14,7 +14,9 @@ import androidx.fragment.app.Fragment import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceManager +import com.google.android.material.appbar.MaterialToolbar import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.databinding.MainSettingsBinding import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.accountManagers import com.lagradost.cloudstream3.ui.home.HomeFragment @@ -22,16 +24,14 @@ import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar import com.lagradost.cloudstream3.utils.UIHelper.navigate import com.lagradost.cloudstream3.utils.UIHelper.setImage import com.lagradost.cloudstream3.utils.UIHelper.toPx -import kotlinx.android.synthetic.main.main_settings.* -import kotlinx.android.synthetic.main.standard_toolbar.* import java.io.File class SettingsFragment : Fragment() { companion object { var beneneCount = 0 - private var isTv : Boolean = false - private var isTrueTv : Boolean = false + private var isTv: Boolean = false + private var isTrueTv: Boolean = false fun PreferenceFragmentCompat?.getPref(id: Int): Preference? { if (this == null) return null @@ -55,26 +55,30 @@ class SettingsFragment : Fragment() { fun Fragment?.setUpToolbar(title: String) { if (this == null) return - settings_toolbar?.apply { + val settingsToolbar = view?.findViewById(R.id.settings_toolbar) ?: return + + settingsToolbar.apply { setTitle(title) setNavigationIcon(R.drawable.ic_baseline_arrow_back_24) setNavigationOnClickListener { activity?.onBackPressed() } } - fixPaddingStatusbar(settings_toolbar) + fixPaddingStatusbar(settingsToolbar) } fun Fragment?.setUpToolbar(@StringRes title: Int) { if (this == null) return - settings_toolbar?.apply { + val settingsToolbar = view?.findViewById(R.id.settings_toolbar) ?: return + + settingsToolbar.apply { setTitle(title) setNavigationIcon(R.drawable.ic_baseline_arrow_back_24) setNavigationOnClickListener { activity?.onBackPressed() } } - fixPaddingStatusbar(settings_toolbar) + fixPaddingStatusbar(settingsToolbar) } fun getFolderSize(dir: File): Long { @@ -139,12 +143,21 @@ class SettingsFragment : Fragment() { } } + override fun onDestroyView() { + binding = null + super.onDestroyView() + } + + var binding: MainSettingsBinding? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, - ): View? { - return inflater.inflate(R.layout.main_settings, container, false) + ): View { + val localBinding = MainSettingsBinding.inflate(inflater, container, false) + binding = localBinding + return localBinding.root + //return inflater.inflate(R.layout.main_settings, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -157,36 +170,34 @@ class SettingsFragment : Fragment() { for (syncApi in accountManagers) { val login = syncApi.loginInfo() val pic = login?.profilePicture ?: continue - if (settings_profile_pic?.setImage( + if (binding?.settingsProfilePic?.setImage( pic, errorImageDrawable = HomeFragment.errorProfilePic ) == true ) { - settings_profile_text?.text = login.name - settings_profile?.isVisible = true + binding?.settingsProfileText?.text = login.name + binding?.settingsProfile?.isVisible = true break } } - - listOf( - Pair(settings_general, R.id.action_navigation_settings_to_navigation_settings_general), - Pair(settings_player, R.id.action_navigation_settings_to_navigation_settings_player), - Pair(settings_credits, R.id.action_navigation_settings_to_navigation_settings_account), - Pair(settings_ui, R.id.action_navigation_settings_to_navigation_settings_ui), - Pair(settings_providers, R.id.action_navigation_settings_to_navigation_settings_providers), - Pair(settings_updates, R.id.action_navigation_settings_to_navigation_settings_updates), - Pair( - settings_extensions, - R.id.action_navigation_settings_to_navigation_settings_extensions - ), - ).forEach { (view, navigationId) -> - view?.apply { - setOnClickListener { - navigate(navigationId) - } - if (isTrueTv) { - isFocusable = true - isFocusableInTouchMode = true + binding?.apply { + listOf( + settingsGeneral to R.id.action_navigation_settings_to_navigation_settings_general, + settingsPlayer to R.id.action_navigation_settings_to_navigation_settings_player, + settingsCredits to R.id.action_navigation_settings_to_navigation_settings_account, + settingsUi to R.id.action_navigation_settings_to_navigation_settings_ui, + settingsProviders to R.id.action_navigation_settings_to_navigation_settings_providers, + settingsUpdates to R.id.action_navigation_settings_to_navigation_settings_updates, + settingsExtensions to R.id.action_navigation_settings_to_navigation_settings_extensions, + ).forEach { (view, navigationId) -> + view.apply { + setOnClickListener { + navigate(navigationId) + } + if (isTrueTv) { + isFocusable = true + isFocusableInTouchMode = true + } } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsGeneral.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsGeneral.kt index ee262eec..ef194b57 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsGeneral.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsGeneral.kt @@ -22,6 +22,8 @@ import com.lagradost.cloudstream3.CommonActivity import com.lagradost.cloudstream3.CommonActivity.showToast import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.databinding.AddRemoveSitesBinding +import com.lagradost.cloudstream3.databinding.AddSiteInputBinding import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.normalSafeApiCall import com.lagradost.cloudstream3.network.initClient @@ -38,8 +40,6 @@ import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard import com.lagradost.cloudstream3.utils.USER_PROVIDER_API import com.lagradost.cloudstream3.utils.VideoDownloadManager import com.lagradost.cloudstream3.utils.VideoDownloadManager.getBasePath -import kotlinx.android.synthetic.main.add_remove_sites.* -import kotlinx.android.synthetic.main.add_site_input.* import java.io.File fun getCurrentLocale(context: Context): String { @@ -197,18 +197,20 @@ class SettingsGeneral : PreferenceFragmentCompat() { {}) { selection -> val provider = providers.getOrNull(selection) ?: return@showDialog + val binding : AddSiteInputBinding = AddSiteInputBinding.inflate(layoutInflater,null,false) + val builder = AlertDialog.Builder(context ?: return@showDialog, R.style.AlertDialogCustom) - .setView(R.layout.add_site_input) + .setView(binding.root) val dialog = builder.create() dialog.show() - dialog.text2?.text = provider.name - dialog.apply_btt?.setOnClickListener { - val name = dialog.site_name_input?.text?.toString() - val url = dialog.site_url_input?.text?.toString() - val lang = dialog.site_lang_input?.text?.toString() + binding.text2.text = provider.name + binding.applyBtt.setOnClickListener { + val name = binding.siteNameInput.text?.toString() + val url = binding.siteUrlInput.text?.toString() + val lang = binding.siteLangInput.text?.toString() val realLang = if (lang.isNullOrBlank()) provider.lang else lang if (url.isNullOrBlank() || name.isNullOrBlank() || realLang.length != 2) { showToast(activity, R.string.error_invalid_data, Toast.LENGTH_SHORT) @@ -222,7 +224,7 @@ class SettingsGeneral : PreferenceFragmentCompat() { dialog.dismissSafe(activity) } - dialog.cancel_btt?.setOnClickListener { + binding.cancelBtt.setOnClickListener { dialog.dismissSafe(activity) } } @@ -242,18 +244,19 @@ class SettingsGeneral : PreferenceFragmentCompat() { } fun showAddOrDelete() { + val binding : AddRemoveSitesBinding = AddRemoveSitesBinding.inflate(layoutInflater,null,false) val builder = AlertDialog.Builder(context ?: return, R.style.AlertDialogCustom) - .setView(R.layout.add_remove_sites) + .setView(binding.root) val dialog = builder.create() dialog.show() - dialog.add_site?.setOnClickListener { + binding.addSite.setOnClickListener { showAdd() dialog.dismissSafe(activity) } - dialog.remove_site?.setOnClickListener { + binding.removeSite.setOnClickListener { showDelete() dialog.dismissSafe(activity) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsUpdates.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsUpdates.kt index f9ac3fee..4208f965 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsUpdates.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsUpdates.kt @@ -13,6 +13,7 @@ import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceManager import com.lagradost.cloudstream3.CommonActivity.showToast import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.databinding.LogcatBinding import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setPaddingBottom @@ -25,7 +26,6 @@ import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard import com.lagradost.cloudstream3.utils.VideoDownloadManager -import kotlinx.android.synthetic.main.logcat.* import okhttp3.internal.closeQuietly import java.io.BufferedReader import java.io.InputStreamReader @@ -60,7 +60,9 @@ class SettingsUpdates : PreferenceFragmentCompat() { getPref(R.string.show_logcat_key)?.setOnPreferenceClickListener { pref -> val builder = AlertDialog.Builder(pref.context, R.style.AlertDialogCustom) - .setView(R.layout.logcat) + + val binding = LogcatBinding.inflate(layoutInflater,null,false ) + builder.setView(binding.root) val dialog = builder.create() dialog.show() @@ -81,9 +83,9 @@ class SettingsUpdates : PreferenceFragmentCompat() { } val text = log.toString() - dialog.text1?.text = text + binding.text1.text = text - dialog.copy_btt?.setOnClickListener { + binding.copyBtt.setOnClickListener { // Can crash on too much text try { val serviceClipboard = @@ -96,11 +98,11 @@ class SettingsUpdates : PreferenceFragmentCompat() { showToast(activity, R.string.clipboard_too_large) } } - dialog.clear_btt?.setOnClickListener { + binding.clearBtt.setOnClickListener { Runtime.getRuntime().exec("logcat -c") dialog.dismissSafe(activity) } - dialog.save_btt?.setOnClickListener { + binding.saveBtt.setOnClickListener { var fileStream: OutputStream? = null try { fileStream = @@ -119,7 +121,7 @@ class SettingsUpdates : PreferenceFragmentCompat() { dialog.dismissSafe(activity) } } - dialog.close_btt?.setOnClickListener { + binding.closeBtt.setOnClickListener { dialog.dismissSafe(activity) } return@setOnPreferenceClickListener true diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt index 75ff8305..711026c6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt @@ -18,6 +18,8 @@ import androidx.navigation.fragment.findNavController import com.lagradost.cloudstream3.CommonActivity.showToast import com.lagradost.cloudstream3.MainActivity.Companion.afterRepositoryLoadedEvent import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.databinding.AddRepoInputBinding +import com.lagradost.cloudstream3.databinding.FragmentExtensionsBinding import com.lagradost.cloudstream3.mvvm.observe import com.lagradost.cloudstream3.mvvm.observeNullable import com.lagradost.cloudstream3.plugins.RepositoryManager @@ -30,16 +32,22 @@ import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.Coroutines.main import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe import com.lagradost.cloudstream3.widget.LinearRecycleViewLayoutManager -import kotlinx.android.synthetic.main.add_repo_input.* -import kotlinx.android.synthetic.main.fragment_extensions.* class ExtensionsFragment : Fragment() { + var binding: FragmentExtensionsBinding? = null + override fun onDestroyView() { + binding = null + super.onDestroyView() + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, - ): View? { - return inflater.inflate(R.layout.fragment_extensions, container, false) + ): View { + val localBinding = FragmentExtensionsBinding.inflate(inflater, container, false) + binding = localBinding + return localBinding.root//inflater.inflate(R.layout.fragment_extensions, container, false) } private fun View.setLayoutWidth(weight: Int) { @@ -74,7 +82,7 @@ class ExtensionsFragment : Fragment() { setUpToolbar(R.string.extensions) - repo_recycler_view?.adapter = RepoAdapter(false, { + binding?.repoRecyclerView?.adapter = RepoAdapter(false, { findNavController().navigate( R.id.navigation_settings_extensions_to_navigation_settings_plugins, PluginsFragment.newInstance( @@ -113,12 +121,12 @@ class ExtensionsFragment : Fragment() { }) observe(extensionViewModel.repositories) { - repo_recycler_view?.isVisible = it.isNotEmpty() - blank_repo_screen?.isVisible = it.isEmpty() - (repo_recycler_view?.adapter as? RepoAdapter)?.updateList(it) + binding?.repoRecyclerView?.isVisible = it.isNotEmpty() + binding?.blankRepoScreen?.isVisible = it.isEmpty() + (binding?.repoRecyclerView?.adapter as? RepoAdapter)?.updateList(it) } - repo_recycler_view?.apply { + binding?.repoRecyclerView?.apply { context?.let { ctx -> layoutManager = LinearRecycleViewLayoutManager(ctx, nextFocusUpId, nextFocusDownId) } @@ -140,28 +148,30 @@ class ExtensionsFragment : Fragment() { // } observeNullable(extensionViewModel.pluginStats) { value -> - if (value == null) { - plugin_storage_appbar?.isVisible = false + binding?.apply { + if (value == null) { + pluginStorageAppbar.isVisible = false - return@observeNullable - } + return@observeNullable + } - plugin_storage_appbar?.isVisible = true - if (value.total == 0) { - plugin_download?.setLayoutWidth(1) - plugin_disabled?.setLayoutWidth(0) - plugin_not_downloaded?.setLayoutWidth(0) - } else { - plugin_download?.setLayoutWidth(value.downloaded) - plugin_disabled?.setLayoutWidth(value.disabled) - plugin_not_downloaded?.setLayoutWidth(value.notDownloaded) + pluginStorageAppbar.isVisible = true + if (value.total == 0) { + pluginDownload.setLayoutWidth(1) + pluginDisabled.setLayoutWidth(0) + pluginNotDownloaded.setLayoutWidth(0) + } else { + pluginDownload.setLayoutWidth(value.downloaded) + pluginDisabled.setLayoutWidth(value.disabled) + pluginNotDownloaded.setLayoutWidth(value.notDownloaded) + } + pluginNotDownloadedTxt.setText(value.notDownloadedText) + pluginDisabledTxt.setText(value.disabledText) + pluginDownloadTxt.setText(value.downloadedText) } - plugin_not_downloaded_txt.setText(value.notDownloadedText) - plugin_disabled_txt.setText(value.disabledText) - plugin_download_txt.setText(value.downloadedText) } - plugin_storage_appbar?.setOnClickListener { + binding?.pluginStorageAppbar?.setOnClickListener { findNavController().navigate( R.id.navigation_settings_extensions_to_navigation_settings_plugins, PluginsFragment.newInstance( @@ -173,16 +183,18 @@ class ExtensionsFragment : Fragment() { } val addRepositoryClick = View.OnClickListener { + val ctx = context ?: return@OnClickListener + val binding = AddRepoInputBinding.inflate(LayoutInflater.from(ctx), null, false) val builder = - AlertDialog.Builder(context ?: return@OnClickListener, R.style.AlertDialogCustom) - .setView(R.layout.add_repo_input) + AlertDialog.Builder(ctx, R.style.AlertDialogCustom) + .setView(binding.root) val dialog = builder.create() dialog.show() (activity?.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager?)?.primaryClip?.getItemAt( 0 )?.text?.toString()?.let { copy -> - dialog.repo_url_input?.setText(copy) + binding.repoUrlInput.setText(copy) } // dialog.list_repositories?.setOnClickListener { @@ -192,10 +204,10 @@ class ExtensionsFragment : Fragment() { // } // dialog.text2?.text = provider.name - dialog.apply_btt?.setOnClickListener secondListener@{ - val name = dialog.repo_name_input?.text?.toString() + binding.applyBtt.setOnClickListener secondListener@{ + val name = binding.repoNameInput.text?.toString() ioSafe { - val url = dialog.repo_url_input?.text?.toString() + val url = binding.repoUrlInput.text?.toString() ?.let { it1 -> RepositoryManager.parseRepoUrl(it1) } if (url.isNullOrBlank()) { main { @@ -214,22 +226,23 @@ class ExtensionsFragment : Fragment() { } dialog.dismissSafe(activity) } - dialog.cancel_btt?.setOnClickListener { + binding.cancelBtt.setOnClickListener { dialog.dismissSafe(activity) } } val isTv = isTrueTvSettings() - add_repo_button?.isGone = isTv - add_repo_button_imageview_holder?.isVisible = isTv + binding?.apply { + addRepoButton.isGone = isTv + addRepoButtonImageviewHolder.isVisible = isTv - // Band-aid for Fire TV - plugin_storage_appbar?.isFocusableInTouchMode = isTv - add_repo_button_imageview?.isFocusableInTouchMode = isTv - - add_repo_button?.setOnClickListener(addRepositoryClick) - add_repo_button_imageview?.setOnClickListener(addRepositoryClick) + // Band-aid for Fire TV + pluginStorageAppbar.isFocusableInTouchMode = isTv + addRepoButtonImageview.isFocusableInTouchMode = isTv + addRepoButton.setOnClickListener(addRepositoryClick) + addRepoButtonImageview.setOnClickListener(addRepositoryClick) + } reloadRepositories() } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/RepoAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/RepoAdapter.kt index e90166a8..602b45e4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/RepoAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/RepoAdapter.kt @@ -1,14 +1,15 @@ package com.lagradost.cloudstream3.ui.settings.extensions import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView +import androidx.viewbinding.ViewBinding import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.databinding.RepositoryItemBinding +import com.lagradost.cloudstream3.databinding.RepositoryItemTvBinding import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings -import kotlinx.android.synthetic.main.repository_item.view.* class RepoAdapter( val isSetup: Boolean, @@ -20,9 +21,17 @@ class RepoAdapter( private val repositories: MutableList = mutableListOf() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - val layout = if(isTrueTvSettings()) R.layout.repository_item_tv else R.layout.repository_item + val layout = if (isTrueTvSettings()) RepositoryItemTvBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) else RepositoryItemBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) //R.layout.repository_item_tv else R.layout.repository_item return RepoViewHolder( - LayoutInflater.from(parent.context).inflate(layout, parent, false) + layout ) } @@ -57,30 +66,57 @@ class RepoAdapter( diffResult.dispatchUpdatesTo(this) } - inner class RepoViewHolder(itemView: View) : - RecyclerView.ViewHolder(itemView) { + inner class RepoViewHolder( + val binding: ViewBinding + ) : + RecyclerView.ViewHolder(binding.root) { fun bind( repositoryData: RepositoryData ) { val isPrebuilt = PREBUILT_REPOSITORIES.contains(repositoryData) val drawable = if (isSetup) R.drawable.netflix_download else R.drawable.ic_baseline_delete_outline_24 + when (binding) { + is RepositoryItemTvBinding -> { + binding.apply { + // Only shows icon if on setup or if it isn't a prebuilt repo. + // No delete buttons on prebuilt repos. + if (!isPrebuilt || isSetup) { + actionButton.setImageResource(drawable) + } - // Only shows icon if on setup or if it isn't a prebuilt repo. - // No delete buttons on prebuilt repos. - if (!isPrebuilt || isSetup) { - itemView.action_button?.setImageResource(drawable) - } + actionButton.setOnClickListener { + imageClickCallback(repositoryData) + } - itemView.action_button?.setOnClickListener { - imageClickCallback(repositoryData) - } + repositoryItemRoot.setOnClickListener { + clickCallback(repositoryData) + } + mainText.text = repositoryData.name + subText.text = repositoryData.url + } + } - itemView.repository_item_root?.setOnClickListener { - clickCallback(repositoryData) + is RepositoryItemBinding -> { + binding.apply { + // Only shows icon if on setup or if it isn't a prebuilt repo. + // No delete buttons on prebuilt repos. + if (!isPrebuilt || isSetup) { + actionButton.setImageResource(drawable) + } + + actionButton.setOnClickListener { + imageClickCallback(repositoryData) + } + + repositoryItemRoot.setOnClickListener { + clickCallback(repositoryData) + } + mainText.text = repositoryData.name + subText.text = repositoryData.url + } + } } - itemView.main_text?.text = repositoryData.name - itemView.sub_text?.text = repositoryData.url } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/testing/TestFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/testing/TestFragment.kt index 34cd67cd..59b1b856 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/testing/TestFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/testing/TestFragment.kt @@ -1,97 +1,105 @@ package com.lagradost.cloudstream3.ui.settings.testing import android.os.Bundle -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.coordinatorlayout.widget.CoordinatorLayout +import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.databinding.FragmentTestingBinding import com.lagradost.cloudstream3.mvvm.normalSafeApiCall import com.lagradost.cloudstream3.mvvm.observe import com.lagradost.cloudstream3.mvvm.observeNullable import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar -import kotlinx.android.synthetic.main.fragment_testing.* -import kotlinx.android.synthetic.main.view_test.* class TestFragment : Fragment() { private val testViewModel: TestViewModel by activityViewModels() + var binding: FragmentTestingBinding? = null + + override fun onDestroyView() { + binding = null + super.onDestroyView() + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { setUpToolbar(R.string.category_provider_test) super.onViewCreated(view, savedInstanceState) - provider_test_recycler_view?.adapter = TestResultAdapter( - mutableListOf() - ) + binding?.apply { + providerTestRecyclerView.adapter = TestResultAdapter( + mutableListOf() + ) - testViewModel.init() - if (testViewModel.isRunningTest) { - provider_test?.setState(TestView.TestState.Running) - } - - observe(testViewModel.providerProgress) { (passed, failed, total) -> - provider_test?.setProgress(passed, failed, total) - } - - observeNullable(testViewModel.providerResults) { - normalSafeApiCall { - val newItems = it.sortedBy { api -> api.first.name } - (provider_test_recycler_view?.adapter as? TestResultAdapter)?.updateList( - newItems - ) + testViewModel.init() + if (testViewModel.isRunningTest) { + providerTest.setState(TestView.TestState.Running) } - } - provider_test?.setOnPlayButtonListener { state -> - when (state) { - TestView.TestState.Stopped -> testViewModel.stopTest() - TestView.TestState.Running -> testViewModel.startTest() - TestView.TestState.None -> testViewModel.startTest() + observe(testViewModel.providerProgress) { (passed, failed, total) -> + providerTest.setProgress(passed, failed, total) } - } - if (isTrueTvSettings()) { - tests_play_pause?.isFocusableInTouchMode = true - tests_play_pause?.requestFocus() - } - - provider_test?.playPauseButton?.setOnFocusChangeListener { _, hasFocus -> - if (hasFocus) { - provider_test_appbar?.setExpanded(true, true) + observeNullable(testViewModel.providerResults) { + normalSafeApiCall { + val newItems = it.sortedBy { api -> api.first.name } + (providerTestRecyclerView.adapter as? TestResultAdapter)?.updateList( + newItems + ) + } + } + + providerTest.setOnPlayButtonListener { state -> + when (state) { + TestView.TestState.Stopped -> testViewModel.stopTest() + TestView.TestState.Running -> testViewModel.startTest() + TestView.TestState.None -> testViewModel.startTest() + } } - } - fun focusRecyclerView() { - // Hack to make it possible to focus the recyclerview. if (isTrueTvSettings()) { - provider_test_recycler_view?.requestFocus() - provider_test_appbar?.setExpanded(false, true) + providerTest.playPauseButton?.isFocusableInTouchMode = true + providerTest.playPauseButton?.requestFocus() } - } - provider_test?.setOnMainClick { - testViewModel.setFilterMethod(TestViewModel.ProviderFilter.All) - focusRecyclerView() - } - provider_test?.setOnFailedClick { - testViewModel.setFilterMethod(TestViewModel.ProviderFilter.Failed) - focusRecyclerView() - } - provider_test?.setOnPassedClick { - testViewModel.setFilterMethod(TestViewModel.ProviderFilter.Passed) - focusRecyclerView() + providerTest.playPauseButton?.setOnFocusChangeListener { _, hasFocus -> + if (hasFocus) { + providerTestAppbar.setExpanded(true, true) + } + } + + fun focusRecyclerView() { + // Hack to make it possible to focus the recyclerview. + if (isTrueTvSettings()) { + providerTestRecyclerView.requestFocus() + providerTestAppbar.setExpanded(false, true) + } + } + + providerTest.setOnMainClick { + testViewModel.setFilterMethod(TestViewModel.ProviderFilter.All) + focusRecyclerView() + } + providerTest.setOnFailedClick { + testViewModel.setFilterMethod(TestViewModel.ProviderFilter.Failed) + focusRecyclerView() + } + providerTest.setOnPassedClick { + testViewModel.setFilterMethod(TestViewModel.ProviderFilter.Passed) + focusRecyclerView() + } } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { - return inflater.inflate(R.layout.fragment_testing, container, false) + ): View { + val localBinding = FragmentTestingBinding.inflate(inflater, container, false) + binding = localBinding + return localBinding.root//inflater.inflate(R.layout.fragment_testing, container, false) } } \ No newline at end of file