forked from recloudstream/cloudstream
		
	crash fix and headphones pause
This commit is contained in:
		
							parent
							
								
									ca4d05bd34
								
							
						
					
					
						commit
						0f1229354a
					
				
					 9 changed files with 246 additions and 149 deletions
				
			
		|  | @ -35,8 +35,8 @@ android { | |||
|         minSdkVersion 21 | ||||
|         targetSdkVersion 30 | ||||
| 
 | ||||
|         versionCode 40 | ||||
|         versionName "2.4.8" | ||||
|         versionCode 41 | ||||
|         versionName "2.5.8" | ||||
| 
 | ||||
|         resValue "string", "app_version", | ||||
|                 "${defaultConfig.versionName}${versionNameSuffix ?: ""}" | ||||
|  |  | |||
|  | @ -39,7 +39,6 @@ object APIHolder { | |||
|         WcoProvider(), | ||||
|         // MeloMovieProvider(), // Captcha for links | ||||
|         DubbedAnimeProvider(), | ||||
|         HDMProvider(), | ||||
|         IHaveNoTvProvider(), // Documentaries provider | ||||
|         //LookMovieProvider(), // RECAPTCHA (Please allow up to 5 seconds...) | ||||
|         VMoveeProvider(), | ||||
|  | @ -58,8 +57,6 @@ object APIHolder { | |||
| 
 | ||||
|         //TmdbProvider(), | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         FilmanProvider(), | ||||
| 
 | ||||
|         ZoroProvider(), | ||||
|  | @ -81,6 +78,7 @@ object APIHolder { | |||
| 
 | ||||
|     private val backwardsCompatibleProviders = arrayListOf( | ||||
|         KawaiifuProvider(), // removed due to cloudflare | ||||
|         HDMProvider(),// removed due to cloudflare | ||||
|     ) | ||||
| 
 | ||||
|     fun getApiFromName(apiName: String?): MainAPI { | ||||
|  | @ -179,7 +177,8 @@ object APIHolder { | |||
| 
 | ||||
|     fun Context.filterProviderByPreferredMedia(): List<MainAPI> { | ||||
|         val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) | ||||
|         val currentPrefMedia = settingsManager.getInt(this.getString(R.string.prefer_media_type_key), 0) | ||||
|         val currentPrefMedia = | ||||
|             settingsManager.getInt(this.getString(R.string.prefer_media_type_key), 0) | ||||
|         val langs = this.getApiProviderLangSettings() | ||||
|         val allApis = apis.filter { langs.contains(it.lang) }.filter { api -> api.hasMainPage } | ||||
|         return if (currentPrefMedia < 1) { | ||||
|  | @ -275,7 +274,7 @@ fun parseRating(ratingString: String?): Int? { | |||
|     return (floatRating * 10).toInt() | ||||
| } | ||||
| 
 | ||||
| fun MainAPI.fixUrlNull(url : String?) : String? { | ||||
| fun MainAPI.fixUrlNull(url: String?): String? { | ||||
|     if (url.isNullOrEmpty()) { | ||||
|         return null | ||||
|     } | ||||
|  | @ -305,7 +304,7 @@ fun sortUrls(urls: Set<ExtractorLink>): List<ExtractorLink> { | |||
|     return urls.sortedBy { t -> -t.quality } | ||||
| } | ||||
| 
 | ||||
| fun sortSubs(subs : Set<SubtitleData>) : List<SubtitleData> { | ||||
| fun sortSubs(subs: Set<SubtitleData>): List<SubtitleData> { | ||||
|     return subs.sortedBy { it.name } | ||||
| } | ||||
| 
 | ||||
|  | @ -473,7 +472,7 @@ fun LoadResponse?.isAnimeBased(): Boolean { | |||
|     return (this.type == TvType.Anime || this.type == TvType.ONA) // && (this is AnimeLoadResponse) | ||||
| } | ||||
| 
 | ||||
| fun TvType?.isEpisodeBased() : Boolean { | ||||
| fun TvType?.isEpisodeBased(): Boolean { | ||||
|     if (this == null) return false | ||||
|     return (this == TvType.TvSeries || this == TvType.Anime) | ||||
| } | ||||
|  | @ -573,7 +572,13 @@ fun MainAPI.newMovieLoadResponse( | |||
|     dataUrl: String, | ||||
|     initializer: MovieLoadResponse.() -> Unit = { } | ||||
| ): MovieLoadResponse { | ||||
|     val builder = MovieLoadResponse(name = name, url = url, apiName = this.name, type = type, dataUrl = dataUrl) | ||||
|     val builder = MovieLoadResponse( | ||||
|         name = name, | ||||
|         url = url, | ||||
|         apiName = this.name, | ||||
|         type = type, | ||||
|         dataUrl = dataUrl | ||||
|     ) | ||||
|     builder.initializer() | ||||
|     return builder | ||||
| } | ||||
|  | @ -634,7 +639,13 @@ fun MainAPI.newTvSeriesLoadResponse( | |||
|     episodes: List<TvSeriesEpisode>, | ||||
|     initializer: TvSeriesLoadResponse.() -> Unit = { } | ||||
| ): TvSeriesLoadResponse { | ||||
|     val builder = TvSeriesLoadResponse(name = name, url = url, apiName = this.name, type = type, episodes = episodes) | ||||
|     val builder = TvSeriesLoadResponse( | ||||
|         name = name, | ||||
|         url = url, | ||||
|         apiName = this.name, | ||||
|         type = type, | ||||
|         episodes = episodes | ||||
|     ) | ||||
|     builder.initializer() | ||||
|     return builder | ||||
| } | ||||
|  |  | |||
|  | @ -1,26 +1,27 @@ | |||
| package com.lagradost.cloudstream3.ui.player | ||||
| 
 | ||||
| import android.annotation.SuppressLint | ||||
| import android.content.BroadcastReceiver | ||||
| import android.content.Context | ||||
| import android.content.Intent | ||||
| import android.content.IntentFilter | ||||
| import android.content.* | ||||
| import android.graphics.drawable.AnimatedImageDrawable | ||||
| import android.graphics.drawable.AnimatedVectorDrawable | ||||
| import android.media.metrics.PlaybackErrorEvent | ||||
| import android.os.Build | ||||
| import android.os.Bundle | ||||
| import android.support.v4.media.session.MediaSessionCompat | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.view.WindowManager | ||||
| import android.widget.Toast | ||||
| import androidx.annotation.LayoutRes | ||||
| import androidx.annotation.StringRes | ||||
| import androidx.core.view.isVisible | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.media.session.MediaButtonReceiver | ||||
| import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat | ||||
| import com.google.android.exoplayer2.ExoPlayer | ||||
| import com.google.android.exoplayer2.PlaybackException | ||||
| import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector | ||||
| import com.google.android.exoplayer2.ui.AspectRatioFrameLayout | ||||
| import com.google.android.exoplayer2.ui.SubtitleView | ||||
| import com.lagradost.cloudstream3.AcraApplication.Companion.getKey | ||||
|  | @ -81,9 +82,20 @@ abstract class AbstractPlayerFragment( | |||
|         throw NotImplementedError() | ||||
|     } | ||||
| 
 | ||||
|     private fun keepScreenOn(on : Boolean) { | ||||
|         if(on) { | ||||
|             activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) | ||||
|         } else { | ||||
|             activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun updateIsPlaying(playing: Pair<CSPlayerLoading, CSPlayerLoading>) { | ||||
|         val (wasPlaying, isPlaying) = playing | ||||
|         val isPlayingRightNow = CSPlayerLoading.IsPlaying == isPlaying | ||||
|         val isPausedRightNow = CSPlayerLoading.IsPaused == isPlaying | ||||
| 
 | ||||
|         keepScreenOn(!isPausedRightNow) | ||||
| 
 | ||||
|         isBuffering = CSPlayerLoading.IsBuffering == isPlaying | ||||
|         if (isBuffering) { | ||||
|  | @ -241,11 +253,48 @@ abstract class AbstractPlayerFragment( | |||
| 
 | ||||
|     private fun playerUpdated(player: Any?) { | ||||
|         if (player is ExoPlayer) { | ||||
|             context?.let { ctx -> | ||||
|                 val mediaButtonReceiver = ComponentName(ctx, MediaButtonReceiver::class.java) | ||||
|                 MediaSessionCompat(ctx, "Player", mediaButtonReceiver, null).let { media -> | ||||
|                     //media.setCallback(mMediaSessionCallback) | ||||
|                     //media.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS) | ||||
|                     val mediaSessionConnector = MediaSessionConnector(media) | ||||
|                     mediaSessionConnector.setPlayer(player) | ||||
|                     media.isActive = true | ||||
|                     mMediaSessionCompat = media | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             player_view?.player = player | ||||
|             player_view?.performClick() | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private var mediaSessionConnector: MediaSessionConnector? = null | ||||
|     private var mMediaSessionCompat: MediaSessionCompat? = null | ||||
| 
 | ||||
|     // this can be used in the future for players other than exoplayer | ||||
|     //private val mMediaSessionCallback: MediaSessionCompat.Callback = object : MediaSessionCompat.Callback() { | ||||
|     //    override fun onMediaButtonEvent(mediaButtonEvent: Intent): Boolean { | ||||
|     //        val keyEvent = mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT) as KeyEvent? | ||||
|     //        if (keyEvent != null) { | ||||
|     //            if (keyEvent.action == KeyEvent.ACTION_DOWN) { // NO DOUBLE SKIP | ||||
|     //                val consumed = when (keyEvent.keyCode) { | ||||
|     //                    KeyEvent.KEYCODE_MEDIA_PAUSE -> callOnPause() | ||||
|     //                    KeyEvent.KEYCODE_MEDIA_PLAY -> callOnPlay() | ||||
|     //                    KeyEvent.KEYCODE_MEDIA_STOP -> callOnStop() | ||||
|     //                    KeyEvent.KEYCODE_MEDIA_NEXT -> callOnNext() | ||||
|     //                    else -> false | ||||
|     //                } | ||||
|     //                if (consumed) return true | ||||
|     //            } | ||||
|     //        } | ||||
|     // | ||||
|     //        return super.onMediaButtonEvent(mediaButtonEvent) | ||||
|     //    } | ||||
|     //} | ||||
| 
 | ||||
| 
 | ||||
|     @SuppressLint("SetTextI18n") | ||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
|         resizeMode = getKey(RESIZE_MODE_KEY) ?: 0 | ||||
|  | @ -295,6 +344,7 @@ abstract class AbstractPlayerFragment( | |||
|         keyEventListener = null | ||||
|         SubtitlesFragment.applyStyleEvent -= ::onSubStyleChanged | ||||
| 
 | ||||
|         keepScreenOn(false) | ||||
|         super.onDestroy() | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -130,7 +130,7 @@ open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) { | |||
|         if (isShowing) { | ||||
|             updateUIVisibility() | ||||
|         } else { | ||||
|             player_holder.postDelayed({ updateUIVisibility() }, 200) | ||||
|             player_holder?.postDelayed({ updateUIVisibility() }, 200) | ||||
|         } | ||||
| 
 | ||||
|         val titleMove = if (isShowing) 0f else -50.toPx.toFloat() | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ import com.hippo.unifile.UniFile | |||
| import com.lagradost.cloudstream3.* | ||||
| import com.lagradost.cloudstream3.CommonActivity.showToast | ||||
| import com.lagradost.cloudstream3.mvvm.Resource | ||||
| import com.lagradost.cloudstream3.mvvm.logError | ||||
| import com.lagradost.cloudstream3.mvvm.normalSafeApiCall | ||||
| import com.lagradost.cloudstream3.mvvm.observe | ||||
| import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType | ||||
|  | @ -171,111 +172,115 @@ class GeneratorPlayer : FullScreenPlayer() { | |||
| 
 | ||||
|     var selectSourceDialog: AlertDialog? = null | ||||
|     override fun showMirrorsDialogue() { | ||||
|         currentSelectedSubtitles = player.getCurrentPreferredSubtitle() | ||||
|         context?.let { ctx -> | ||||
|             val isPlaying = player.getIsPlaying() | ||||
|             player.handleEvent(CSPlayerEvent.Pause) | ||||
|             val currentSubtitles = sortSubs(currentSubs) | ||||
|         try { | ||||
|             currentSelectedSubtitles = player.getCurrentPreferredSubtitle() | ||||
|             context?.let { ctx -> | ||||
|                 val isPlaying = player.getIsPlaying() | ||||
|                 player.handleEvent(CSPlayerEvent.Pause) | ||||
|                 val currentSubtitles = sortSubs(currentSubs) | ||||
| 
 | ||||
|             val sourceBuilder = AlertDialog.Builder(ctx, R.style.AlertDialogCustomBlack) | ||||
|                 .setView(R.layout.player_select_source_and_subs) | ||||
|                 val sourceBuilder = AlertDialog.Builder(ctx, R.style.AlertDialogCustomBlack) | ||||
|                     .setView(R.layout.player_select_source_and_subs) | ||||
| 
 | ||||
|             val sourceDialog = sourceBuilder.create() | ||||
|             selectSourceDialog = sourceDialog | ||||
|             sourceDialog.show() | ||||
|             val providerList = | ||||
|                 sourceDialog.findViewById<ListView>(R.id.sort_providers)!! | ||||
|             val subtitleList = | ||||
|                 sourceDialog.findViewById<ListView>(R.id.sort_subtitles)!! | ||||
|             val applyButton = | ||||
|                 sourceDialog.findViewById<MaterialButton>(R.id.apply_btt)!! | ||||
|             val cancelButton = | ||||
|                 sourceDialog.findViewById<MaterialButton>(R.id.cancel_btt)!! | ||||
|                 val sourceDialog = sourceBuilder.create() | ||||
|                 selectSourceDialog = sourceDialog | ||||
|                 sourceDialog.show() | ||||
|                 val providerList = | ||||
|                     sourceDialog.findViewById<ListView>(R.id.sort_providers)!! | ||||
|                 val subtitleList = | ||||
|                     sourceDialog.findViewById<ListView>(R.id.sort_subtitles)!! | ||||
|                 val applyButton = | ||||
|                     sourceDialog.findViewById<MaterialButton>(R.id.apply_btt)!! | ||||
|                 val cancelButton = | ||||
|                     sourceDialog.findViewById<MaterialButton>(R.id.cancel_btt)!! | ||||
| 
 | ||||
|             val footer: TextView = | ||||
|                 layoutInflater.inflate(R.layout.sort_bottom_footer_add_choice, null) as TextView | ||||
|             footer.text = ctx.getString(R.string.player_load_subtitles) | ||||
|             footer.setOnClickListener { | ||||
|                 openSubPicker() | ||||
|             } | ||||
|             subtitleList.addFooterView(footer) | ||||
| 
 | ||||
|             var sourceIndex = 0 | ||||
|             var startSource = 0 | ||||
| 
 | ||||
|             val sortedUrls = sortLinks(useQualitySettings = false) | ||||
|             if (sortedUrls.isNullOrEmpty()) { | ||||
|                 sourceDialog.findViewById<LinearLayout>(R.id.sort_sources_holder)?.isGone = true | ||||
|             } else { | ||||
|                 startSource = sortedUrls.indexOf(currentSelectedLink) | ||||
|                 sourceIndex = startSource | ||||
| 
 | ||||
|                 val sourcesArrayAdapter = | ||||
|                     ArrayAdapter<String>(ctx, R.layout.sort_bottom_single_choice) | ||||
| 
 | ||||
|                 sourcesArrayAdapter.addAll(sortedUrls.map { | ||||
|                     it.first?.name ?: it.second?.name ?: "NULL" | ||||
|                 }) | ||||
| 
 | ||||
|                 providerList.choiceMode = AbsListView.CHOICE_MODE_SINGLE | ||||
|                 providerList.adapter = sourcesArrayAdapter | ||||
|                 providerList.setSelection(sourceIndex) | ||||
|                 providerList.setItemChecked(sourceIndex, true) | ||||
| 
 | ||||
|                 providerList.setOnItemClickListener { _, _, which, _ -> | ||||
|                     sourceIndex = which | ||||
|                     providerList.setItemChecked(which, true) | ||||
|                 val footer: TextView = | ||||
|                     layoutInflater.inflate(R.layout.sort_bottom_footer_add_choice, null) as TextView | ||||
|                 footer.text = ctx.getString(R.string.player_load_subtitles) | ||||
|                 footer.setOnClickListener { | ||||
|                     openSubPicker() | ||||
|                 } | ||||
|             } | ||||
|                 subtitleList.addFooterView(footer) | ||||
| 
 | ||||
|             sourceDialog.setOnDismissListener { | ||||
|                 if (isPlaying) { | ||||
|                     player.handleEvent(CSPlayerEvent.Play) | ||||
|                 } | ||||
|                 activity?.hideSystemUI() | ||||
|                 selectSourceDialog = null | ||||
|             } | ||||
|                 var sourceIndex = 0 | ||||
|                 var startSource = 0 | ||||
| 
 | ||||
|             val subtitleIndexStart = currentSubtitles.indexOf(currentSelectedSubtitles) + 1 | ||||
|             var subtitleIndex = subtitleIndexStart | ||||
|                 val sortedUrls = sortLinks(useQualitySettings = false) | ||||
|                 if (sortedUrls.isNullOrEmpty()) { | ||||
|                     sourceDialog.findViewById<LinearLayout>(R.id.sort_sources_holder)?.isGone = true | ||||
|                 } else { | ||||
|                     startSource = sortedUrls.indexOf(currentSelectedLink) | ||||
|                     sourceIndex = startSource | ||||
| 
 | ||||
|             val subsArrayAdapter = | ||||
|                 ArrayAdapter<String>(ctx, R.layout.sort_bottom_single_choice) | ||||
|             subsArrayAdapter.add(getString(R.string.no_subtitles)) | ||||
|             subsArrayAdapter.addAll(currentSubtitles.map { it.name }) | ||||
|                     val sourcesArrayAdapter = | ||||
|                         ArrayAdapter<String>(ctx, R.layout.sort_bottom_single_choice) | ||||
| 
 | ||||
|             subtitleList.adapter = subsArrayAdapter | ||||
|             subtitleList.choiceMode = AbsListView.CHOICE_MODE_SINGLE | ||||
|                     sourcesArrayAdapter.addAll(sortedUrls.map { | ||||
|                         it.first?.name ?: it.second?.name ?: "NULL" | ||||
|                     }) | ||||
| 
 | ||||
|             subtitleList.setSelection(subtitleIndex) | ||||
|             subtitleList.setItemChecked(subtitleIndex, true) | ||||
|                     providerList.choiceMode = AbsListView.CHOICE_MODE_SINGLE | ||||
|                     providerList.adapter = sourcesArrayAdapter | ||||
|                     providerList.setSelection(sourceIndex) | ||||
|                     providerList.setItemChecked(sourceIndex, true) | ||||
| 
 | ||||
|             subtitleList.setOnItemClickListener { _, _, which, _ -> | ||||
|                 subtitleIndex = which | ||||
|                 subtitleList.setItemChecked(which, true) | ||||
|             } | ||||
| 
 | ||||
|             cancelButton.setOnClickListener { | ||||
|                 sourceDialog.dismissSafe(activity) | ||||
|             } | ||||
| 
 | ||||
|             applyButton.setOnClickListener { | ||||
|                 var init = false | ||||
|                 if (sourceIndex != startSource) { | ||||
|                     init = true | ||||
|                 } | ||||
|                 if (subtitleIndex != subtitleIndexStart) { | ||||
|                     init = init || if (subtitleIndex <= 0) { | ||||
|                         noSubtitles() | ||||
|                     } else { | ||||
|                         setSubtitles(currentSubtitles[subtitleIndex - 1]) | ||||
|                     providerList.setOnItemClickListener { _, _, which, _ -> | ||||
|                         sourceIndex = which | ||||
|                         providerList.setItemChecked(which, true) | ||||
|                     } | ||||
|                 } | ||||
|                 if (init) { | ||||
|                     loadLink(sortedUrls[sourceIndex], true) | ||||
| 
 | ||||
|                 sourceDialog.setOnDismissListener { | ||||
|                     if (isPlaying) { | ||||
|                         player.handleEvent(CSPlayerEvent.Play) | ||||
|                     } | ||||
|                     activity?.hideSystemUI() | ||||
|                     selectSourceDialog = null | ||||
|                 } | ||||
| 
 | ||||
|                 val subtitleIndexStart = currentSubtitles.indexOf(currentSelectedSubtitles) + 1 | ||||
|                 var subtitleIndex = subtitleIndexStart | ||||
| 
 | ||||
|                 val subsArrayAdapter = | ||||
|                     ArrayAdapter<String>(ctx, R.layout.sort_bottom_single_choice) | ||||
|                 subsArrayAdapter.add(getString(R.string.no_subtitles)) | ||||
|                 subsArrayAdapter.addAll(currentSubtitles.map { it.name }) | ||||
| 
 | ||||
|                 subtitleList.adapter = subsArrayAdapter | ||||
|                 subtitleList.choiceMode = AbsListView.CHOICE_MODE_SINGLE | ||||
| 
 | ||||
|                 subtitleList.setSelection(subtitleIndex) | ||||
|                 subtitleList.setItemChecked(subtitleIndex, true) | ||||
| 
 | ||||
|                 subtitleList.setOnItemClickListener { _, _, which, _ -> | ||||
|                     subtitleIndex = which | ||||
|                     subtitleList.setItemChecked(which, true) | ||||
|                 } | ||||
| 
 | ||||
|                 cancelButton.setOnClickListener { | ||||
|                     sourceDialog.dismissSafe(activity) | ||||
|                 } | ||||
| 
 | ||||
|                 applyButton.setOnClickListener { | ||||
|                     var init = false | ||||
|                     if (sourceIndex != startSource) { | ||||
|                         init = true | ||||
|                     } | ||||
|                     if (subtitleIndex != subtitleIndexStart) { | ||||
|                         init = init || if (subtitleIndex <= 0) { | ||||
|                             noSubtitles() | ||||
|                         } else { | ||||
|                             setSubtitles(currentSubtitles[subtitleIndex - 1]) | ||||
|                         } | ||||
|                     } | ||||
|                     if (init) { | ||||
|                         loadLink(sortedUrls[sourceIndex], true) | ||||
|                     } | ||||
|                     sourceDialog.dismissSafe(activity) | ||||
|                 } | ||||
|                 sourceDialog.dismissSafe(activity) | ||||
|             } | ||||
|         } catch (e : Exception) { | ||||
|             logError(e) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -755,9 +755,13 @@ class ResultFragment : Fragment() { | |||
| 
 | ||||
|                 ACTION_PLAY_EPISODE_IN_BROWSER -> { | ||||
|                     acquireSingeExtractorLink(getString(R.string.episode_action_play_in_browser)) { link -> | ||||
|                         val i = Intent(ACTION_VIEW) | ||||
|                         i.data = Uri.parse(link.url) | ||||
|                         startActivity(i) | ||||
|                         try { | ||||
|                             val i = Intent(ACTION_VIEW) | ||||
|                             i.data = Uri.parse(link.url) | ||||
|                             startActivity(i) | ||||
|                         } catch (e : Exception) { | ||||
|                             logError(e) | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|  | @ -1125,11 +1129,15 @@ class ResultFragment : Fragment() { | |||
|                         } | ||||
| 
 | ||||
|                         result_share?.setOnClickListener { | ||||
|                             val i = Intent(ACTION_SEND) | ||||
|                             i.type = "text/plain" | ||||
|                             i.putExtra(EXTRA_SUBJECT, d.name) | ||||
|                             i.putExtra(EXTRA_TEXT, d.url) | ||||
|                             startActivity(createChooser(i, d.name)) | ||||
|                             try { | ||||
|                                 val i = Intent(ACTION_SEND) | ||||
|                                 i.type = "text/plain" | ||||
|                                 i.putExtra(EXTRA_SUBJECT, d.name) | ||||
|                                 i.putExtra(EXTRA_TEXT, d.url) | ||||
|                                 startActivity(createChooser(i, d.name)) | ||||
|                             } catch (e: Exception) { | ||||
|                                 logError(e) | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         updateSync(d.getId()) | ||||
|  |  | |||
|  | @ -32,6 +32,7 @@ import com.lagradost.cloudstream3.DubStatus | |||
| import com.lagradost.cloudstream3.R | ||||
| import com.lagradost.cloudstream3.app | ||||
| import com.lagradost.cloudstream3.mvvm.logError | ||||
| import com.lagradost.cloudstream3.mvvm.normalSafeApiCall | ||||
| import com.lagradost.cloudstream3.syncproviders.AccountManager | ||||
| import com.lagradost.cloudstream3.syncproviders.OAuth2API | ||||
| import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.aniListApi | ||||
|  | @ -301,22 +302,24 @@ class SettingsFragment : PreferenceFragmentCompat() { | |||
|         } | ||||
| 
 | ||||
|         fun getDownloadDirs(): List<String> { | ||||
|             val defaultDir = getDownloadDir()?.filePath | ||||
|             return normalSafeApiCall { | ||||
|                 val defaultDir = getDownloadDir()?.filePath | ||||
| 
 | ||||
|             // app_name_download_path = Cloudstream and does not change depending on release. | ||||
|             // DOES NOT WORK ON SCOPED STORAGE. | ||||
|             val secondaryDir = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) null else Environment.getExternalStorageDirectory().absolutePath + | ||||
|                     File.separator + resources.getString(R.string.app_name_download_path) | ||||
|             val first = listOf(defaultDir, secondaryDir) | ||||
|             return (try { | ||||
|                 val currentDir = context?.getBasePath()?.let { it.first?.filePath ?: it.second } | ||||
|                 // app_name_download_path = Cloudstream and does not change depending on release. | ||||
|                 // DOES NOT WORK ON SCOPED STORAGE. | ||||
|                 val secondaryDir = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) null else Environment.getExternalStorageDirectory().absolutePath + | ||||
|                         File.separator + resources.getString(R.string.app_name_download_path) | ||||
|                 val first = listOf(defaultDir, secondaryDir) | ||||
|                 (try { | ||||
|                     val currentDir = context?.getBasePath()?.let { it.first?.filePath ?: it.second } | ||||
| 
 | ||||
|                 (first + | ||||
|                         requireContext().getExternalFilesDirs("").mapNotNull { it.path } + | ||||
|                         currentDir) | ||||
|             } catch (e: Exception) { | ||||
|                 first | ||||
|             }).filterNotNull().distinct() | ||||
|                     (first + | ||||
|                             requireContext().getExternalFilesDirs("").mapNotNull { it.path } + | ||||
|                             currentDir) | ||||
|                 } catch (e: Exception) { | ||||
|                     first | ||||
|                 }).filterNotNull().distinct() | ||||
|             } ?: emptyList() | ||||
|         } | ||||
| 
 | ||||
|         downloadPathPreference.setOnPreferenceClickListener { | ||||
|  |  | |||
|  | @ -126,7 +126,12 @@ class InAppUpdater { | |||
|                         } | ||||
|                     )!! < 0 else false | ||||
|                 return if (foundVersion != null) { | ||||
|                     Update(shouldUpdate, foundAsset.browser_download_url, foundVersion.groupValues[2], found.body) | ||||
|                     Update( | ||||
|                         shouldUpdate, | ||||
|                         foundAsset.browser_download_url, | ||||
|                         foundVersion.groupValues[2], | ||||
|                         found.body | ||||
|                     ) | ||||
|                 } else { | ||||
|                     Update(false, null, null, null) | ||||
|                 } | ||||
|  | @ -135,7 +140,8 @@ class InAppUpdater { | |||
|         } | ||||
| 
 | ||||
|         private fun Activity.getPreReleaseUpdate(): Update { | ||||
|             val tagUrl = "https://api.github.com/repos/LagradOst/CloudStream-3/git/ref/tags/pre-release" | ||||
|             val tagUrl = | ||||
|                 "https://api.github.com/repos/LagradOst/CloudStream-3/git/ref/tags/pre-release" | ||||
|             val releaseUrl = "https://api.github.com/repos/LagradOst/CloudStream-3/releases" | ||||
|             val headers = mapOf("Accept" to "application/vnd.github.v3+json") | ||||
|             val response = | ||||
|  | @ -150,10 +156,16 @@ class InAppUpdater { | |||
|             val tagResponse = | ||||
|                 mapper.readValue<GithubTag>(app.get(tagUrl, headers = headers).text) | ||||
| 
 | ||||
|             val shouldUpdate = (getString(R.string.prerelease_commit_hash) != tagResponse.github_object.sha) | ||||
|             val shouldUpdate = | ||||
|                 (getString(R.string.prerelease_commit_hash) != tagResponse.github_object.sha) | ||||
| 
 | ||||
|             return if (foundAsset != null) { | ||||
|                 Update(shouldUpdate, foundAsset.browser_download_url, tagResponse.github_object.sha, found.body) | ||||
|                 Update( | ||||
|                     shouldUpdate, | ||||
|                     foundAsset.browser_download_url, | ||||
|                     tagResponse.github_object.sha, | ||||
|                     found.body | ||||
|                 ) | ||||
|             } else { | ||||
|                 Update(false, null, null, null) | ||||
|             } | ||||
|  | @ -217,26 +229,33 @@ class InAppUpdater { | |||
|         } | ||||
| 
 | ||||
|         fun openApk(context: Context, uri: Uri) { | ||||
|             uri.path?.let { | ||||
|                 val contentUri = FileProvider.getUriForFile( | ||||
|                     context, | ||||
|                     BuildConfig.APPLICATION_ID + ".provider", | ||||
|                     File(it) | ||||
|                 ) | ||||
|                 val installIntent = Intent(Intent.ACTION_VIEW).apply { | ||||
|                     addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) | ||||
|                     addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) | ||||
|                     putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true) | ||||
|                     data = contentUri | ||||
|             try { | ||||
|                 uri.path?.let { | ||||
|                     val contentUri = FileProvider.getUriForFile( | ||||
|                         context, | ||||
|                         BuildConfig.APPLICATION_ID + ".provider", | ||||
|                         File(it) | ||||
|                     ) | ||||
|                     val installIntent = Intent(Intent.ACTION_VIEW).apply { | ||||
|                         addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) | ||||
|                         addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) | ||||
|                         putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true) | ||||
|                         data = contentUri | ||||
|                     } | ||||
|                     context.startActivity(installIntent) | ||||
|                 } | ||||
|                 context.startActivity(installIntent) | ||||
|             } catch (e: Exception) { | ||||
|                 logError(e) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         fun Activity.runAutoUpdate(checkAutoUpdate: Boolean = true): Boolean { | ||||
|             val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) | ||||
| 
 | ||||
|             if (!checkAutoUpdate || settingsManager.getBoolean(getString(R.string.auto_update_key), true) | ||||
|             if (!checkAutoUpdate || settingsManager.getBoolean( | ||||
|                     getString(R.string.auto_update_key), | ||||
|                     true | ||||
|                 ) | ||||
|             ) { | ||||
|                 val update = getAppUpdate() | ||||
|                 if (update.shouldUpdate && update.updateURL != null) { | ||||
|  | @ -264,7 +283,8 @@ class InAppUpdater { | |||
|                                     showToast(context, R.string.download_started, Toast.LENGTH_LONG) | ||||
|                                     thread { | ||||
|                                         val downloadStatus = | ||||
|                                             normalSafeApiCall { context.downloadUpdate(update.updateURL) } ?: false | ||||
|                                             normalSafeApiCall { context.downloadUpdate(update.updateURL) } | ||||
|                                                 ?: false | ||||
|                                         if (!downloadStatus) { | ||||
|                                             runOnUiThread { | ||||
|                                                 showToast( | ||||
|  | @ -281,7 +301,8 @@ class InAppUpdater { | |||
| 
 | ||||
|                                 if (checkAutoUpdate) { | ||||
|                                     setNeutralButton(R.string.dont_show_again) { _, _ -> | ||||
|                                         settingsManager.edit().putBoolean("auto_update", false).apply() | ||||
|                                         settingsManager.edit().putBoolean("auto_update", false) | ||||
|                                             .apply() | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue