Merge branch 'master' of https://github.com/recloudstream/cloudstream into recloudstream-master
# Conflicts: # app/src/main/ic_launcher-playstore.png # app/src/main/res/mipmap-hdpi/ic_launcher.png # app/src/main/res/mipmap-hdpi/ic_launcher_round.png # app/src/main/res/mipmap-mdpi/ic_launcher.png # app/src/main/res/mipmap-mdpi/ic_launcher_round.png # app/src/main/res/mipmap-xhdpi/ic_launcher.png # app/src/main/res/mipmap-xhdpi/ic_launcher_round.png # app/src/main/res/mipmap-xxhdpi/ic_launcher.png # app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png # app/src/main/res/mipmap-xxxhdpi/ic_launcher.png # app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png # app/src/prerelease/ic_launcher-playstore.png # app/src/prerelease/res/mipmap-hdpi/ic_launcher.png # app/src/prerelease/res/mipmap-hdpi/ic_launcher_round.png # app/src/prerelease/res/mipmap-mdpi/ic_launcher.png # app/src/prerelease/res/mipmap-mdpi/ic_launcher_round.png # app/src/prerelease/res/mipmap-xhdpi/ic_launcher.png # app/src/prerelease/res/mipmap-xhdpi/ic_launcher_round.png # app/src/prerelease/res/mipmap-xxhdpi/ic_launcher.png # app/src/prerelease/res/mipmap-xxhdpi/ic_launcher_round.png # app/src/prerelease/res/mipmap-xxxhdpi/ic_launcher.png # app/src/prerelease/res/mipmap-xxxhdpi/ic_launcher_round.png
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 136 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 8.2 KiB |
|
@ -150,7 +150,11 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
* @return true if the str has launched an app task (be it successful or not)
|
* @return true if the str has launched an app task (be it successful or not)
|
||||||
* @param isWebview does not handle providers and opening download page if true. Can still add repos and login.
|
* @param isWebview does not handle providers and opening download page if true. Can still add repos and login.
|
||||||
* */
|
* */
|
||||||
fun handleAppIntentUrl(activity: FragmentActivity?, str: String?, isWebview: Boolean): Boolean =
|
fun handleAppIntentUrl(
|
||||||
|
activity: FragmentActivity?,
|
||||||
|
str: String?,
|
||||||
|
isWebview: Boolean
|
||||||
|
): Boolean =
|
||||||
with(activity) {
|
with(activity) {
|
||||||
if (str != null && this != null) {
|
if (str != null && this != null) {
|
||||||
if (str.startsWith("https://cs.repo")) {
|
if (str.startsWith("https://cs.repo")) {
|
||||||
|
@ -191,7 +195,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
val url = str.replaceFirst(appStringRepo, "https")
|
val url = str.replaceFirst(appStringRepo, "https")
|
||||||
loadRepository(url)
|
loadRepository(url)
|
||||||
return true
|
return true
|
||||||
} else if (!isWebview){
|
} else if (!isWebview) {
|
||||||
if (str.startsWith(DOWNLOAD_NAVIGATE_TO)) {
|
if (str.startsWith(DOWNLOAD_NAVIGATE_TO)) {
|
||||||
this.navigate(R.id.navigation_downloads)
|
this.navigate(R.id.navigation_downloads)
|
||||||
return true
|
return true
|
||||||
|
@ -565,9 +569,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
for (api in accountManagers) {
|
for (api in accountManagers) {
|
||||||
api.init()
|
api.init()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ioSafe {
|
|
||||||
inAppAuths.apmap { api ->
|
inAppAuths.apmap { api ->
|
||||||
try {
|
try {
|
||||||
api.initialize()
|
api.initialize()
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
package com.lagradost.cloudstream3.plugins
|
package com.lagradost.cloudstream3.plugins
|
||||||
|
|
||||||
|
import android.app.*
|
||||||
import dalvik.system.PathClassLoader
|
import dalvik.system.PathClassLoader
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import android.content.res.AssetManager
|
import android.content.res.AssetManager
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import android.app.Activity
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import androidx.core.net.toUri
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||||
|
@ -25,7 +31,9 @@ import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES
|
import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES
|
||||||
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.ExtractorApi
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
|
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
|
||||||
import com.lagradost.cloudstream3.utils.extractorApis
|
import com.lagradost.cloudstream3.utils.extractorApis
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
@ -38,6 +46,9 @@ import java.util.*
|
||||||
const val PLUGINS_KEY = "PLUGINS_KEY"
|
const val PLUGINS_KEY = "PLUGINS_KEY"
|
||||||
const val PLUGINS_KEY_LOCAL = "PLUGINS_KEY_LOCAL"
|
const val PLUGINS_KEY_LOCAL = "PLUGINS_KEY_LOCAL"
|
||||||
|
|
||||||
|
const val EXTENSIONS_CHANNEL_ID = "cloudstream3.extensions"
|
||||||
|
const val EXTENSIONS_CHANNEL_NAME = "Extensions"
|
||||||
|
const val EXTENSIONS_CHANNEL_DESCRIPT = "Extension notification channel"
|
||||||
|
|
||||||
// Data class for internal storage
|
// Data class for internal storage
|
||||||
data class PluginData(
|
data class PluginData(
|
||||||
|
@ -78,6 +89,8 @@ object PluginManager {
|
||||||
|
|
||||||
const val TAG = "PluginManager"
|
const val TAG = "PluginManager"
|
||||||
|
|
||||||
|
private var hasCreatedNotChanel = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store data about the plugin for fetching later
|
* Store data about the plugin for fetching later
|
||||||
* */
|
* */
|
||||||
|
@ -220,8 +233,11 @@ object PluginManager {
|
||||||
"Outdated plugins: ${outdatedPlugins.filter { it.isOutdated }}"
|
"Outdated plugins: ${outdatedPlugins.filter { it.isOutdated }}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val updatedPlugins = mutableListOf<String>()
|
||||||
|
|
||||||
outdatedPlugins.apmap { pluginData ->
|
outdatedPlugins.apmap { pluginData ->
|
||||||
if (pluginData.isDisabled) {
|
if (pluginData.isDisabled) {
|
||||||
|
//updatedPlugins.add(activity.getString(R.string.single_plugin_disabled, pluginData.onlineData.second.name))
|
||||||
unloadPlugin(pluginData.savedData.filePath)
|
unloadPlugin(pluginData.savedData.filePath)
|
||||||
} else if (pluginData.isOutdated) {
|
} else if (pluginData.isOutdated) {
|
||||||
downloadAndLoadPlugin(
|
downloadAndLoadPlugin(
|
||||||
|
@ -229,10 +245,17 @@ object PluginManager {
|
||||||
pluginData.onlineData.second.url,
|
pluginData.onlineData.second.url,
|
||||||
pluginData.savedData.internalName,
|
pluginData.savedData.internalName,
|
||||||
pluginData.onlineData.first
|
pluginData.onlineData.first
|
||||||
)
|
).let { success ->
|
||||||
|
if (success)
|
||||||
|
updatedPlugins.add(pluginData.onlineData.second.name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
createNotification(activity, updatedPlugins)
|
||||||
|
}
|
||||||
|
|
||||||
ioSafe {
|
ioSafe {
|
||||||
afterPluginsLoadedEvent.invoke(true)
|
afterPluginsLoadedEvent.invoke(true)
|
||||||
}
|
}
|
||||||
|
@ -438,4 +461,59 @@ object PluginManager {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Context.createNotificationChannel() {
|
||||||
|
hasCreatedNotChanel = true
|
||||||
|
// Create the NotificationChannel, but only on API 26+ because
|
||||||
|
// the NotificationChannel class is new and not in the support library
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
val name = EXTENSIONS_CHANNEL_NAME //getString(R.string.channel_name)
|
||||||
|
val descriptionText = EXTENSIONS_CHANNEL_DESCRIPT//getString(R.string.channel_description)
|
||||||
|
val importance = NotificationManager.IMPORTANCE_LOW
|
||||||
|
val channel = NotificationChannel(EXTENSIONS_CHANNEL_ID, name, importance).apply {
|
||||||
|
description = descriptionText
|
||||||
|
}
|
||||||
|
// Register the channel with the system
|
||||||
|
val notificationManager: NotificationManager =
|
||||||
|
this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
notificationManager.createNotificationChannel(channel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private fun createNotification(
|
||||||
|
context: Context,
|
||||||
|
extensionNames: List<String>
|
||||||
|
): Notification? {
|
||||||
|
try {
|
||||||
|
if (extensionNames.isEmpty()) return null
|
||||||
|
|
||||||
|
val content = extensionNames.joinToString(", ")
|
||||||
|
// main { // DON'T WANT TO SLOW IT DOWN
|
||||||
|
val builder = NotificationCompat.Builder(context, EXTENSIONS_CHANNEL_ID)
|
||||||
|
.setAutoCancel(false)
|
||||||
|
.setColorized(true)
|
||||||
|
.setOnlyAlertOnce(true)
|
||||||
|
.setSilent(true)
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||||
|
.setColor(context.colorFromAttribute(R.attr.colorPrimary))
|
||||||
|
.setContentTitle(context.getString(R.string.plugins_updated, extensionNames.size))
|
||||||
|
.setSmallIcon(R.drawable.ic_baseline_extension_24)
|
||||||
|
.setStyle(NotificationCompat.BigTextStyle()
|
||||||
|
.bigText(content))
|
||||||
|
.setContentText(content)
|
||||||
|
|
||||||
|
if (!hasCreatedNotChanel) {
|
||||||
|
context.createNotificationChannel()
|
||||||
|
}
|
||||||
|
|
||||||
|
val notification = builder.build()
|
||||||
|
with(NotificationManagerCompat.from(context)) {
|
||||||
|
// notificationId is a unique int for each notification that you must define
|
||||||
|
notify((System.currentTimeMillis()/1000).toInt(), notification)
|
||||||
|
}
|
||||||
|
return notification
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logError(e)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -40,13 +40,15 @@ class WebviewFragment : Fragment() {
|
||||||
return super.shouldOverrideUrlLoading(view, request)
|
return super.shouldOverrideUrlLoading(view, request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebViewResolver.webViewUserAgent = web_view.settings.userAgentString
|
||||||
|
|
||||||
web_view.addJavascriptInterface(RepoApi(activity), "RepoApi")
|
web_view.addJavascriptInterface(RepoApi(activity), "RepoApi")
|
||||||
web_view.settings.javaScriptEnabled = true
|
web_view.settings.javaScriptEnabled = true
|
||||||
web_view.settings.userAgentString = USER_AGENT
|
web_view.settings.userAgentString = USER_AGENT
|
||||||
web_view.settings.domStorageEnabled = true
|
web_view.settings.domStorageEnabled = true
|
||||||
|
// WebView.setWebContentsDebuggingEnabled(true)
|
||||||
|
|
||||||
WebViewResolver.webViewUserAgent = web_view.settings.userAgentString
|
|
||||||
// web_view.settings.userAgentString = USER_AGENT
|
|
||||||
web_view.loadUrl(url)
|
web_view.loadUrl(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -611,6 +611,7 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
|
||||||
player_lock?.isGone = !isShowing
|
player_lock?.isGone = !isShowing
|
||||||
//player_media_route_button?.isClickable = !isGone
|
//player_media_route_button?.isClickable = !isGone
|
||||||
player_go_back_holder?.isGone = isGone
|
player_go_back_holder?.isGone = isGone
|
||||||
|
player_sources_btt?.isGone = isGone
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateLockUI() {
|
private fun updateLockUI() {
|
||||||
|
|
|
@ -60,7 +60,7 @@ class EpisodeAdapter(
|
||||||
private val clickCallback: (EpisodeClickEvent) -> Unit,
|
private val clickCallback: (EpisodeClickEvent) -> Unit,
|
||||||
private val downloadClickCallback: (DownloadClickEvent) -> Unit,
|
private val downloadClickCallback: (DownloadClickEvent) -> Unit,
|
||||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
private var cardList: MutableList<ResultEpisode> = mutableListOf()
|
var cardList: MutableList<ResultEpisode> = mutableListOf()
|
||||||
|
|
||||||
private val mBoundViewHolders: HashSet<DownloadButtonViewHolder> = HashSet()
|
private val mBoundViewHolders: HashSet<DownloadButtonViewHolder> = HashSet()
|
||||||
private fun getAllBoundViewHolders(): Set<DownloadButtonViewHolder?>? {
|
private fun getAllBoundViewHolders(): Set<DownloadButtonViewHolder?>? {
|
||||||
|
@ -239,7 +239,6 @@ class EpisodeAdapter(
|
||||||
|
|
||||||
itemView.setOnLongClickListener {
|
itemView.setOnLongClickListener {
|
||||||
clickCallback.invoke(EpisodeClickEvent(ACTION_SHOW_OPTIONS, card))
|
clickCallback.invoke(EpisodeClickEvent(ACTION_SHOW_OPTIONS, card))
|
||||||
|
|
||||||
return@setOnLongClickListener true
|
return@setOnLongClickListener true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@ import kotlinx.android.synthetic.main.fragment_result.result_vpn
|
||||||
import kotlinx.android.synthetic.main.fragment_result_swipe.*
|
import kotlinx.android.synthetic.main.fragment_result_swipe.*
|
||||||
import kotlinx.android.synthetic.main.fragment_result_tv.*
|
import kotlinx.android.synthetic.main.fragment_result_tv.*
|
||||||
import kotlinx.android.synthetic.main.result_sync.*
|
import kotlinx.android.synthetic.main.result_sync.*
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
|
|
||||||
|
@ -293,7 +294,7 @@ open class ResultFragment : ResultTrailerPlayer() {
|
||||||
result_reload_connection_open_in_browser?.isVisible = true
|
result_reload_connection_open_in_browser?.isVisible = true
|
||||||
}
|
}
|
||||||
2 -> {
|
2 -> {
|
||||||
result_bookmark_fab?.isGone = isTvSettings()
|
result_bookmark_fab?.isGone = isTrueTvSettings()
|
||||||
result_bookmark_fab?.extend()
|
result_bookmark_fab?.extend()
|
||||||
//if (result_bookmark_button?.context?.isTrueTvSettings() == true) {
|
//if (result_bookmark_button?.context?.isTrueTvSettings() == true) {
|
||||||
// when {
|
// when {
|
||||||
|
@ -412,7 +413,39 @@ open class ResultFragment : ResultTrailerPlayer() {
|
||||||
is ResourceSome.Success -> {
|
is ResourceSome.Success -> {
|
||||||
result_episodes?.isVisible = true
|
result_episodes?.isVisible = true
|
||||||
result_episode_loading?.isVisible = false
|
result_episode_loading?.isVisible = false
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Okay so what is this fuckery?
|
||||||
|
* Basically Android TV will crash if you request a new focus while
|
||||||
|
* the adapter gets updated.
|
||||||
|
*
|
||||||
|
* This means that if you load thumbnails and request a next focus at the same time
|
||||||
|
* the app will crash without any way to catch it!
|
||||||
|
*
|
||||||
|
* How to bypass this?
|
||||||
|
* This code basically steals the focus for 500ms and puts it in an inescapable view
|
||||||
|
* then lets out the focus by requesting focus to result_episodes
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Do not use this.isTv, that is the player
|
||||||
|
val isTv = isTvSettings()
|
||||||
|
val hasEpisodes =
|
||||||
|
!(result_episodes?.adapter as? EpisodeAdapter?)?.cardList.isNullOrEmpty()
|
||||||
|
|
||||||
|
if (isTv && hasEpisodes) {
|
||||||
|
// Make it impossible to focus anywhere else!
|
||||||
|
temporary_no_focus?.isFocusable = true
|
||||||
|
temporary_no_focus?.requestFocus()
|
||||||
|
}
|
||||||
|
|
||||||
(result_episodes?.adapter as? EpisodeAdapter?)?.updateList(episodes.value)
|
(result_episodes?.adapter as? EpisodeAdapter?)?.updateList(episodes.value)
|
||||||
|
|
||||||
|
if (isTv && hasEpisodes) main {
|
||||||
|
delay(500)
|
||||||
|
temporary_no_focus?.isFocusable = false
|
||||||
|
// This might make some people sad as it changes the focus when leaving an episode :(
|
||||||
|
result_episodes?.requestFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -458,7 +491,14 @@ open class ResultFragment : ResultTrailerPlayer() {
|
||||||
val storedData = getStoredData(activity ?: context ?: return) ?: return
|
val storedData = getStoredData(activity ?: context ?: return) ?: return
|
||||||
|
|
||||||
//viewModel.clear()
|
//viewModel.clear()
|
||||||
viewModel.load(activity, storedData.url ?: return, storedData.apiName, storedData.showFillers, storedData.dubStatus, storedData.start)
|
viewModel.load(
|
||||||
|
activity,
|
||||||
|
storedData.url ?: return,
|
||||||
|
storedData.apiName,
|
||||||
|
storedData.showFillers,
|
||||||
|
storedData.dubStatus,
|
||||||
|
storedData.start
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -916,7 +956,14 @@ open class ResultFragment : ResultTrailerPlayer() {
|
||||||
|
|
||||||
if (storedData?.url != null) {
|
if (storedData?.url != null) {
|
||||||
result_reload_connectionerror.setOnClickListener {
|
result_reload_connectionerror.setOnClickListener {
|
||||||
viewModel.load(activity, storedData.url, storedData.apiName, storedData.showFillers, storedData.dubStatus, storedData.start)
|
viewModel.load(
|
||||||
|
activity,
|
||||||
|
storedData.url,
|
||||||
|
storedData.apiName,
|
||||||
|
storedData.showFillers,
|
||||||
|
storedData.dubStatus,
|
||||||
|
storedData.start
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
result_reload_connection_open_in_browser?.setOnClickListener {
|
result_reload_connection_open_in_browser?.setOnClickListener {
|
||||||
|
@ -952,7 +999,14 @@ open class ResultFragment : ResultTrailerPlayer() {
|
||||||
|
|
||||||
if (restart || !viewModel.hasLoaded()) {
|
if (restart || !viewModel.hasLoaded()) {
|
||||||
//viewModel.clear()
|
//viewModel.clear()
|
||||||
viewModel.load(activity, storedData.url, storedData.apiName, storedData.showFillers, storedData.dubStatus, storedData.start)
|
viewModel.load(
|
||||||
|
activity,
|
||||||
|
storedData.url,
|
||||||
|
storedData.apiName,
|
||||||
|
storedData.showFillers,
|
||||||
|
storedData.dubStatus,
|
||||||
|
storedData.start
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.6 MiB |
|
@ -420,14 +420,14 @@
|
||||||
|
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:nextFocusRight="@id/result_bookmark_button"
|
|
||||||
android:id="@+id/result_movie_progress_downloaded_holder"
|
android:id="@+id/result_movie_progress_downloaded_holder"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:layout_marginEnd="5dp"
|
android:layout_marginEnd="5dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:minWidth="250dp">
|
android:minWidth="250dp"
|
||||||
|
android:nextFocusRight="@id/result_bookmark_button">
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/result_download_movie"
|
android:id="@+id/result_download_movie"
|
||||||
|
@ -510,17 +510,17 @@
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:nextFocusLeft="@id/result_movie_progress_downloaded_holder"
|
|
||||||
android:nextFocusDown="@id/result_resume_series_button_play"
|
|
||||||
|
|
||||||
android:id="@+id/result_bookmark_button"
|
android:id="@+id/result_bookmark_button"
|
||||||
style="@style/BlackButton"
|
style="@style/BlackButton"
|
||||||
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="5dp"
|
||||||
android:layout_marginEnd="5dp"
|
android:layout_marginEnd="5dp"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:minWidth="250dp"
|
android:minWidth="250dp"
|
||||||
|
android:nextFocusLeft="@id/result_movie_progress_downloaded_holder"
|
||||||
|
android:nextFocusDown="@id/result_resume_series_button_play"
|
||||||
android:text="@string/type_none"
|
android:text="@string/type_none"
|
||||||
android:visibility="visible" />
|
android:visibility="visible" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -753,6 +753,16 @@
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
tools:listitem="@layout/result_episode" />
|
tools:listitem="@layout/result_episode" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/temporary_no_focus"
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:focusable="false"
|
||||||
|
android:nextFocusLeft="@id/temporary_no_focus"
|
||||||
|
android:nextFocusRight="@id/temporary_no_focus"
|
||||||
|
android:nextFocusUp="@id/temporary_no_focus"
|
||||||
|
android:nextFocusDown="@id/temporary_no_focus" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.0 KiB |
|
@ -455,4 +455,5 @@
|
||||||
<string name="extension_types">Wspierane</string>
|
<string name="extension_types">Wspierane</string>
|
||||||
<string name="extension_language">Język</string>
|
<string name="extension_language">Język</string>
|
||||||
<string name="extension_install_first">Najpierw zainstaluj rozszerzenie</string>
|
<string name="extension_install_first">Najpierw zainstaluj rozszerzenie</string>
|
||||||
|
<string name="plugins_updated">Zaaktualizowano %d rozszerzeń</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -601,6 +601,7 @@
|
||||||
<string name="plugins_downloaded" formatted="true">Downloaded: %d</string>
|
<string name="plugins_downloaded" formatted="true">Downloaded: %d</string>
|
||||||
<string name="plugins_disabled" formatted="true">Disabled: %d</string>
|
<string name="plugins_disabled" formatted="true">Disabled: %d</string>
|
||||||
<string name="plugins_not_downloaded" formatted="true">Not downloaded: %d</string>
|
<string name="plugins_not_downloaded" formatted="true">Not downloaded: %d</string>
|
||||||
|
<string name="plugins_updated" formatted="true">Updated %d plugins</string>
|
||||||
<string name="blank_repo_message">Add a repository to install site extensions</string>
|
<string name="blank_repo_message">Add a repository to install site extensions</string>
|
||||||
<string name="view_public_repositories_button">View community repositories</string>
|
<string name="view_public_repositories_button">View community repositories</string>
|
||||||
<string name="view_public_repositories_button_short">Public list</string>
|
<string name="view_public_repositories_button_short">Public list</string>
|
||||||
|
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.0 KiB |