mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	Added intent to start searching
This commit is contained in:
		
							parent
							
								
									9a93b375f3
								
							
						
					
					
						commit
						2b29e8078f
					
				
					 5 changed files with 72 additions and 10 deletions
				
			
		|  | @ -110,6 +110,17 @@ | |||
| 
 | ||||
|                 <data android:scheme="cloudstreamrepo" /> | ||||
|             </intent-filter> | ||||
| 
 | ||||
|             <!-- Allow searching with intents: cloudstreamsearch://Your%20Name --> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.VIEW" /> | ||||
| 
 | ||||
|                 <category android:name="android.intent.category.DEFAULT" /> | ||||
|                 <category android:name="android.intent.category.BROWSABLE" /> | ||||
| 
 | ||||
|                 <data android:scheme="cloudstreamsearch" /> | ||||
|             </intent-filter> | ||||
| 
 | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.VIEW" /> | ||||
| 
 | ||||
|  |  | |||
|  | @ -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() | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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<TvType>().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") | ||||
|  |  | |||
|  | @ -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"> | ||||
|         <argument | ||||
|             android:name="search_query" | ||||
|             android:defaultValue="" | ||||
|             app:argType="string" /> | ||||
|     </fragment> | ||||
| 
 | ||||
|     <fragment | ||||
|         android:id="@+id/navigation_downloads" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue