mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	very nice long hold popups
This commit is contained in:
		
							parent
							
								
									65fda1889c
								
							
						
					
					
						commit
						60aca3ebdc
					
				
					 8 changed files with 392 additions and 41 deletions
				
			
		|  | @ -1,16 +1,14 @@ | |||
| package com.lagradost.cloudstream3 | ||||
| 
 | ||||
| import android.content.ComponentName | ||||
| import android.content.DialogInterface | ||||
| import android.content.Context | ||||
| import android.content.Intent | ||||
| import android.content.res.ColorStateList | ||||
| import android.content.res.Configuration | ||||
| import android.os.Bundle | ||||
| import android.util.AttributeSet | ||||
| import android.util.Log | ||||
| import android.view.KeyEvent | ||||
| import android.view.Menu | ||||
| import android.view.MenuItem | ||||
| import android.view.WindowManager | ||||
| import android.view.* | ||||
| import android.widget.Toast | ||||
| import androidx.activity.result.ActivityResultLauncher | ||||
| import androidx.annotation.IdRes | ||||
|  | @ -19,6 +17,7 @@ import androidx.appcompat.app.AppCompatActivity | |||
| import androidx.constraintlayout.widget.ConstraintLayout | ||||
| import androidx.core.view.isVisible | ||||
| import androidx.fragment.app.FragmentActivity | ||||
| import androidx.lifecycle.ViewModelProvider | ||||
| import androidx.navigation.NavController | ||||
| import androidx.navigation.NavDestination | ||||
| import androidx.navigation.NavDestination.Companion.hierarchy | ||||
|  | @ -31,6 +30,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature | |||
| import com.fasterxml.jackson.databind.ObjectMapper | ||||
| import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper | ||||
| import com.google.android.gms.cast.framework.* | ||||
| import com.google.android.material.bottomsheet.BottomSheetDialog | ||||
| import com.google.android.material.navigationrail.NavigationRailView | ||||
| import com.jaredrummler.android.colorpicker.ColorPickerDialogListener | ||||
| import com.lagradost.cloudstream3.APIHolder.allProviders | ||||
|  | @ -46,8 +46,7 @@ import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent | |||
| 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.mvvm.* | ||||
| import com.lagradost.cloudstream3.network.initClient | ||||
| import com.lagradost.cloudstream3.plugins.PluginManager | ||||
| import com.lagradost.cloudstream3.plugins.PluginManager.loadAllOnlinePlugins | ||||
|  | @ -61,9 +60,13 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStri | |||
| 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.WatchType | ||||
| import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO | ||||
| import com.lagradost.cloudstream3.ui.home.HomeViewModel | ||||
| import com.lagradost.cloudstream3.ui.result.ResultViewModel2 | ||||
| import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST | ||||
| import com.lagradost.cloudstream3.ui.result.setImage | ||||
| import com.lagradost.cloudstream3.ui.result.setText | ||||
| import com.lagradost.cloudstream3.ui.search.SearchFragment | ||||
| import com.lagradost.cloudstream3.ui.search.SearchResultBuilder | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings | ||||
|  | @ -74,6 +77,7 @@ import com.lagradost.cloudstream3.ui.settings.SettingsGeneral | |||
| import com.lagradost.cloudstream3.ui.setup.HAS_DONE_SETUP_KEY | ||||
| import com.lagradost.cloudstream3.ui.setup.SetupFragmentExtensions | ||||
| import com.lagradost.cloudstream3.utils.* | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.html | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.loadCache | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.loadRepository | ||||
|  | @ -86,9 +90,11 @@ import com.lagradost.cloudstream3.utils.DataStore.getKey | |||
| import com.lagradost.cloudstream3.utils.DataStore.setKey | ||||
| import com.lagradost.cloudstream3.utils.DataStoreHelper.migrateResumeWatching | ||||
| import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate | ||||
| import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.changeStatusBarState | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.checkWrite | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.getResourceColor | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.navigate | ||||
|  | @ -96,6 +102,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.requestRW | |||
| import com.lagradost.nicehttp.Requests | ||||
| import com.lagradost.nicehttp.ResponseParser | ||||
| import kotlinx.android.synthetic.main.activity_main.* | ||||
| import kotlinx.android.synthetic.main.bottom_resultview_preview.* | ||||
| import kotlinx.android.synthetic.main.fragment_result_swipe.* | ||||
| import kotlinx.coroutines.sync.Mutex | ||||
| import kotlinx.coroutines.sync.withLock | ||||
|  | @ -244,6 +251,10 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { | |||
|             Event<Boolean>() // homepage api, used to speed up time to load for homepage | ||||
|         val afterRepositoryLoadedEvent = Event<Boolean>() | ||||
| 
 | ||||
|         // kinda shitty solution, but cant com main->home otherwise for popups | ||||
|         val bookmarksUpdatedEvent = Event<Boolean>() | ||||
| 
 | ||||
| 
 | ||||
|         /** | ||||
|          * @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. | ||||
|  | @ -336,6 +347,16 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { | |||
|             } | ||||
|     } | ||||
| 
 | ||||
|     var lastPopup : SearchResponse? = null | ||||
|     fun loadPopup(result: SearchResponse) { | ||||
|         lastPopup = result | ||||
|         viewModel.load( | ||||
|             this, result.url, result.apiName, false, if (getApiDubstatusSettings() | ||||
|                     .contains(DubStatus.Dubbed) | ||||
|             ) DubStatus.Dubbed else DubStatus.Subbed, null | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     override fun onColorSelected(dialogId: Int, color: Int) { | ||||
|         onColorSelectedEvent.invoke(Pair(dialogId, color)) | ||||
|     } | ||||
|  | @ -619,6 +640,37 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     lateinit var viewModel: ResultViewModel2 | ||||
| 
 | ||||
|     override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { | ||||
|         viewModel = | ||||
|             ViewModelProvider(this)[ResultViewModel2::class.java] | ||||
| 
 | ||||
|         return super.onCreateView(name, context, attrs) | ||||
|     } | ||||
| 
 | ||||
|     private fun hidePreviewPopupDialog() { | ||||
|         viewModel.clear() | ||||
|         bottomPreviewPopup.dismissSafe(this) | ||||
|     } | ||||
| 
 | ||||
|     var bottomPreviewPopup: BottomSheetDialog? = null | ||||
|     private fun showPreviewPopupDialog(): BottomSheetDialog { | ||||
|         val ret = (bottomPreviewPopup ?: run { | ||||
|             val builder = | ||||
|                 BottomSheetDialog(this) | ||||
|             builder.setContentView(R.layout.bottom_resultview_preview) | ||||
|             builder.setOnDismissListener { | ||||
|                 bottomPreviewPopup = null | ||||
|                 viewModel.clear() | ||||
|             } | ||||
|             builder.setCanceledOnTouchOutside(true) | ||||
|             builder.show() | ||||
|             builder | ||||
|         }) | ||||
|         bottomPreviewPopup = ret | ||||
|         return ret | ||||
|     } | ||||
| 
 | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         app.initClient(this) | ||||
|  | @ -708,6 +760,78 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { | |||
|             builder.show().setDefaultFocus() | ||||
|         } | ||||
| 
 | ||||
|         observeNullable(viewModel.page) { resource -> | ||||
|             if (resource == null) { | ||||
|                 bottomPreviewPopup.dismissSafe(this) | ||||
|                 return@observeNullable | ||||
|             } | ||||
|             when (resource) { | ||||
|                 is Resource.Failure -> { | ||||
|                     showToast(this, R.string.error) | ||||
|                     hidePreviewPopupDialog() | ||||
|                 } | ||||
|                 is Resource.Loading -> { | ||||
|                     showPreviewPopupDialog().apply { | ||||
|                         resultview_preview_loading?.isVisible = true | ||||
|                         resultview_preview_result?.isVisible = false | ||||
|                         resultview_preview_loading_shimmer?.startShimmer() | ||||
|                     } | ||||
|                 } | ||||
|                 is Resource.Success -> { | ||||
|                     val d = resource.value | ||||
|                     showPreviewPopupDialog().apply { | ||||
|                         resultview_preview_loading?.isVisible = false | ||||
|                         resultview_preview_result?.isVisible = true | ||||
|                         resultview_preview_loading_shimmer?.stopShimmer() | ||||
| 
 | ||||
|                         resultview_preview_title?.text = d.title | ||||
| 
 | ||||
|                         resultview_preview_meta_type.setText(d.typeText) | ||||
|                         resultview_preview_meta_year.setText(d.yearText) | ||||
|                         resultview_preview_meta_duration.setText(d.durationText) | ||||
|                         resultview_preview_meta_rating.setText(d.ratingText) | ||||
| 
 | ||||
|                         resultview_preview_description?.setText(d.plotText) | ||||
|                         resultview_preview_poster?.setImage( | ||||
|                             d.posterImage ?: d.posterBackgroundImage | ||||
|                         ) | ||||
| 
 | ||||
|                         resultview_preview_poster?.setOnClickListener { | ||||
|                             //viewModel.updateWatchStatus(WatchType.PLANTOWATCH) | ||||
|                             val value = viewModel.watchStatus.value ?: WatchType.NONE | ||||
| 
 | ||||
|                             this@MainActivity.showBottomDialog( | ||||
|                                 WatchType.values().map { getString(it.stringRes) }.toList(), | ||||
|                                 value.ordinal, | ||||
|                                 this@MainActivity.getString(R.string.action_add_to_bookmarks), | ||||
|                                 showApply = false, | ||||
|                                 {}) { | ||||
|                                 viewModel.updateWatchStatus(WatchType.values()[it]) | ||||
|                                 bookmarksUpdatedEvent(true) | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         if (!isTvSettings()) // dont want this clickable on tv layout | ||||
|                             resultview_preview_description?.setOnClickListener { view -> | ||||
|                                 view.context?.let { ctx -> | ||||
|                                     val builder: AlertDialog.Builder = | ||||
|                                         AlertDialog.Builder(ctx, R.style.AlertDialogCustom) | ||||
|                                     builder.setMessage(d.plotText.asString(ctx).html()) | ||||
|                                         .setTitle(d.plotHeaderText.asString(ctx)) | ||||
|                                         .show() | ||||
|                                 } | ||||
|                             } | ||||
| 
 | ||||
|                         resultview_preview_more_info?.setOnClickListener { | ||||
|                             hidePreviewPopupDialog() | ||||
|                             lastPopup?.let { | ||||
|                                 loadSearchResult(it) | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| //        ioSafe { | ||||
| //            val plugins = | ||||
|  |  | |||
|  | @ -32,6 +32,7 @@ import com.lagradost.cloudstream3.APIHolder.filterProviderByPreferredMedia | |||
| import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings | ||||
| import com.lagradost.cloudstream3.AcraApplication.Companion.getKey | ||||
| import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent | ||||
| import com.lagradost.cloudstream3.MainActivity.Companion.bookmarksUpdatedEvent | ||||
| import com.lagradost.cloudstream3.MainActivity.Companion.mainPluginsLoadedEvent | ||||
| import com.lagradost.cloudstream3.mvvm.Resource | ||||
| import com.lagradost.cloudstream3.mvvm.logError | ||||
|  | @ -435,6 +436,11 @@ class HomeFragment : Fragment() { | |||
|         return inflater.inflate(layout, container, false) | ||||
|     } | ||||
| 
 | ||||
|     override fun onDestroyView() { | ||||
|         bottomSheetDialog?.ownHide() | ||||
|         super.onDestroyView() | ||||
|     } | ||||
| 
 | ||||
|     private fun fixGrid() { | ||||
|         activity?.getSpanCount()?.let { | ||||
|             currentSpan = it | ||||
|  | @ -461,14 +467,20 @@ class HomeFragment : Fragment() { | |||
|         fixGrid() | ||||
|     } | ||||
| 
 | ||||
|     fun bookmarksUpdated(_data : Boolean) { | ||||
|         reloadStored() | ||||
|     } | ||||
| 
 | ||||
|     override fun onResume() { | ||||
|         super.onResume() | ||||
|         reloadStored() | ||||
|         bookmarksUpdatedEvent += ::bookmarksUpdated | ||||
|         afterPluginsLoadedEvent += ::afterPluginsLoaded | ||||
|         mainPluginsLoadedEvent += ::afterMainPluginsLoaded | ||||
|     } | ||||
| 
 | ||||
|     override fun onStop() { | ||||
|         bookmarksUpdatedEvent -= ::bookmarksUpdated | ||||
|         afterPluginsLoadedEvent -= ::afterPluginsLoaded | ||||
|         mainPluginsLoadedEvent -= ::afterMainPluginsLoaded | ||||
|         super.onStop() | ||||
|  |  | |||
|  | @ -850,6 +850,7 @@ open class ResultFragment : ResultTrailerPlayer() { | |||
|         } | ||||
| 
 | ||||
|         observe(viewModel.page) { data -> | ||||
|             if(data == null) return@observe | ||||
|             when (data) { | ||||
|                 is Resource.Success -> { | ||||
|                     val d = data.value | ||||
|  |  | |||
|  | @ -55,7 +55,6 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultSeason | |||
| import com.lagradost.cloudstream3.utils.UIHelper.navigate | ||||
| import kotlinx.coroutines.* | ||||
| import java.io.File | ||||
| import java.lang.Math.abs | ||||
| import java.util.concurrent.TimeUnit | ||||
| 
 | ||||
| 
 | ||||
|  | @ -314,6 +313,11 @@ data class ExtractedTrailerData( | |||
| class ResultViewModel2 : ViewModel() { | ||||
|     private var currentResponse: LoadResponse? = null | ||||
| 
 | ||||
|     fun clear() { | ||||
|         currentResponse = null | ||||
|         _page.postValue(null) | ||||
|     } | ||||
| 
 | ||||
|     data class EpisodeIndexer( | ||||
|         val dubStatus: DubStatus, | ||||
|         val season: Int, | ||||
|  | @ -340,9 +344,9 @@ class ResultViewModel2 : ViewModel() { | |||
|     //private val currentHeaderName get() = currentResponse?.name | ||||
| 
 | ||||
| 
 | ||||
|     private val _page: MutableLiveData<Resource<ResultData>> = | ||||
|         MutableLiveData(Resource.Loading()) | ||||
|     val page: LiveData<Resource<ResultData>> = _page | ||||
|     private val _page: MutableLiveData<Resource<ResultData>?> = | ||||
|         MutableLiveData(null) | ||||
|     val page: LiveData<Resource<ResultData>?> = _page | ||||
| 
 | ||||
|     private val _episodes: MutableLiveData<ResourceSome<List<ResultEpisode>>> = | ||||
|         MutableLiveData(ResourceSome.Loading()) | ||||
|  | @ -398,7 +402,6 @@ class ResultViewModel2 : ViewModel() { | |||
|     private val _selectedDubStatusIndex: MutableLiveData<Int> = MutableLiveData(-1) | ||||
|     val selectedDubStatusIndex: LiveData<Int> = _selectedDubStatusIndex | ||||
| 
 | ||||
| 
 | ||||
|     private val _loadedLinks: MutableLiveData<Some<LinkProgress>> = MutableLiveData(Some.None) | ||||
|     val loadedLinks: LiveData<Some<LinkProgress>> = _loadedLinks | ||||
| 
 | ||||
|  | @ -1627,10 +1630,11 @@ class ResultViewModel2 : ViewModel() { | |||
|         if (ranges?.contains(range) != true) { | ||||
|             // if the current ranges does not include the range then select the range with the closest matching start episode | ||||
|             // this usually happends when dub has less episodes then sub -> the range does not exist | ||||
|             ranges?.minByOrNull { kotlin.math.abs(it.startEpisode - range.startEpisode) }?.let { r -> | ||||
|                 postEpisodeRange(indexer, r) | ||||
|                 return | ||||
|             } | ||||
|             ranges?.minByOrNull { kotlin.math.abs(it.startEpisode - range.startEpisode) } | ||||
|                 ?.let { r -> | ||||
|                     postEpisodeRange(indexer, r) | ||||
|                     return | ||||
|                 } | ||||
|         } | ||||
| 
 | ||||
|         val isMovie = currentResponse?.isMovie() == true | ||||
|  | @ -2111,6 +2115,7 @@ class ResultViewModel2 : ViewModel() { | |||
|         showFillers: Boolean, | ||||
|         dubStatus: DubStatus, | ||||
|         autostart: AutoResume?, | ||||
|         loadTrailers: Boolean = true, | ||||
|     ) = | ||||
|         viewModelScope.launchSafe { | ||||
|             _page.postValue(Resource.Loading(url)) | ||||
|  | @ -2189,8 +2194,8 @@ class ResultViewModel2 : ViewModel() { | |||
|                             System.currentTimeMillis(), | ||||
|                         ) | ||||
|                     ) | ||||
| 
 | ||||
|                     loadTrailers(data.value) | ||||
|                     if (loadTrailers) | ||||
|                         loadTrailers(data.value) | ||||
|                     postSuccessful( | ||||
|                         data.value, | ||||
|                         updateEpisodes = true, | ||||
|  |  | |||
|  | @ -45,6 +45,7 @@ import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.updateChips | |||
| import com.lagradost.cloudstream3.ui.home.ParentItemAdapter | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.ownHide | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.ownShow | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.setDefaultFocus | ||||
| import com.lagradost.cloudstream3.utils.Coroutines.main | ||||
|  | @ -121,6 +122,7 @@ class SearchFragment : Fragment() { | |||
| 
 | ||||
|     override fun onDestroyView() { | ||||
|         hideKeyboard() | ||||
|         bottomSheetDialog?.ownHide() | ||||
|         super.onDestroyView() | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,11 +3,13 @@ package com.lagradost.cloudstream3.ui.search | |||
| import android.app.Activity | ||||
| import android.widget.Toast | ||||
| import com.lagradost.cloudstream3.CommonActivity.showToast | ||||
| import com.lagradost.cloudstream3.MainActivity | ||||
| import com.lagradost.cloudstream3.R | ||||
| import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_PLAY_FILE | ||||
| import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup.handleDownloadClick | ||||
| import com.lagradost.cloudstream3.ui.download.DownloadClickEvent | ||||
| import com.lagradost.cloudstream3.ui.result.START_ACTION_LOAD_EP | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult | ||||
| import com.lagradost.cloudstream3.utils.DataStoreHelper | ||||
| import com.lagradost.cloudstream3.utils.VideoDownloadHelper | ||||
|  | @ -54,7 +56,15 @@ object SearchHelper { | |||
|                 } | ||||
|             } | ||||
|             SEARCH_ACTION_SHOW_METADATA -> { | ||||
|                 showToast(activity, callback.card.name, Toast.LENGTH_SHORT) | ||||
|                 if(!isTvSettings()) { // we only want this on phone as UI is not done yet on tv | ||||
|                     (activity as? MainActivity?)?.apply { | ||||
|                         loadPopup(callback.card) | ||||
|                     } ?: kotlin.run { | ||||
|                         showToast(activity, callback.card.name, Toast.LENGTH_SHORT) | ||||
|                     } | ||||
|                 } else { | ||||
|                     showToast(activity, callback.card.name, Toast.LENGTH_SHORT) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
							
								
								
									
										197
									
								
								app/src/main/res/layout/bottom_resultview_preview.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								app/src/main/res/layout/bottom_resultview_preview.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,197 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
| 
 | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent"> | ||||
| 
 | ||||
| 
 | ||||
|     <LinearLayout | ||||
|         android:id="@+id/resultview_preview_result" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent" | ||||
|         android:orientation="vertical" | ||||
|         android:visibility="gone" | ||||
|         tools:visibility="visible"> | ||||
| 
 | ||||
|         <LinearLayout | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:orientation="horizontal" | ||||
|             android:padding="12dp"> | ||||
| 
 | ||||
|             <androidx.cardview.widget.CardView | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 app:cardCornerRadius="@dimen/rounded_image_radius"> | ||||
| 
 | ||||
|                 <ImageView | ||||
|                     android:id="@+id/resultview_preview_poster" | ||||
|                     android:layout_width="88dp" | ||||
|                     android:layout_height="138dp" | ||||
|                     android:contentDescription="@string/poster_image" | ||||
|                     android:scaleType="centerCrop" | ||||
|                     tools:src="@drawable/example_poster" /> | ||||
|             </androidx.cardview.widget.CardView> | ||||
| 
 | ||||
|             <LinearLayout | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="138dp" | ||||
|                 android:layout_marginStart="10dp" | ||||
|                 android:orientation="vertical"> | ||||
| 
 | ||||
|                 <TextView | ||||
|                     android:id="@+id/resultview_preview_title" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:textColor="?attr/textColor" | ||||
|                     android:textSize="16sp" | ||||
| 
 | ||||
|                     android:textStyle="bold" | ||||
|                     tools:text="The Perfect Run"> | ||||
| 
 | ||||
|                 </TextView> | ||||
| 
 | ||||
|                 <com.lagradost.cloudstream3.widget.FlowLayout | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     app:itemSpacing="10dp"> | ||||
| 
 | ||||
|                     <TextView | ||||
|                         android:id="@+id/resultview_preview_meta_type" | ||||
|                         style="@style/ResultInfoText" | ||||
|                         tools:text="Movie" /> | ||||
| 
 | ||||
|                     <TextView | ||||
|                         android:id="@+id/resultview_preview_meta_year" | ||||
|                         style="@style/ResultInfoText" | ||||
|                         tools:text="2022" /> | ||||
| 
 | ||||
|                     <TextView | ||||
|                         android:id="@+id/resultview_preview_meta_rating" | ||||
|                         style="@style/ResultInfoText" | ||||
|                         tools:text="Rated: 8.5/10.0" /> | ||||
| 
 | ||||
|                     <TextView | ||||
|                         android:id="@+id/resultview_preview_meta_status" | ||||
|                         style="@style/ResultInfoText" | ||||
|                         tools:text="Ongoing" /> | ||||
| 
 | ||||
|                     <TextView | ||||
|                         android:id="@+id/resultview_preview_meta_duration" | ||||
|                         style="@style/ResultInfoText" | ||||
|                         tools:text="121min" /> | ||||
|                 </com.lagradost.cloudstream3.widget.FlowLayout> | ||||
| 
 | ||||
|                 <!-- <TextView | ||||
|                      android:id="@+id/resultview_preview_year" | ||||
|                      android:layout_width="wrap_content" | ||||
|                      android:layout_height="wrap_content" | ||||
| 
 | ||||
|                      android:textColor="?attr/grayTextColor" | ||||
|                      tools:text="2023" />--> | ||||
| 
 | ||||
|                 <FrameLayout | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="match_parent"> | ||||
| 
 | ||||
|                     <TextView | ||||
|                         android:id="@+id/resultview_preview_description" | ||||
|                         android:layout_width="wrap_content" | ||||
|                         android:layout_height="wrap_content" | ||||
| 
 | ||||
|                         android:ellipsize="end" | ||||
|                         android:textColor="?attr/textColor" | ||||
|                         tools:text="Ryan Quicksave Romano is an eccentric adventurer with a strange power: he can create a save-point in time and redo his life whenever he dies. Arriving in New Rome, the glitzy capital of sin of a rebuilding Europe, he finds the city torn between mega-corporations, sponsored heroes, superpowered criminals, and true monsters. It's a time of chaos, where potions can grant the power to rule the world and dangers lurk everywhere. " /> | ||||
| 
 | ||||
|                     <View | ||||
|                         android:layout_width="match_parent" | ||||
|                         android:layout_height="20dp" | ||||
|                         android:layout_gravity="bottom" | ||||
|                         android:background="@drawable/background_shadow" /> | ||||
|                 </FrameLayout> | ||||
|             </LinearLayout> | ||||
|         </LinearLayout> | ||||
| 
 | ||||
|         <TextView | ||||
|             android:id="@+id/resultview_preview_more_info" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:background="?android:attr/selectableItemBackground" | ||||
|             android:gravity="start|center_vertical" | ||||
|             android:padding="12dp" | ||||
|             android:text="@string/home_more_info" | ||||
|             android:textColor="?attr/textColor" | ||||
|             app:drawableRightCompat="@drawable/ic_baseline_arrow_forward_24" | ||||
|             app:drawableTint="?attr/white" /> | ||||
|     </LinearLayout> | ||||
| 
 | ||||
|     <FrameLayout | ||||
|         android:id="@+id/resultview_preview_loading" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent" | ||||
|         android:visibility="gone" | ||||
|         tools:visibility="visible"> | ||||
| 
 | ||||
|         <com.facebook.shimmer.ShimmerFrameLayout | ||||
|             android:id="@+id/resultview_preview_loading_shimmer" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:layout_gravity="center" | ||||
|             android:orientation="vertical" | ||||
|             app:shimmer_auto_start="true" | ||||
|             app:shimmer_base_alpha="0.2" | ||||
|             app:shimmer_duration="@integer/loading_time" | ||||
|             app:shimmer_highlight_alpha="0.3"> | ||||
| 
 | ||||
|             <LinearLayout | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:orientation="vertical"> | ||||
| 
 | ||||
|                 <LinearLayout | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_marginStart="@dimen/result_padding" | ||||
|                     android:layout_marginTop="@dimen/result_padding" | ||||
| 
 | ||||
|                     android:layout_marginEnd="@dimen/result_padding" | ||||
|                     android:orientation="horizontal"> | ||||
| 
 | ||||
|                     <include layout="@layout/loading_poster" /> | ||||
| 
 | ||||
|                     <LinearLayout | ||||
|                         android:layout_width="match_parent" | ||||
|                         android:layout_height="match_parent" | ||||
|                         android:orientation="vertical" | ||||
|                         android:paddingStart="10dp" | ||||
|                         android:paddingEnd="10dp"> | ||||
| 
 | ||||
|                         <include layout="@layout/loading_line" /> | ||||
| 
 | ||||
|                         <include layout="@layout/loading_line_short" /> | ||||
| 
 | ||||
|                         <include layout="@layout/loading_line" /> | ||||
| 
 | ||||
|                         <include layout="@layout/loading_line" /> | ||||
| 
 | ||||
|                         <include layout="@layout/loading_line" /> | ||||
|                     </LinearLayout> | ||||
|                 </LinearLayout> | ||||
| 
 | ||||
|                 <androidx.cardview.widget.CardView | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="26dp" | ||||
|                     android:layout_margin="@dimen/result_padding" | ||||
|                     android:layout_marginBottom="@dimen/loading_margin" | ||||
|                     android:background="@color/grayShimmer" | ||||
|                     app:cardCornerRadius="@dimen/loading_radius" | ||||
|                     tools:ignore="ContentDescription" /> | ||||
|             </LinearLayout> | ||||
|         </com.facebook.shimmer.ShimmerFrameLayout> | ||||
|     </FrameLayout> | ||||
| </FrameLayout> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1,59 +1,59 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|         android:orientation="vertical" | ||||
|         android:paddingTop="@dimen/loading_margin" | ||||
|         android:paddingBottom="@dimen/loading_margin" | ||||
|         android:layout_height="200dp" | ||||
|         android:layout_width="match_parent"> | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="200dp" | ||||
|     android:orientation="vertical" | ||||
|     android:paddingTop="@dimen/loading_margin" | ||||
|     android:paddingBottom="@dimen/loading_margin"> | ||||
| 
 | ||||
|     <include layout="@layout/loading_line_short" /> | ||||
| 
 | ||||
|     <LinearLayout | ||||
|             android:orientation="horizontal" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content"> | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:orientation="horizontal"> | ||||
| 
 | ||||
|         <include layout="@layout/loading_poster" /> | ||||
| 
 | ||||
|         <View | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_width="@dimen/loading_margin" /> | ||||
|             android:layout_width="@dimen/loading_margin" | ||||
|             android:layout_height="wrap_content" /> | ||||
| 
 | ||||
|         <include layout="@layout/loading_poster" /> | ||||
| 
 | ||||
|         <View | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_width="@dimen/loading_margin" /> | ||||
|             android:layout_width="@dimen/loading_margin" | ||||
|             android:layout_height="wrap_content" /> | ||||
| 
 | ||||
|         <include layout="@layout/loading_poster" /> | ||||
| 
 | ||||
|         <View | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_width="@dimen/loading_margin" /> | ||||
|             android:layout_width="@dimen/loading_margin" | ||||
|             android:layout_height="wrap_content" /> | ||||
| 
 | ||||
|         <include layout="@layout/loading_poster" /> | ||||
| 
 | ||||
|         <View | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_width="@dimen/loading_margin" /> | ||||
|             android:layout_width="@dimen/loading_margin" | ||||
|             android:layout_height="wrap_content" /> | ||||
| 
 | ||||
|         <include layout="@layout/loading_poster" /> | ||||
| 
 | ||||
|         <View | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_width="@dimen/loading_margin" /> | ||||
|             android:layout_width="@dimen/loading_margin" | ||||
|             android:layout_height="wrap_content" /> | ||||
| 
 | ||||
|         <include layout="@layout/loading_poster" /> | ||||
| 
 | ||||
|         <View | ||||
|                 android:layout_height="match_parent" | ||||
|                 android:layout_width="@dimen/loading_margin" /> | ||||
|             android:layout_width="@dimen/loading_margin" | ||||
|             android:layout_height="match_parent" /> | ||||
| 
 | ||||
|         <include layout="@layout/loading_poster" /> | ||||
| 
 | ||||
|         <View | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_width="@dimen/loading_margin" /> | ||||
|             android:layout_width="@dimen/loading_margin" | ||||
|             android:layout_height="wrap_content" /> | ||||
| 
 | ||||
|         <include layout="@layout/loading_poster" /> | ||||
|     </LinearLayout> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue