tv UI fixes

This commit is contained in:
reduplicated 2022-08-29 01:52:15 +02:00
parent 01c81fc421
commit cd119822f2
29 changed files with 393 additions and 167 deletions

View file

@ -6,7 +6,6 @@ import android.content.Context
import android.content.pm.PackageManager
import android.content.res.Resources
import android.os.Build
import android.os.Looper
import android.util.Log
import android.view.*
import android.widget.TextView
@ -20,12 +19,12 @@ import com.google.android.gms.cast.framework.CastSession
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.ui.player.PlayerEventType
import com.lagradost.cloudstream3.ui.result.UiText
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.updateTv
import com.lagradost.cloudstream3.utils.Event
import com.lagradost.cloudstream3.utils.UIHelper
import com.lagradost.cloudstream3.utils.UIHelper.hasPIPPermission
import com.lagradost.cloudstream3.utils.UIHelper.shouldShowPIPMode
import com.lagradost.cloudstream3.utils.UIHelper.toPx
import kotlinx.coroutines.currentCoroutineContext
import org.schabi.newpipe.extractor.NewPipe
import java.util.*
@ -128,7 +127,7 @@ object CommonActivity {
act.hasPIPPermission() // CHECK IF FEATURE IS ENABLED IN SETTINGS
act.updateLocale()
act.updateTv()
NewPipe.init(DownloaderTestImpl.getInstance())
}

View file

@ -226,7 +226,7 @@ object APIHolder {
}
private fun Context.getHasTrailers(): Boolean {
if (this.isTvSettings()) return false
if (isTvSettings()) return false
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
return settingsManager.getBoolean(this.getString(R.string.show_trailers_key), true)
}

View file

@ -175,7 +175,7 @@ class DownloadFragment : Fragment() {
download_list?.adapter = adapter
download_list?.layoutManager = GridLayoutManager(context, 1)
download_stream_button?.isGone = context?.isTvSettings() == true
download_stream_button?.isGone = isTvSettings()
download_stream_button?.setOnClickListener {
val dialog =
Dialog(it.context ?: return@setOnClickListener, R.style.AlertDialogCustom)

View file

@ -400,7 +400,7 @@ class HomeFragment : Fragment() {
//homeViewModel =
// ViewModelProvider(this).get(HomeViewModel::class.java)
val layout =
if (context?.isTvSettings() == true) R.layout.fragment_home_tv else R.layout.fragment_home
if (isTvSettings()) R.layout.fragment_home_tv else R.layout.fragment_home
return inflater.inflate(layout, container, false)
}
@ -568,7 +568,7 @@ class HomeFragment : Fragment() {
val randomSize = items.size
tempAdapter?.updateList(items)
if (context?.isTvSettings() == false) {
if (!isTvSettings()) {
home_main_poster_recyclerview?.post {
(home_main_poster_recyclerview?.layoutManager as CenterZoomLayoutManager?)?.let { manager ->
manager.updateSize(forceUpdate = true)
@ -939,7 +939,7 @@ class HomeFragment : Fragment() {
}
} // GridLayoutManager(context, 1).also { it.supportsPredictiveItemAnimations() }
if (context?.isTvSettings() == false) {
if (!isTvSettings()) {
LinearSnapHelper().attachToRecyclerView(home_main_poster_recyclerview) // snap
val centerLayoutManager =
CenterZoomLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
@ -975,7 +975,7 @@ class HomeFragment : Fragment() {
home_api_fab?.shrink() // hide
home_random?.shrink()
} else if (dy < -5) {
if (v.context?.isTvSettings() == false) {
if (!isTvSettings()) {
home_api_fab?.extend() // show
home_random?.extend()
}
@ -984,12 +984,11 @@ class HomeFragment : Fragment() {
// nice profile pic on homepage
home_profile_picture_holder?.isVisible = false
context?.let { ctx ->
// just in case
if (ctx.isTvSettings()) {
if (isTvSettings()) {
home_api_fab?.isVisible = false
home_change_api?.isVisible = true
if (ctx.isTrueTvSettings()) {
if (isTrueTvSettings()) {
home_change_api_loading?.isVisible = true
home_change_api_loading?.isFocusable = true
home_change_api_loading?.isFocusableInTouchMode = true
@ -1018,4 +1017,3 @@ class HomeFragment : Fragment() {
}
}
}
}

View file

@ -29,7 +29,7 @@ class ParentItemAdapter(
override fun onCreateViewHolder(parent: ViewGroup, i: Int): ParentViewHolder {
//println("onCreateViewHolder $i")
val layout =
if (parent.context.isTvSettings()) R.layout.homepage_parent_tv else R.layout.homepage_parent
if (isTvSettings()) R.layout.homepage_parent_tv else R.layout.homepage_parent
return ParentViewHolder(
LayoutInflater.from(parent.context).inflate(layout, parent, false),
clickCallback,

View file

@ -993,7 +993,7 @@ class GeneratorPlayer : FullScreenPlayer() {
savedInstanceState: Bundle?
): View? {
// this is used instead of layout-television to follow the settings and some TV devices are not classified as TV for some reason
isTv = context?.isTvSettings() == true
isTv = isTvSettings()
layout =
if (isTv) R.layout.fragment_player_tv else R.layout.fragment_player

View file

@ -124,7 +124,7 @@ class PlayerEpisodeAdapter(
clickCallback.invoke(PlayerEpisodeClickEvent(0, card))
}
if (parentView.context.isTrueTvSettings()) {
if (isTrueTvSettings()) {
parentView.isFocusable = true
parentView.isFocusableInTouchMode = true
parentView.touchscreenBlocksFocus = false

View file

@ -166,7 +166,7 @@ class EpisodeAdapter(
fun bind(card: ResultEpisode) {
localCard = card
val isTrueTv = itemView.context?.isTrueTvSettings() == true
val isTrueTv = isTrueTvSettings()
val (parentView, otherView) = if (card.poster == null) {
itemView.episode_holder to itemView.episode_holder_large

View file

@ -83,7 +83,7 @@ class ImageAdapter(
this.nextFocusUpId = nextFocusUp
}
if (clickCallback != null) {
if (context.isTrueTvSettings()) {
if (isTrueTvSettings()) {
isClickable = true
isLongClickable = true
isFocusable = true

View file

@ -293,7 +293,7 @@ open class ResultFragment : ResultTrailerPlayer() {
result_reload_connection_open_in_browser?.isVisible = true
}
2 -> {
result_bookmark_fab?.isGone = result_bookmark_fab?.context?.isTvSettings() == true
result_bookmark_fab?.isGone = isTvSettings()
result_bookmark_fab?.extend()
//if (result_bookmark_button?.context?.isTrueTvSettings() == true) {
// when {
@ -551,7 +551,7 @@ open class ResultFragment : ResultTrailerPlayer() {
}
// This is to band-aid FireTV navigation
val isTv = context?.isTvSettings() == true
val isTv = isTvSettings()
result_season_button?.isFocusableInTouchMode = isTv
result_episode_select?.isFocusableInTouchMode = isTv
result_dub_select?.isFocusableInTouchMode = isTv
@ -794,7 +794,7 @@ open class ResultFragment : ResultTrailerPlayer() {
result_next_airing_time.setText(d.nextAiringDate)
result_poster.setImage(d.posterImage)
if (d.posterImage != null && context?.isTrueTvSettings() == false)
if (d.posterImage != null && !isTrueTvSettings())
result_poster_holder?.setOnClickListener {
try {
context?.let { ctx ->
@ -883,7 +883,7 @@ open class ResultFragment : ResultTrailerPlayer() {
result_tag_holder?.isVisible = tags.isNotEmpty()
if (tags.isNotEmpty()) {
//result_tag_holder?.visibility = VISIBLE
val isOnTv = context?.isTrueTvSettings() == true
val isOnTv = isTrueTvSettings()
for ((index, tag) in tags.withIndex()) {
val viewBtt = layoutInflater.inflate(R.layout.result_tag, null)
val btt = viewBtt.findViewById<MaterialButton>(R.id.result_tag_card)
@ -941,7 +941,7 @@ open class ResultFragment : ResultTrailerPlayer() {
}
// bloats the navigation on tv
if (context?.isTrueTvSettings() == false) {
if (!isTrueTvSettings()) {
result_meta_site?.setOnClickListener {
it.context?.openBrowser(storedData.url)
}

View file

@ -85,7 +85,7 @@ class SelectAdaptor(val callback: (Any) -> Unit) : RecyclerView.Adapter<Recycler
fun bind(
data: SelectData, isSelected: Boolean, callback: (Any) -> Unit
) {
val isTrueTv = itemView.context?.isTrueTvSettings() == true
val isTrueTv = isTrueTvSettings()
if (isTrueTv) {
item.isFocusable = true
item.isFocusableInTouchMode = true

View file

@ -386,7 +386,7 @@ class SearchFragment : Fragment() {
}
}
if (context?.isTrueTvSettings() == true) {
if (isTrueTvSettings()) {
search_filter.isFocusable = true
search_filter.isFocusableInTouchMode = true
}

View file

@ -164,7 +164,7 @@ object SearchResultBuilder {
}
}
if (bg.context.isTrueTvSettings()) {
if (isTrueTvSettings()) {
bg.isFocusable = true
bg.isFocusableInTouchMode = true
bg.touchscreenBlocksFocus = false

View file

@ -117,7 +117,7 @@ class SettingsAccount : PreferenceFragmentCompat() {
dialog.login_username_input to api.requiresUsername
)
if (activity.isTvSettings()) {
if (isTvSettings()) {
visibilityMap.forEach { (input, isVisible) ->
input.isVisible = isVisible

View file

@ -30,6 +30,9 @@ class SettingsFragment : Fragment() {
companion object {
var beneneCount = 0
private var isTv : Boolean = false
private var isTrueTv : Boolean = false
fun PreferenceFragmentCompat?.getPref(id: Int): Preference? {
if (this == null) return null
@ -45,7 +48,7 @@ class SettingsFragment : Fragment() {
* On TV you cannot properly scroll to the bottom of settings, this fixes that.
* */
fun PreferenceFragmentCompat.setPaddingBottom() {
if (this.context?.isTvSettings() == true) {
if (isTvSettings()) {
listView?.setPadding(0, 0, 0, 100.toPx)
}
}
@ -93,7 +96,7 @@ class SettingsFragment : Fragment() {
return settingsManager.getInt(this.getString(R.string.app_layout_key), -1)
}
fun Context.isTvSettings(): Boolean {
private fun Context.isTvSettings(): Boolean {
var value = getLayoutInt()
if (value == -1) {
value = if (isAutoTv()) 1 else 0
@ -101,7 +104,7 @@ class SettingsFragment : Fragment() {
return value == 1 || value == 2
}
fun Context.isTrueTvSettings(): Boolean {
private fun Context.isTrueTvSettings(): Boolean {
var value = getLayoutInt()
if (value == -1) {
value = if (isAutoTv()) 1 else 0
@ -109,6 +112,19 @@ class SettingsFragment : Fragment() {
return value == 1
}
fun Context.updateTv() {
isTrueTv = isTrueTvSettings()
isTv = isTvSettings()
}
fun isTrueTvSettings(): Boolean {
return isTrueTv
}
fun isTvSettings(): Boolean {
return isTv
}
fun Context.isEmulatorSettings(): Boolean {
return getLayoutInt() == 2
}
@ -136,7 +152,7 @@ class SettingsFragment : Fragment() {
activity?.navigate(id, Bundle())
}
val isTrueTv = context?.isTrueTvSettings() == true
val isTrueTv = isTrueTvSettings()
for (syncApi in accountManagers) {
val login = syncApi.loginInfo()

View file

@ -11,6 +11,7 @@ import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setPaddingBottom
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.updateTv
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showMultiDialog
@ -22,6 +23,7 @@ class SettingsUI : PreferenceFragmentCompat() {
setUpToolbar(R.string.category_ui)
setPaddingBottom()
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
hideKeyboard()
setPreferencesFromResource(R.xml.settins_ui, rootKey)
@ -71,6 +73,7 @@ class SettingsUI : PreferenceFragmentCompat() {
settingsManager.edit()
.putInt(getString(R.string.app_layout_key), prefValues[it])
.apply()
context?.updateTv()
activity?.recreate()
} catch (e: Exception) {
logError(e)
@ -130,7 +133,10 @@ class SettingsUI : PreferenceFragmentCompat() {
getPref(R.string.pref_filter_search_quality_key)?.setOnPreferenceClickListener {
val names = enumValues<SearchQuality>().sorted().map { it.name }
val currentList = settingsManager.getStringSet(getString(R.string.pref_filter_search_quality_key), setOf())?.map {
val currentList = settingsManager.getStringSet(
getString(R.string.pref_filter_search_quality_key),
setOf()
)?.map {
it.toInt()
} ?: listOf()

View file

@ -11,6 +11,7 @@ import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
@ -23,12 +24,14 @@ import com.lagradost.cloudstream3.mvvm.Some
import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.plugins.RepositoryManager
import com.lagradost.cloudstream3.ui.result.setText
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
import com.lagradost.cloudstream3.utils.AppUtils.downloadAllPluginsDialog
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.*
import kotlinx.android.synthetic.main.fragment_extensions.list_repositories
@ -119,9 +122,15 @@ class ExtensionsFragment : Fragment() {
(repo_recycler_view?.adapter as? RepoAdapter)?.updateList(it)
}
repo_recycler_view?.apply {
context?.let { ctx ->
layoutManager = LinearRecycleViewLayoutManager(ctx, nextFocusUpId, nextFocusDownId)
}
}
list_repositories?.setOnClickListener {
// Open webview on tv if browser fails
val isTv = it.context.isTvSettings()
val isTv = isTvSettings()
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
// Set clipboard on TV because the browser might not exist or work properly
@ -170,9 +179,9 @@ class ExtensionsFragment : Fragment() {
)
}
add_repo_button?.setOnClickListener {
val addRepositoryClick = View.OnClickListener {
val builder =
AlertDialog.Builder(context ?: return@setOnClickListener, R.style.AlertDialogCustom)
AlertDialog.Builder(context ?: return@OnClickListener, R.style.AlertDialogCustom)
.setView(R.layout.add_repo_input)
val dialog = builder.create()
@ -193,8 +202,7 @@ class ExtensionsFragment : Fragment() {
dialog.list_repositories?.setOnClickListener {
// Open webview on tv if browser fails
val isTv = it.context.isTvSettings()
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
}
// dialog.text2?.text = provider.name
@ -223,6 +231,12 @@ class ExtensionsFragment : Fragment() {
}
}
val isTv = isTrueTvSettings()
add_repo_button?.isGone = isTv
add_repo_button_imageview_holder?.isVisible = isTv
add_repo_button?.setOnClickListener(addRepositoryClick)
add_repo_button_imageview?.setOnClickListener(addRepositoryClick)
reloadRepositories()
}
}

View file

@ -14,6 +14,7 @@ import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.plugins.PluginManager
import com.lagradost.cloudstream3.ui.result.setText
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
import com.lagradost.cloudstream3.utils.AppUtils.html
import com.lagradost.cloudstream3.utils.GlideApp
import com.lagradost.cloudstream3.utils.SubtitleHelper.fromTwoLettersToLanguage
@ -36,8 +37,9 @@ class PluginAdapter(
private val plugins: MutableList<PluginViewData> = mutableListOf()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layout = if(isTrueTvSettings()) R.layout.repository_item_tv else R.layout.repository_item
return PluginViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.repository_item, parent, false)
LayoutInflater.from(parent.context).inflate(layout, parent, false)
)
}
@ -123,7 +125,6 @@ class PluginAdapter(
itemView.action_button?.setOnClickListener {
iconClickCallback.invoke(data.plugin)
}
testFindClosestBase2()
//if (itemView.context?.isTrueTvSettings() == false) {
// val siteUrl = metadata.repositoryUrl
// if (siteUrl != null && siteUrl.isNotBlank() && siteUrl != "NONE") {

View file

@ -128,7 +128,7 @@ class PluginsFragment : Fragment() {
pluginViewModel.handlePluginAction(activity, url, it, isLocal)
}
if (context?.isTvSettings() == true) {
if (isTvSettings()) {
// Scrolling down does not reveal the whole RecyclerView on TV, add to bypass that.
plugin_recycler_view?.setPadding(0, 0, 0, 200.toPx)
}

View file

@ -7,6 +7,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.R
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(
@ -19,8 +20,9 @@ class RepoAdapter(
private val repositories: MutableList<RepositoryData> = mutableListOf()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layout = if(isTrueTvSettings()) R.layout.repository_item_tv else R.layout.repository_item
return RepoViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.repository_item, parent, false)
LayoutInflater.from(parent.context).inflate(layout, parent, false)
)
}

View file

@ -73,8 +73,7 @@ class SetupFragmentExtensions : Fragment() {
} else {
list_repositories?.setOnClickListener {
// Open webview on tv if browser fails
val isTv = it.context.isTvSettings()
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
}
}
}
@ -86,8 +85,7 @@ class SetupFragmentExtensions : Fragment() {
val isSetup = arguments?.getBoolean(SETUP_EXTENSION_BUNDLE_IS_SETUP) ?: false
view_public_repositories_button?.setOnClickListener {
val isTv = it.context.isTvSettings()
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
}
with(context) {

View file

@ -164,7 +164,7 @@ class ChromecastSubtitlesFragment : Fragment() {
state = getCurrentSavedStyle()
context?.updateState()
val isTvSettings = context?.isTvSettings() == true
val isTvSettings = isTvSettings()
fun View.setFocusableInTv() {
this.isFocusableInTouchMode = isTvSettings

View file

@ -243,7 +243,7 @@ class SubtitlesFragment : Fragment() {
state = getCurrentSavedStyle()
context?.updateState()
val isTvTrueSettings = context?.isTrueTvSettings() == true
val isTvTrueSettings = isTrueTvSettings()
fun View.setFocusableInTv() {
this.isFocusableInTouchMode = isTvTrueSettings

View file

@ -407,8 +407,8 @@ object AppUtils {
//private val viewModel: ResultViewModel by activityViewModels()
private fun getResultsId(context: Context): Int {
return if (context.isTrueTvSettings()) {
private fun getResultsId(): Int {
return if (isTrueTvSettings()) {
R.id.global_to_navigation_results_tv
} else {
R.id.global_to_navigation_results_phone
@ -424,7 +424,7 @@ object AppUtils {
this.runOnUiThread {
// viewModelStore.clear()
this.navigate(
getResultsId(this.applicationContext ?: return@runOnUiThread),
getResultsId(),
ResultFragment.newInstance(url, apiName, startAction, startValue)
)
}
@ -438,7 +438,7 @@ object AppUtils {
this?.runOnUiThread {
// viewModelStore.clear()
this.navigate(
getResultsId(this),
getResultsId(),
ResultFragment.newInstance(card, startAction, startValue)
)
}

View file

@ -44,7 +44,7 @@ object SingleSelectionHelper {
) {
if (this == null) return
if (this.isTvSettings()) {
if (isTvSettings()) {
val builder =
AlertDialog.Builder(this, R.style.AlertDialogCustom)
.setView(R.layout.options_popup_tv)

View file

@ -0,0 +1,30 @@
package com.lagradost.cloudstream3.widget
import android.content.Context
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
class LinearRecycleViewLayoutManager(
val context: Context,
val nextFocusUp: Int,
val nextFocusDown: Int
) : LinearLayoutManager(context) {
override fun onInterceptFocusSearch(focused: View, direction: Int): View? {
return try {
val position = getPosition(focused)
val count = itemCount
//println("onInterceptFocusSearch position=$position count=$count focused=$focused direction=$direction")
(if (position == count - 1 && direction == View.FOCUS_DOWN) {
focused.rootView.findViewById(nextFocusDown)
} else if (position == 0 && direction == View.FOCUS_UP) {
focused.rootView.findViewById(nextFocusUp)
} else {
super.onInterceptFocusSearch(focused, direction)
}) ?: super.onInterceptFocusSearch(focused, direction)
} catch (t : Throwable) {
super.onInterceptFocusSearch(focused, direction)
}
}
}

View file

@ -29,7 +29,10 @@
android:textStyle="bold" />
<com.google.android.material.button.MaterialButton
android:nextFocusDown="@id/repo_name_input"
android:id="@+id/list_repositories"
android:nextFocusLeft="@id/apply_btt"
android:nextFocusRight="@id/cancel_btt"
style="@style/WhiteButton"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
@ -67,6 +70,7 @@
android:autofillHints="username"
android:hint="@string/repository_name_hint"
android:inputType="text"
android:nextFocusUp="@id/list_repositories"
android:nextFocusLeft="@id/apply_btt"
android:nextFocusRight="@id/cancel_btt"
android:nextFocusDown="@id/site_url_input"

View file

@ -11,6 +11,8 @@
<include layout="@layout/standard_toolbar" />
<androidx.recyclerview.widget.RecyclerView
android:nextFocusUp="@id/settings_toolbar"
android:nextFocusDown="@id/plugin_storage_appbar"
android:id="@+id/repo_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -23,13 +25,13 @@
tools:visibility="visible" />
<LinearLayout
tools:visibility="gone"
android:id="@+id/blank_repo_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:gravity="center"
android:orientation="vertical">
android:orientation="vertical"
tools:visibility="gone">
<ImageView
android:layout_width="30dp"
@ -38,36 +40,40 @@
android:src="@drawable/ic_baseline_extension_24" />
<TextView
android:layout_marginBottom="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:gravity="center"
android:text="@string/blank_repo_message"
android:textSize="16sp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/list_repositories"
android:nextFocusDown="@id/add_repo_button"
style="@style/WhiteButton"
android:layout_width="wrap_content"
android:nextFocusDown="@id/add_repo_button"
android:text="@string/view_public_repositories_button" />
</LinearLayout>
<LinearLayout
android:foreground="@drawable/outline_drawable"
android:nextFocusUp="@id/add_repo_button"
android:id="@+id/plugin_storage_appbar"
android:nextFocusRight="@id/add_repo_button_imageview"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_gravity="bottom"
android:background="?attr/primaryGrayBackground"
android:orientation="vertical"
android:foreground="@drawable/outline_drawable"
android:padding="10dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
android:orientation="horizontal">
<LinearLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
@ -160,12 +166,42 @@
tools:text="Not downloaded 3" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/add_repo_button_imageview_holder"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:textColor="?attr/textColor"
android:layout_gravity="center"
android:text="@string/add_repository"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:background="@drawable/outline_drawable"
android:nextFocusLeft="@id/plugin_storage_appbar"
android:layout_gravity="center"
android:id="@+id/add_repo_button_imageview"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/ic_baseline_add_24"
android:contentDescription="@string/add_repository"
app:tint="?attr/textColor">
</ImageView>
</LinearLayout>
</LinearLayout>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/add_repo_button"
style="@style/ExtendedFloatingActionButton"
android:foreground="@drawable/outline_drawable"
android:nextFocusDown="@id/plugin_storage_appbar"
style="@style/ExtendedFloatingActionButton"
android:text="@string/add_repository"
android:textColor="?attr/textColor"
android:translationY="-80dp"

View file

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/repository_item_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/outline_drawable"
android:nextFocusRight="@id/action_button"
android:orientation="horizontal"
android:padding="12dp">
<ImageView
android:id="@+id/entry_icon"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="start|center_vertical"
android:layout_marginEnd="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_github_logo" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/main_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/textColor"
android:textSize="16sp"
tools:text="Test repository" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/lang_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="5dp"
android:text="🇷🇼"
android:textColor="?attr/grayTextColor"
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/ext_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="5dp"
android:text="v1"
android:textColor="?attr/grayTextColor"
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/ext_filesize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="5dp"
android:text="100MB"
android:textColor="?attr/grayTextColor"
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/nsfw_marker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/is_adult"
android:textColor="@color/adultColor"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
<TextView
android:id="@+id/sub_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/grayTextColor"
android:textSize="12sp"
tools:text="https://github.com/..." />
</LinearLayout>
<ImageView
android:id="@+id/action_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="12dp"
android:background="@drawable/outline_drawable"
android:contentDescription="@string/title_settings"
android:visibility="gone"
app:srcCompat="@drawable/ic_baseline_tune_24"
tools:visibility="visible" />
<ImageView
android:id="@+id/action_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:layout_marginStart="10dp"
android:background="@drawable/outline_drawable"
android:clickable="true"
android:contentDescription="@string/download"
android:focusable="true"
android:nextFocusLeft="@id/repository_item_root"
android:padding="12dp"
tools:src="@drawable/ic_baseline_add_24" />
</LinearLayout>