From 2b29e8078fe540a91ccaf6b9f91b9263a80acb6f Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Sun, 13 Nov 2022 01:40:49 +0100 Subject: [PATCH] Added intent to start searching --- app/src/main/AndroidManifest.xml | 11 +++++ .../lagradost/cloudstream3/MainActivity.kt | 42 +++++++++++++++---- .../syncproviders/AccountManager.kt | 3 ++ .../cloudstream3/ui/search/SearchFragment.kt | 19 ++++++++- .../main/res/navigation/mobile_navigation.xml | 7 +++- 5 files changed, 72 insertions(+), 10 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 47676059..ae8479fe 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -110,6 +110,17 @@ + + + + + + + + + + + diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index ff74d6cc..b999199f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -16,11 +16,9 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible import androidx.fragment.app.FragmentActivity -import androidx.navigation.NavController -import androidx.navigation.NavDestination +import androidx.navigation.* import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavGraph.Companion.findStartDestination -import androidx.navigation.NavOptions import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.setupWithNavController import androidx.preference.PreferenceManager @@ -44,6 +42,7 @@ import com.lagradost.cloudstream3.CommonActivity.onUserLeaveHint import com.lagradost.cloudstream3.CommonActivity.showToast import com.lagradost.cloudstream3.CommonActivity.updateLocale import com.lagradost.cloudstream3.mvvm.logError +import com.lagradost.cloudstream3.mvvm.normalSafeApiCall import com.lagradost.cloudstream3.network.initClient import com.lagradost.cloudstream3.plugins.PluginManager import com.lagradost.cloudstream3.plugins.PluginManager.loadSinglePlugin @@ -52,9 +51,11 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.OAuth2A import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.accountManagers import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appString import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringRepo +import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringSearch import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.inAppAuths import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO +import com.lagradost.cloudstream3.ui.search.SearchFragment import com.lagradost.cloudstream3.ui.search.SearchResultBuilder import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings @@ -88,11 +89,9 @@ import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.fragment_result_swipe.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import okhttp3.ConnectionSpec -import okhttp3.OkHttpClient -import okhttp3.internal.applyConnectionSpec import java.io.File import java.net.URI +import java.net.URLDecoder import java.nio.charset.Charset import kotlin.reflect.KClass @@ -147,7 +146,7 @@ val VLC = ResultResume( val MPV = ResultResume( MPV_PACKAGE, //"is.xyz.mpv.MPVActivity.result", // resume not working :pensive: - position = "position", + position = "position", duration = "duration", ) @@ -188,6 +187,15 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { companion object { const val TAG = "MAINACT" + /** + * Setting this will automatically enter the query in the search + * next time the search fragment is opened. + * This variable will clear itself after one use. Null does nothing. + * + * This is a very bad solution but I was unable to find a better one. + **/ + private var nextSearchQuery: String? = null + /** * Fires every time a new batch of plugins have been loaded, no guarantee about how often this is run and on which thread * */ @@ -206,6 +214,9 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { isWebview: Boolean ): Boolean = with(activity) { + // Invalid URIs can crash + fun safeURI(uri: String) = normalSafeApiCall { URI(uri) } + if (str != null && this != null) { if (str.startsWith("https://cs.repo")) { val realUrl = "https://" + str.substringAfter("?") @@ -241,10 +252,14 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { return true } } - } else if (URI(str).scheme == appStringRepo) { + } else if (safeURI(str)?.scheme == appStringRepo) { val url = str.replaceFirst(appStringRepo, "https") loadRepository(url) return true + } else if (safeURI(str)?.scheme == appStringSearch) { + nextSearchQuery = + URLDecoder.decode(str.substringAfter("$appStringSearch://"), "UTF-8") + nav_view.selectedItemId = R.id.navigation_search } else if (!isWebview) { if (str.startsWith(DOWNLOAD_NAVIGATE_TO)) { this.navigate(R.id.navigation_downloads) @@ -619,6 +634,17 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController + + navController.addOnDestinationChangedListener { _: NavController, navDestination: NavDestination, bundle: Bundle? -> + // Intercept search and add a query + if (navDestination.matchDestination(R.id.navigation_search) && !nextSearchQuery.isNullOrBlank()) { + bundle?.apply { + this.putString(SearchFragment.SEARCH_QUERY, nextSearchQuery) + nextSearchQuery = null + } + } + } + //val navController = findNavController(R.id.nav_host_fragment) /*navOptions = NavOptions.Builder() diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AccountManager.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AccountManager.kt index 825ff673..388e1774 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AccountManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AccountManager.kt @@ -43,6 +43,9 @@ abstract class AccountManager(private val defIndex: Int) : AuthAPI { const val appString = "cloudstreamapp" const val appStringRepo = "cloudstreamrepo" + // Instantly start the search given a query + const val appStringSearch = "cloudstreamsearch" + val unixTime: Long get() = System.currentTimeMillis() / 1000L val unixTimeMs: Long diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt index 4da88af7..4e59e6a0 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt @@ -73,6 +73,14 @@ class SearchFragment : Fragment() { } } } + + const val SEARCH_QUERY = "search_query" + + fun newInstance(query: String): Bundle { + return Bundle().apply { + putString(SEARCH_QUERY, query) + } + } } private val searchViewModel: SearchViewModel by activityViewModels() @@ -132,7 +140,8 @@ class SearchFragment : Fragment() { val default = enumValues().sorted().filter { it != TvType.NSFW } .map { it.ordinal.toString() }.toSet() val preferredTypes = (PreferenceManager.getDefaultSharedPreferences(ctx) - .getStringSet(this.getString(R.string.prefer_media_type_key), default)?.ifEmpty { default } ?: default) + .getStringSet(this.getString(R.string.prefer_media_type_key), default) + ?.ifEmpty { default } ?: default) .mapNotNull { it.toIntOrNull() ?: return@mapNotNull null } val settings = ctx.getApiSettings() @@ -487,6 +496,14 @@ class SearchFragment : Fragment() { search_master_recycler?.adapter = masterAdapter search_master_recycler?.layoutManager = GridLayoutManager(context, 1) + // Automatically search the specified query, this allows the app search to launch from intent + arguments?.getString(SEARCH_QUERY)?.let { query -> + if (query.isBlank()) return@let + main_search?.setQuery(query, true) + // Clear the query as to not make it request the same query every time the page is opened + arguments?.putString(SEARCH_QUERY, null) + } + // SubtitlesFragment.push(activity) //searchViewModel.search("iron man") //(activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro") diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index 6ae2fa04..14d750a0 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -274,7 +274,12 @@ app:exitAnim="@anim/exit_anim" app:popEnterAnim="@anim/enter_anim" app:popExitAnim="@anim/exit_anim" - tools:layout="@layout/fragment_search" /> + tools:layout="@layout/fragment_search"> + +