mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
extensions info + updated adapter
This commit is contained in:
parent
a3d17065f4
commit
0dc8077296
7 changed files with 281 additions and 30 deletions
|
@ -107,7 +107,7 @@ object PluginManager {
|
||||||
|
|
||||||
private val classLoaders: MutableMap<PathClassLoader, Plugin> =
|
private val classLoaders: MutableMap<PathClassLoader, Plugin> =
|
||||||
HashMap<PathClassLoader, Plugin>()
|
HashMap<PathClassLoader, Plugin>()
|
||||||
|
|
||||||
private var loadedLocalPlugins = false
|
private var loadedLocalPlugins = false
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ object PluginManager {
|
||||||
|
|
||||||
|
|
||||||
// Helper class for updateAllOnlinePluginsAndLoadThem
|
// Helper class for updateAllOnlinePluginsAndLoadThem
|
||||||
private data class OnlinePluginData(
|
data class OnlinePluginData(
|
||||||
val savedData: PluginData,
|
val savedData: PluginData,
|
||||||
val onlineData: Pair<String, SitePlugin>,
|
val onlineData: Pair<String, SitePlugin>,
|
||||||
) {
|
) {
|
||||||
|
@ -135,6 +135,8 @@ object PluginManager {
|
||||||
val isDisabled = onlineData.second.status == PROVIDER_STATUS_DOWN
|
val isDisabled = onlineData.second.status == PROVIDER_STATUS_DOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var allCurrentOutDatedPlugins: Set<OnlinePluginData> = emptySet()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Needs to be run before other plugin loading because plugin loading can not be overwritten
|
* Needs to be run before other plugin loading because plugin loading can not be overwritten
|
||||||
* 1. Gets all online data about the downloaded plugins
|
* 1. Gets all online data about the downloaded plugins
|
||||||
|
@ -143,7 +145,8 @@ object PluginManager {
|
||||||
* 4. Else load the plugin normally
|
* 4. Else load the plugin normally
|
||||||
**/
|
**/
|
||||||
fun updateAllOnlinePluginsAndLoadThem(activity: Activity) {
|
fun updateAllOnlinePluginsAndLoadThem(activity: Activity) {
|
||||||
val urls = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY) ?: emptyArray()) + PREBUILT_REPOSITORIES
|
val urls = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY)
|
||||||
|
?: emptyArray()) + PREBUILT_REPOSITORIES
|
||||||
|
|
||||||
val onlinePlugins = urls.toList().apmap {
|
val onlinePlugins = urls.toList().apmap {
|
||||||
getRepoPlugins(it.url)?.toList() ?: emptyList()
|
getRepoPlugins(it.url)?.toList() ?: emptyList()
|
||||||
|
@ -156,6 +159,7 @@ object PluginManager {
|
||||||
OnlinePluginData(savedData, onlineData)
|
OnlinePluginData(savedData, onlineData)
|
||||||
}
|
}
|
||||||
}.flatten().distinctBy { it.onlineData.second.url }
|
}.flatten().distinctBy { it.onlineData.second.url }
|
||||||
|
allCurrentOutDatedPlugins = outdatedPlugins.toSet()
|
||||||
|
|
||||||
Log.i(TAG, "Outdated plugins: ${outdatedPlugins.filter { it.isOutdated }}")
|
Log.i(TAG, "Outdated plugins: ${outdatedPlugins.filter { it.isOutdated }}")
|
||||||
|
|
||||||
|
@ -308,7 +312,7 @@ object PluginManager {
|
||||||
APIHolder.allProviders.removeIf { provider: MainAPI -> provider.sourcePlugin == plugin.__filename }
|
APIHolder.allProviders.removeIf { provider: MainAPI -> provider.sourcePlugin == plugin.__filename }
|
||||||
extractorApis.removeIf { provider: ExtractorApi -> provider.sourcePlugin == plugin.__filename }
|
extractorApis.removeIf { provider: ExtractorApi -> provider.sourcePlugin == plugin.__filename }
|
||||||
|
|
||||||
classLoaders.values.removeIf { v -> v == plugin}
|
classLoaders.values.removeIf { v -> v == plugin }
|
||||||
|
|
||||||
plugins.remove(absolutePath)
|
plugins.remove(absolutePath)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,16 +7,20 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.LinearLayout
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
|
import com.lagradost.cloudstream3.mvvm.Some
|
||||||
import com.lagradost.cloudstream3.mvvm.observe
|
import com.lagradost.cloudstream3.mvvm.observe
|
||||||
import com.lagradost.cloudstream3.plugins.PREBUILT_REPOSITORIES
|
import com.lagradost.cloudstream3.plugins.PREBUILT_REPOSITORIES
|
||||||
import com.lagradost.cloudstream3.plugins.RepositoryManager
|
import com.lagradost.cloudstream3.plugins.RepositoryManager
|
||||||
|
import com.lagradost.cloudstream3.ui.result.setText
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||||
|
@ -35,6 +39,15 @@ class ExtensionsFragment : Fragment() {
|
||||||
return inflater.inflate(R.layout.fragment_extensions, container, false)
|
return inflater.inflate(R.layout.fragment_extensions, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun View.setLayoutWidth(weight: Int) {
|
||||||
|
val param = LinearLayout.LayoutParams(
|
||||||
|
0,
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
weight.toFloat()
|
||||||
|
)
|
||||||
|
this.layoutParams = param
|
||||||
|
}
|
||||||
|
|
||||||
private val extensionViewModel: ExtensionsViewModel by activityViewModels()
|
private val extensionViewModel: ExtensionsViewModel by activityViewModels()
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
@ -43,7 +56,7 @@ class ExtensionsFragment : Fragment() {
|
||||||
|
|
||||||
setUpToolbar(R.string.extensions)
|
setUpToolbar(R.string.extensions)
|
||||||
|
|
||||||
repo_recycler_view?.adapter = RepoAdapter(PREBUILT_REPOSITORIES, false, {
|
repo_recycler_view?.adapter = RepoAdapter(false, {
|
||||||
findNavController().navigate(
|
findNavController().navigate(
|
||||||
R.id.navigation_settings_extensions_to_navigation_settings_plugins,
|
R.id.navigation_settings_extensions_to_navigation_settings_plugins,
|
||||||
Bundle().apply {
|
Bundle().apply {
|
||||||
|
@ -60,6 +73,7 @@ class ExtensionsFragment : Fragment() {
|
||||||
DialogInterface.BUTTON_POSITIVE -> {
|
DialogInterface.BUTTON_POSITIVE -> {
|
||||||
ioSafe {
|
ioSafe {
|
||||||
RepositoryManager.removeRepository(view.context, repo)
|
RepositoryManager.removeRepository(view.context, repo)
|
||||||
|
extensionViewModel.loadStats()
|
||||||
extensionViewModel.loadRepositories()
|
extensionViewModel.loadRepositories()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,8 +92,32 @@ class ExtensionsFragment : Fragment() {
|
||||||
})
|
})
|
||||||
|
|
||||||
observe(extensionViewModel.repositories) {
|
observe(extensionViewModel.repositories) {
|
||||||
(repo_recycler_view?.adapter as? RepoAdapter)?.repositories = it
|
(repo_recycler_view?.adapter as? RepoAdapter)?.updateList(it)
|
||||||
(repo_recycler_view?.adapter as? RepoAdapter)?.notifyDataSetChanged()
|
}
|
||||||
|
|
||||||
|
observe(extensionViewModel.pluginStats) {
|
||||||
|
when (it) {
|
||||||
|
is Some.Success -> {
|
||||||
|
val value = it.value
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
plugin_not_downloaded_txt.setText(value.notDownloadedText)
|
||||||
|
plugin_disabled_txt.setText(value.disabledText)
|
||||||
|
plugin_download_txt.setText(value.downloadedText)
|
||||||
|
}
|
||||||
|
is Some.None -> {
|
||||||
|
plugin_storage_appbar?.isVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
add_repo_button?.setOnClickListener {
|
add_repo_button?.setOnClickListener {
|
||||||
|
@ -118,6 +156,7 @@ class ExtensionsFragment : Fragment() {
|
||||||
|
|
||||||
val newRepo = RepositoryData(fixedName, url)
|
val newRepo = RepositoryData(fixedName, url)
|
||||||
RepositoryManager.addRepository(newRepo)
|
RepositoryManager.addRepository(newRepo)
|
||||||
|
extensionViewModel.loadStats()
|
||||||
extensionViewModel.loadRepositories()
|
extensionViewModel.loadRepositories()
|
||||||
}
|
}
|
||||||
dialog.dismissSafe(activity)
|
dialog.dismissSafe(activity)
|
||||||
|
@ -127,7 +166,7 @@ class ExtensionsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extensionViewModel.loadStats()
|
||||||
extensionViewModel.loadRepositories()
|
extensionViewModel.loadRepositories()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,9 +3,20 @@ package com.lagradost.cloudstream3.ui.settings.extensions
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||||
|
import com.lagradost.cloudstream3.R
|
||||||
|
import com.lagradost.cloudstream3.apmap
|
||||||
|
import com.lagradost.cloudstream3.mvvm.Some
|
||||||
|
import com.lagradost.cloudstream3.mvvm.debugAssert
|
||||||
import com.lagradost.cloudstream3.plugins.PREBUILT_REPOSITORIES
|
import com.lagradost.cloudstream3.plugins.PREBUILT_REPOSITORIES
|
||||||
|
import com.lagradost.cloudstream3.plugins.PluginManager
|
||||||
|
import com.lagradost.cloudstream3.plugins.PluginManager.getPluginsOnline
|
||||||
|
import com.lagradost.cloudstream3.plugins.RepositoryManager
|
||||||
|
import com.lagradost.cloudstream3.ui.result.UiText
|
||||||
|
import com.lagradost.cloudstream3.ui.result.txt
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
data class RepositoryData(
|
data class RepositoryData(
|
||||||
@JsonProperty("name") val name: String,
|
@JsonProperty("name") val name: String,
|
||||||
|
@ -15,12 +26,65 @@ data class RepositoryData(
|
||||||
const val REPOSITORIES_KEY = "REPOSITORIES_KEY"
|
const val REPOSITORIES_KEY = "REPOSITORIES_KEY"
|
||||||
|
|
||||||
class ExtensionsViewModel : ViewModel() {
|
class ExtensionsViewModel : ViewModel() {
|
||||||
|
data class PluginStats(
|
||||||
|
val total: Int,
|
||||||
|
|
||||||
|
val downloaded: Int,
|
||||||
|
val disabled: Int,
|
||||||
|
val notDownloaded: Int,
|
||||||
|
|
||||||
|
val downloadedText: UiText,
|
||||||
|
val disabledText: UiText,
|
||||||
|
val notDownloadedText: UiText,
|
||||||
|
)
|
||||||
|
|
||||||
private val _repositories = MutableLiveData<Array<RepositoryData>>()
|
private val _repositories = MutableLiveData<Array<RepositoryData>>()
|
||||||
val repositories: LiveData<Array<RepositoryData>> = _repositories
|
val repositories: LiveData<Array<RepositoryData>> = _repositories
|
||||||
|
|
||||||
|
private val _pluginStats: MutableLiveData<Some<PluginStats>> = MutableLiveData(Some.None)
|
||||||
|
val pluginStats: LiveData<Some<PluginStats>> = _pluginStats
|
||||||
|
|
||||||
|
//TODO CACHE GET REQUESTS
|
||||||
|
fun loadStats() = viewModelScope.launch {
|
||||||
|
val urls = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY)
|
||||||
|
?: emptyArray()) + PREBUILT_REPOSITORIES
|
||||||
|
|
||||||
|
val onlinePlugins = urls.toList().apmap {
|
||||||
|
RepositoryManager.getRepoPlugins(it.url)?.toList() ?: emptyList()
|
||||||
|
}.flatten().distinctBy { it.second.url }
|
||||||
|
|
||||||
|
// Iterates over all offline plugins, compares to remote repo and returns the plugins which are outdated
|
||||||
|
val outdatedPlugins = getPluginsOnline().map { savedData ->
|
||||||
|
onlinePlugins.filter { onlineData -> savedData.internalName == onlineData.second.internalName }
|
||||||
|
.map { onlineData ->
|
||||||
|
PluginManager.OnlinePluginData(savedData, onlineData)
|
||||||
|
}
|
||||||
|
}.flatten().distinctBy { it.onlineData.second.url }
|
||||||
|
val total = onlinePlugins.count()
|
||||||
|
val disabled = outdatedPlugins.count { it.isDisabled }
|
||||||
|
val downloadedTotal = outdatedPlugins.count()
|
||||||
|
val downloaded = downloadedTotal - disabled
|
||||||
|
val notDownloaded = total - downloadedTotal
|
||||||
|
val stats = PluginStats(
|
||||||
|
total,
|
||||||
|
downloaded,
|
||||||
|
disabled,
|
||||||
|
notDownloaded,
|
||||||
|
txt(R.string.plugins_downloaded, downloaded),
|
||||||
|
txt(R.string.plugins_disabled, disabled),
|
||||||
|
txt(R.string.plugins_not_downloaded, notDownloaded)
|
||||||
|
)
|
||||||
|
debugAssert({ stats.downloaded + stats.notDownloaded + stats.disabled != stats.total }) {
|
||||||
|
"downloaded(${stats.downloaded}) + notDownloaded(${stats.notDownloaded}) + disabled(${stats.disabled}) != total(${stats.total})"
|
||||||
|
}
|
||||||
|
_pluginStats.postValue(Some.Success(stats))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun repos() = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY)
|
||||||
|
?: emptyArray()) + PREBUILT_REPOSITORIES
|
||||||
|
|
||||||
fun loadRepositories() {
|
fun loadRepositories() {
|
||||||
// Crashes weirdly with List<RepositoryData>
|
val urls = repos()
|
||||||
val urls = (getKey<Array<RepositoryData>>(REPOSITORIES_KEY) ?: emptyArray()) + PREBUILT_REPOSITORIES
|
|
||||||
_repositories.postValue(urls)
|
_repositories.postValue(urls)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,19 +3,21 @@ package com.lagradost.cloudstream3.ui.settings.extensions
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.plugins.PREBUILT_REPOSITORIES
|
import com.lagradost.cloudstream3.plugins.PREBUILT_REPOSITORIES
|
||||||
import kotlinx.android.synthetic.main.repository_item.view.*
|
import kotlinx.android.synthetic.main.repository_item.view.*
|
||||||
|
|
||||||
class RepoAdapter(
|
class RepoAdapter(
|
||||||
var repositories: Array<RepositoryData>,
|
|
||||||
val isSetup: Boolean,
|
val isSetup: Boolean,
|
||||||
val clickCallback: RepoAdapter.(RepositoryData) -> Unit,
|
val clickCallback: RepoAdapter.(RepositoryData) -> Unit,
|
||||||
val imageClickCallback: RepoAdapter.(RepositoryData) -> Unit,
|
val imageClickCallback: RepoAdapter.(RepositoryData) -> Unit,
|
||||||
/** In setup mode the trash icons will be replaced with download icons */
|
/** In setup mode the trash icons will be replaced with download icons */
|
||||||
) :
|
) :
|
||||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
private val repositories: MutableList<RepositoryData> = mutableListOf()
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
return RepoViewHolder(
|
return RepoViewHolder(
|
||||||
LayoutInflater.from(parent.context).inflate(R.layout.repository_item, parent, false)
|
LayoutInflater.from(parent.context).inflate(R.layout.repository_item, parent, false)
|
||||||
|
@ -42,6 +44,17 @@ class RepoAdapter(
|
||||||
return repositories.size
|
return repositories.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateList(newList: Array<RepositoryData>) {
|
||||||
|
val diffResult = DiffUtil.calculateDiff(
|
||||||
|
RepoDiffCallback(this.repositories, newList)
|
||||||
|
)
|
||||||
|
|
||||||
|
repositories.clear()
|
||||||
|
repositories.addAll(newList)
|
||||||
|
|
||||||
|
diffResult.dispatchUpdatesTo(this)
|
||||||
|
}
|
||||||
|
|
||||||
inner class RepoViewHolder(itemView: View) :
|
inner class RepoViewHolder(itemView: View) :
|
||||||
RecyclerView.ViewHolder(itemView) {
|
RecyclerView.ViewHolder(itemView) {
|
||||||
fun bind(
|
fun bind(
|
||||||
|
@ -68,4 +81,20 @@ class RepoAdapter(
|
||||||
itemView.sub_text?.text = repositoryData.url
|
itemView.sub_text?.text = repositoryData.url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RepoDiffCallback(
|
||||||
|
private val oldList: List<RepositoryData>,
|
||||||
|
private val newList: Array<RepositoryData>
|
||||||
|
) :
|
||||||
|
DiffUtil.Callback() {
|
||||||
|
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
|
||||||
|
oldList[oldItemPosition].url == newList[newItemPosition].url
|
||||||
|
|
||||||
|
override fun getOldListSize() = oldList.size
|
||||||
|
|
||||||
|
override fun getNewListSize() = newList.size
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) =
|
||||||
|
oldList[oldItemPosition] == newList[newItemPosition]
|
||||||
}
|
}
|
|
@ -41,9 +41,9 @@ class SetupFragmentExtensions : Fragment() {
|
||||||
with(context) {
|
with(context) {
|
||||||
if (this == null) return
|
if (this == null) return
|
||||||
|
|
||||||
repo_recycler_view?.adapter = RepoAdapter(PREBUILT_REPOSITORIES, true, {}, {
|
repo_recycler_view?.adapter = RepoAdapter(true, {}, {
|
||||||
PluginsViewModel.downloadAll(activity, it.url, null)
|
PluginsViewModel.downloadAll(activity, it.url, null)
|
||||||
})
|
}).apply { updateList(PREBUILT_REPOSITORIES) }
|
||||||
|
|
||||||
if (!isSetup) {
|
if (!isSetup) {
|
||||||
next_btt.setText(R.string.setup_done)
|
next_btt.setText(R.string.setup_done)
|
||||||
|
|
|
@ -1,29 +1,141 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/extensions_root"
|
android:id="@+id/extensions_root"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include layout="@layout/standard_toolbar" />
|
<include layout="@layout/standard_toolbar" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
android:id="@+id/repo_recycler_view"
|
||||||
tools:listitem="@layout/repository_item"
|
android:layout_width="match_parent"
|
||||||
android:id="@+id/repo_recycler_view"
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginBottom="80dp"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
|
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/download_storage_appbar"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:listitem="@layout/repository_item" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/plugin_storage_appbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="?attr/primaryGrayBackground"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:visibility="visible"
|
||||||
|
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:text="@string/extensions"
|
||||||
|
android:textColor="?attr/textColor" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="12dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/plugin_download"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:layout_weight="0.5"
|
||||||
|
android:background="?attr/white" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/plugin_disabled"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:layout_weight="0.10"
|
||||||
|
android:background="?attr/colorPrimary" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/plugin_not_downloaded"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:layout_weight="0.10"
|
||||||
|
android:background="?attr/grayTextColor" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:background="?attr/white" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/plugin_download_txt"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
android:textSize="12sp"
|
||||||
|
tools:text="Downloaded: 7" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:background="?attr/colorPrimary" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/plugin_disabled_txt"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
android:textSize="12sp"
|
||||||
|
tools:text="Disabled: 3" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:background="?attr/grayTextColor" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/plugin_not_downloaded_txt"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
android:textSize="12sp"
|
||||||
|
tools:text="Not downloaded 3" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
android:id="@+id/add_repo_button"
|
android:id="@+id/add_repo_button"
|
||||||
style="@style/ExtendedFloatingActionButton"
|
style="@style/ExtendedFloatingActionButton"
|
||||||
android:text="@string/add_repository"
|
android:text="@string/add_repository"
|
||||||
android:textColor="?attr/textColor"
|
android:textColor="?attr/textColor"
|
||||||
app:icon="@drawable/ic_baseline_add_24"
|
android:translationY="-80dp"
|
||||||
tools:ignore="ContentDescription" />
|
app:icon="@drawable/ic_baseline_add_24"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
|
|
@ -588,4 +588,7 @@
|
||||||
<string name="delete_repository_plugins">This will also delete all repository plugins</string>
|
<string name="delete_repository_plugins">This will also delete all repository plugins</string>
|
||||||
<string name="delete_repository">Delete repository</string>
|
<string name="delete_repository">Delete repository</string>
|
||||||
<string name="setup_extensions_subtext">Download the list of sites you want to use</string>
|
<string name="setup_extensions_subtext">Download the list of sites you want to use</string>
|
||||||
|
<string name="plugins_downloaded" formatted="true">Downloaded: %d</string>
|
||||||
|
<string name="plugins_disabled" formatted="true">Disabled: %d</string>
|
||||||
|
<string name="plugins_not_downloaded" formatted="true">Not downloaded: %d</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue