Compare commits

...

5 Commits

Author SHA1 Message Date
IndusAryan b4468fb206
Merge f89aad3e95 into 138e1a1f0e 2024-04-28 07:01:45 +05:30
Luna712 138e1a1f0e
Don't check year when checking duplicates if year is empty (#1060)
Some sources don't use year which makes this not match when it really should match
2024-04-27 22:40:15 +02:00
IndusAryan f89aad3e95 Merge remote-tracking branch 'origin/master' into dialog2
# Conflicts:
#	app/src/main/res/values/strings.xml
2024-04-14 11:55:37 +05:30
IndusAryan aff24843a0 fix import 2024-04-03 19:33:10 +05:30
IndusAryan 71b61733e4 new dialog on add repo and redirection 2024-04-03 18:43:51 +05:30
12 changed files with 84 additions and 42 deletions

View File

@ -134,7 +134,7 @@ import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult
import com.lagradost.cloudstream3.utils.AppUtils.setDefaultFocus
import com.lagradost.cloudstream3.utils.BackupUtils.backup
import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.BiometricCallback
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.biometricPrompt
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.deviceHasPasswordPinLock
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.isAuthEnabled
@ -294,8 +294,7 @@ var app = Requests(responseParser = object : ResponseParser {
defaultHeaders = mapOf("user-agent" to USER_AGENT)
}
class MainActivity : AppCompatActivity(), ColorPickerDialogListener,
BiometricAuthenticator.BiometricAuthCallback {
class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricCallback {
companion object {
const val TAG = "MAINACT"
const val ANIMATED_OUTLINE: Boolean = false

View File

@ -23,6 +23,7 @@ import com.lagradost.cloudstream3.ui.settings.Globals.PHONE
import com.lagradost.cloudstream3.ui.settings.Globals.TV
import com.lagradost.cloudstream3.ui.settings.Globals.isLayout
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.BiometricCallback
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.biometricPrompt
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.deviceHasPasswordPinLock
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.isAuthEnabled
@ -33,7 +34,7 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper.selectedKeyIndex
import com.lagradost.cloudstream3.utils.DataStoreHelper.setAccount
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
class AccountSelectActivity : AppCompatActivity(), BiometricAuthenticator.BiometricAuthCallback {
class AccountSelectActivity : AppCompatActivity(), BiometricCallback {
lateinit var viewModel: AccountViewModel

View File

@ -1099,13 +1099,14 @@ class ResultViewModel2 : ViewModel() {
val duplicateEntries = data.filter { it: DataStoreHelper.LibrarySearchResponse ->
val librarySyncData = it.syncData
val yearCheck = year == it.year || year == null || it.year == null
val checks = listOf(
{ imdbId != null && getImdbIdFromSyncData(librarySyncData) == imdbId },
{ tmdbId != null && getTMDbIdFromSyncData(librarySyncData) == tmdbId },
{ malId != null && librarySyncData?.get(AccountManager.malApi.idPrefix) == malId },
{ aniListId != null && librarySyncData?.get(AccountManager.aniListApi.idPrefix) == aniListId },
{ normalizedName == normalizeString(it.name) && year == it.year }
{ normalizedName == normalizeString(it.name) && yearCheck }
)
checks.any { it() }

View File

@ -40,7 +40,7 @@ import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setTool
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
import com.lagradost.cloudstream3.utils.AppUtils.html
import com.lagradost.cloudstream3.utils.BackupUtils
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.BiometricCallback
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.authCallback
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.biometricPrompt
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.deviceHasPasswordPinLock
@ -53,7 +53,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
import com.lagradost.cloudstream3.utils.UIHelper.setImage
class SettingsAccount : PreferenceFragmentCompat(), BiometricAuthenticator.BiometricAuthCallback {
class SettingsAccount : PreferenceFragmentCompat(), BiometricCallback {
companion object {
/** Used by nginx plugin too */
fun showLoginInfo(

View File

@ -33,7 +33,7 @@ import com.lagradost.cloudstream3.ui.settings.Globals.TV
import com.lagradost.cloudstream3.ui.settings.Globals.isLayout
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setToolBarScrollFlags
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
import com.lagradost.cloudstream3.utils.AppUtils.downloadAllPluginsDialog
import com.lagradost.cloudstream3.utils.AppUtils.addRepositoryDialog
import com.lagradost.cloudstream3.utils.AppUtils.setDefaultFocus
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.Coroutines.main
@ -273,10 +273,8 @@ class ExtensionsFragment : Fragment() {
if (plugins.isNullOrEmpty()) {
showToast(R.string.no_plugins_found_error, Toast.LENGTH_LONG)
} else {
this@ExtensionsFragment.activity?.downloadAllPluginsDialog(
url,
fixedName
)
this@ExtensionsFragment.activity?.addRepositoryDialog(
fixedName, true)
}
}
}

View File

@ -10,6 +10,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings
import com.lagradost.cloudstream3.AllLanguagesName
import com.lagradost.cloudstream3.BuildConfig
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.databinding.FragmentPluginsBinding
@ -70,6 +71,8 @@ class PluginsFragment : Fragment() {
val name = arguments?.getString(PLUGINS_BUNDLE_NAME)
val url = arguments?.getString(PLUGINS_BUNDLE_URL)
val isLocal = arguments?.getBoolean(PLUGINS_BUNDLE_LOCAL) == true
// download all extensions button
val downloadAllButton = binding?.settingsToolbar?.menu?.findItem(R.id.download_all)
if (url == null || name == null) {
activity?.onBackPressedDispatcher?.onBackPressed()
@ -171,7 +174,7 @@ class PluginsFragment : Fragment() {
if (isLocal) {
// No download button and no categories on local
binding?.settingsToolbar?.menu?.findItem(R.id.download_all)?.isVisible = false
downloadAllButton?.isVisible = false
binding?.settingsToolbar?.menu?.findItem(R.id.lang_filter)?.isVisible = false
pluginViewModel.updatePluginListLocal()
@ -179,6 +182,10 @@ class PluginsFragment : Fragment() {
} else {
pluginViewModel.updatePluginList(context, url)
binding?.tvtypesChipsScroll?.root?.isVisible = true
// not needed for users but may be useful for devs
downloadAllButton?.isVisible = BuildConfig.DEBUG
bindChips(
binding?.tvtypesChipsScroll?.tvtypesChips,

View File

@ -62,6 +62,7 @@ import com.lagradost.cloudstream3.syncproviders.providers.Kitsu
import com.lagradost.cloudstream3.ui.WebviewFragment
import com.lagradost.cloudstream3.ui.result.ResultFragment
import com.lagradost.cloudstream3.ui.settings.Globals
import com.lagradost.cloudstream3.ui.settings.extensions.PluginsFragment
import com.lagradost.cloudstream3.ui.settings.extensions.PluginsViewModel.Companion.downloadAll
import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
@ -386,7 +387,7 @@ object AppUtils {
)
}
afterRepositoryLoadedEvent.invoke(true)
downloadAllPluginsDialog(url, repo.name)
addRepositoryDialog(repo.name, false)
}
}
@ -429,25 +430,37 @@ object AppUtils {
}
}
fun Activity.addRepositoryDialog(repositoryName: String, isExtensionsFragment: Boolean) {
val message = String.format(resources.getString(
R.string.download_all_plugins_from_repo), repositoryName)
val repos = RepositoryManager.getRepositories()
fun Activity.downloadAllPluginsDialog(repositoryUrl: String, repositoryName: String) {
runOnUiThread {
val context = this
val builder: AlertDialog.Builder = AlertDialog.Builder(this)
builder.setTitle(
repositoryName
)
builder.setMessage(
R.string.download_all_plugins_from_repo
)
builder.apply {
setPositiveButton(R.string.download) { _, _ ->
downloadAll(context, repositoryUrl, null)
// navigate to newly added repository on pressing OK
fun openAddedRepo() {
// don't redirect if user is adding from add repo button
if (!isExtensionsFragment && repos.isNotEmpty()) {
normalSafeApiCall { navigate(
R.id.navigation_home_to_navigation_settings_plugins,
PluginsFragment.newInstance(
repositoryName,
repos.last().url,
false))
}
setNegativeButton(R.string.no) { _, _ -> }
}
builder.show().setDefaultFocus()
}
runOnUiThread {
val builder : AlertDialog.Builder = AlertDialog.Builder(this)
builder.apply {
setTitle(repositoryName)
setMessage(message)
setPositiveButton(R.string.ok) { _, _ ->
openAddedRepo()
}
setCancelable(false)
show().setDefaultFocus()
}
}
}

View File

@ -26,7 +26,7 @@ object BiometricAuthenticator {
private var biometricManager: BiometricManager? = null
var biometricPrompt: BiometricPrompt? = null
var promptInfo: BiometricPrompt.PromptInfo? = null
var authCallback: BiometricAuthCallback? = null // listen to authentication success
var authCallback: BiometricCallback? = null // listen to authentication success
private fun initializeBiometrics(activity: Activity) {
val executor = ContextCompat.getMainExecutor(activity)
@ -141,14 +141,14 @@ object BiometricAuthenticator {
// function to start authentication in any fragment or activity
fun startBiometricAuthentication(activity: Activity, title: Int, setDeviceCred: Boolean) {
initializeBiometrics(activity)
authCallback = activity as? BiometricAuthCallback
authCallback = activity as? BiometricCallback
if (isBiometricHardWareAvailable()) {
authCallback = activity as? BiometricAuthCallback
authCallback = activity as? BiometricCallback
authenticationDialog(activity, title, setDeviceCred)
promptInfo?.let { biometricPrompt?.authenticate(it) }
} else {
if (deviceHasPasswordPinLock(activity)) {
authCallback = activity as? BiometricAuthCallback
authCallback = activity as? BiometricCallback
authenticationDialog(activity, R.string.password_pin_authentication_title, true)
promptInfo?.let { biometricPrompt?.authenticate(it) }
@ -165,7 +165,7 @@ object BiometricAuthenticator {
}
}
interface BiometricAuthCallback {
interface BiometricCallback {
fun onAuthenticationSuccess()
fun onAuthenticationError()
}

View File

@ -21,5 +21,6 @@
android:id="@+id/download_all"
android:icon="@drawable/netflix_download"
android:title="@string/batch_download"
app:showAsAction="collapseActionView|ifRoom" />
app:showAsAction="collapseActionView|ifRoom"
android:visible="false"/>
</menu>

View File

@ -273,6 +273,27 @@
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" />
<action
android:id="@+id/navigation_home_to_navigation_settings_plugins"
app:destination="@id/navigation_settings_plugins"
app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim">
<argument
android:name="name"
android:defaultValue="@null"
app:argType="string" />
<argument
android:name="url"
android:defaultValue="@null"
app:argType="string" />
<argument
android:name="isLocal"
android:defaultValue="false"
app:argType="boolean" />
</action>
</fragment>
<fragment

View File

@ -349,6 +349,9 @@
<string name="live_singular">Livestream</string>
<string name="nsfw_singular">NSFW</string>
<string name="other_singular">Video</string>
<string name="music_singlar">Music</string>
<string name="audio_book_singular">Audio Book</string>
<string name="custom_media_singluar">Media</string>
<string name="source_error">Source error</string>
<string name="remote_error">Remote error</string>
<string name="render_error">Renderer error</string>
@ -607,7 +610,8 @@
<string name="view_public_repositories_button">View community repositories</string>
<string name="view_public_repositories_button_short">Public list</string>
<string name="uppercase_all_subtitles">Uppercase all subtitles</string>
<string name="download_all_plugins_from_repo">Download all plugins from this repository?</string>
<string name="download_all_plugins_from_repo">%1$s has been added. You can install your desired extensions from 𝗦𝗲𝘁𝘁𝗶𝗻𝗴𝘀 > 𝗘𝘅𝘁𝗲𝗻𝘀𝗶𝗼𝗻𝘀 > %1$s.
CloudStream 3 does not takes any responsibility for using third-party extensions neither provides support for them.</string>
<string name="single_plugin_disabled" formatted="true">%s (Disabled)</string>
<string name="tracks">Tracks</string>
<string name="audio_tracks">Audio tracks</string>
@ -763,10 +767,7 @@
<string name="password_pin_authentication_title">Password/PIN Authentication</string>
<string name="biometric_unsupported">Biometric authentication is not supported on this device</string>
<string name="biometric_setting_summary">Unlock the app with Fingerprint, Face ID, PIN, Pattern and Password.</string>
<string name="biometric_prompt_description">This screen was closed due to multiple failed attempts. Please restart the application.</string>
<string name="biometric_prompt_description">After a few failed attempts, the prompt will close. Simply restart the app to try again.</string>
<string name="biometric_warning">Your CloudStream data has been backed up now. Although the possibility of this is very low, all devices can behave differently. In the rare case, that you get locked out from accessing the app, clear the app data completely and restore from a backup. We are very sorry for any inconvenience arising from this.</string>
<string name="music_singlar">Music</string>
<string name="audio_book_singular">Audio Book</string>
<string name="custom_media_singluar">Media</string>
<string name="reset_btn">Reset</string>
</resources>

View File

@ -1,6 +1,6 @@
#Fri Apr 30 17:11:15 CEST 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME