| @ -55,16 +55,13 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS | ||||
|  | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         super.onCreate(savedInstanceState) | ||||
|         binding = ActivityMainBinding.inflate(layoutInflater) | ||||
|  | ||||
|         if (!wasInitialized) { | ||||
|             load() | ||||
|         } | ||||
|  | ||||
|         if (!wasInitialized) { load() } | ||||
|         theme.applyStyle(getThemeResource(), true) | ||||
|  | ||||
|         setContentView(binding.root) | ||||
|         binding = ActivityMainBinding.inflate(layoutInflater) | ||||
|         binding.navView.setOnNavigationItemSelectedListener(this) | ||||
|         setContentView(binding.root) | ||||
|  | ||||
|         supportFragmentManager.commit { | ||||
|             replace(R.id.nav_host_fragment, activeBaseFragment, activeBaseFragment.javaClass.simpleName) | ||||
| @ -160,31 +157,16 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS | ||||
|  | ||||
|     /** | ||||
|      * Show the media fragment for the selected media. | ||||
|      * While loading show the loading fragment. | ||||
|      * The loading and media fragment are not stored in activeBaseFragment, | ||||
|      * as the don't replace a fragment but are added on top of one. | ||||
|      * The media fragment is not stored in activeBaseFragment, | ||||
|      * as it doesn't replace a fragment but is added on top of one. | ||||
|      */ | ||||
|     fun showMediaFragment(mediaId: Int) = GlobalScope.launch { | ||||
|         val loadingFragment = LoadingFragment() | ||||
|         supportFragmentManager.commit { | ||||
|             add(R.id.nav_host_fragment, loadingFragment, "MediaFragment") | ||||
|             show(loadingFragment) | ||||
|         } | ||||
|  | ||||
|         // load the streams for the selected media | ||||
|         val media = AoDParser.getMediaById(mediaId) | ||||
|         val tmdb = TMDBApiController().search(media.info.title, media.type) | ||||
|  | ||||
|         val mediaFragment = MediaFragment(media, tmdb) | ||||
|         val mediaFragment = MediaFragment(mediaId) | ||||
|         supportFragmentManager.commit { | ||||
|             add(R.id.nav_host_fragment, mediaFragment, "MediaFragment") | ||||
|             addToBackStack(null) | ||||
|             show(mediaFragment) | ||||
|         } | ||||
|  | ||||
|         supportFragmentManager.commit { | ||||
|             remove(loadingFragment) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fun startPlayer(mediaId: Int, episodeId: Int) { | ||||
|  | ||||
| @ -1,16 +0,0 @@ | ||||
| package org.mosad.teapod.ui.fragments | ||||
|  | ||||
| import android.os.Bundle | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import androidx.fragment.app.Fragment | ||||
| import org.mosad.teapod.R | ||||
|  | ||||
| class LoadingFragment : Fragment() { | ||||
|  | ||||
|     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { | ||||
|         return inflater.inflate(R.layout.fragment_loading, container, false) | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -13,22 +13,26 @@ import androidx.recyclerview.widget.RecyclerView | ||||
| import com.bumptech.glide.Glide | ||||
| import com.bumptech.glide.request.RequestOptions | ||||
| import jp.wasabeef.glide.transformations.BlurTransformation | ||||
| import kotlinx.coroutines.Dispatchers | ||||
| import kotlinx.coroutines.GlobalScope | ||||
| import kotlinx.coroutines.launch | ||||
| import kotlinx.coroutines.withContext | ||||
| import org.mosad.teapod.MainActivity | ||||
| import org.mosad.teapod.R | ||||
| import org.mosad.teapod.databinding.FragmentMediaBinding | ||||
| import org.mosad.teapod.parser.AoDParser | ||||
| import org.mosad.teapod.util.* | ||||
| import org.mosad.teapod.util.DataTypes.MediaType | ||||
| import org.mosad.teapod.util.Episode | ||||
| import org.mosad.teapod.util.Media | ||||
| import org.mosad.teapod.util.StorageController | ||||
| import org.mosad.teapod.util.TMDBResponse | ||||
| import org.mosad.teapod.util.adapter.EpisodeItemAdapter | ||||
|  | ||||
| class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : Fragment() { | ||||
| class MediaFragment(private val mediaId: Int) : Fragment() { | ||||
|  | ||||
|     private lateinit var binding: FragmentMediaBinding | ||||
|     private lateinit var adapterRecEpisodes: EpisodeItemAdapter | ||||
|     private lateinit var viewManager: RecyclerView.LayoutManager | ||||
|  | ||||
|     private lateinit var media: Media | ||||
|     private lateinit var tmdb: TMDBResponse | ||||
|     private lateinit var nextEpisode: Episode | ||||
|  | ||||
|     companion object { | ||||
| @ -46,15 +50,24 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : | ||||
|  | ||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
|         super.onViewCreated(view, savedInstanceState) | ||||
|         binding.frameLoading.visibility = View.VISIBLE | ||||
|  | ||||
|         initGUI() | ||||
|         initActions() | ||||
|         GlobalScope.launch { | ||||
|             // load the streams for the selected media | ||||
|             media = AoDParser.getMediaById(mediaId) | ||||
|             tmdb = TMDBApiController().search(media.info.title, media.type) | ||||
|  | ||||
|             withContext(Dispatchers.Main) { | ||||
|                 updateGUI() | ||||
|                 initActions() | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * if tmdb data is present, use it, else use the aod data | ||||
|      */ | ||||
|     private fun initGUI() { | ||||
|     private fun updateGUI() = with(binding) { | ||||
|         // generic gui | ||||
|         val backdropUrl = if (tmdb.backdropUrl.isNotEmpty()) tmdb.backdropUrl else media.info.posterUrl | ||||
|         val posterUrl = if (tmdb.posterUrl.isNotEmpty()) tmdb.posterUrl else media.info.posterUrl | ||||
| @ -62,27 +75,27 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : | ||||
|         Glide.with(requireContext()).load(backdropUrl) | ||||
|             .apply(RequestOptions.placeholderOf(ColorDrawable(Color.DKGRAY))) | ||||
|             .apply(RequestOptions.bitmapTransform(BlurTransformation(20, 3))) | ||||
|             .into(binding.imageBackdrop) | ||||
|             .into(imageBackdrop) | ||||
|  | ||||
|         Glide.with(requireContext()).load(posterUrl) | ||||
|             .into(binding.imagePoster) | ||||
|             .into(imagePoster) | ||||
|  | ||||
|         binding.textTitle.text = media.info.title | ||||
|         binding.textYear.text = media.info.year.toString() | ||||
|         binding.textAge.text = media.info.age.toString() | ||||
|         binding.textOverview.text = media.info.shortDesc | ||||
|         textTitle.text = media.info.title | ||||
|         textYear.text = media.info.year.toString() | ||||
|         textAge.text = media.info.age.toString() | ||||
|         textOverview.text = media.info.shortDesc | ||||
|         if (StorageController.myList.contains(media.id)) { | ||||
|             Glide.with(requireContext()).load(R.drawable.ic_baseline_check_24).into(binding.imageMyListAction) | ||||
|             Glide.with(requireContext()).load(R.drawable.ic_baseline_check_24).into(imageMyListAction) | ||||
|         } else { | ||||
|             Glide.with(requireContext()).load(R.drawable.ic_baseline_add_24).into(binding.imageMyListAction) | ||||
|             Glide.with(requireContext()).load(R.drawable.ic_baseline_add_24).into(imageMyListAction) | ||||
|         } | ||||
|  | ||||
|         // specific gui | ||||
|         if (media.type == MediaType.TVSHOW) { | ||||
|             adapterRecEpisodes = EpisodeItemAdapter(media.episodes) | ||||
|             viewManager = LinearLayoutManager(context) | ||||
|             binding.recyclerEpisodes.layoutManager = viewManager | ||||
|             binding.recyclerEpisodes.adapter = adapterRecEpisodes | ||||
|             recyclerEpisodes.layoutManager = viewManager | ||||
|             recyclerEpisodes.adapter = adapterRecEpisodes | ||||
|  | ||||
|             binding.textEpisodesOrRuntime.text = getString(R.string.text_episodes_count, media.info.episodesCount) | ||||
|  | ||||
| @ -94,16 +107,18 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : | ||||
|             } | ||||
|  | ||||
|             // title is the next episodes title | ||||
|             binding.textTitle.text = nextEpisode.title | ||||
|             textTitle.text = nextEpisode.title | ||||
|         } else if (media.type == MediaType.MOVIE) { | ||||
|             binding.recyclerEpisodes.visibility = View.GONE | ||||
|             recyclerEpisodes.visibility = View.GONE | ||||
|  | ||||
|             if (tmdb.runtime > 0) { | ||||
|                 binding.textEpisodesOrRuntime.text = getString(R.string.text_runtime, tmdb.runtime) | ||||
|                 textEpisodesOrRuntime.text = getString(R.string.text_runtime, tmdb.runtime) | ||||
|             } else { | ||||
|                 binding.textEpisodesOrRuntime.visibility = View.GONE | ||||
|                 textEpisodesOrRuntime.visibility = View.GONE | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         frameLoading.visibility = View.GONE // hide loading indicator | ||||
|     } | ||||
|  | ||||
|     private fun initActions() { | ||||
| @ -169,5 +184,4 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : | ||||
|         adapterRecEpisodes.notifyDataSetChanged() | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -1,17 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:background="?themePrimary" | ||||
|     android:clickable="true" | ||||
|     android:focusable="true"> | ||||
|  | ||||
|     <com.google.android.material.progressindicator.ProgressIndicator | ||||
|         android:id="@+id/progressBar2" | ||||
|         style="@style/Widget.MaterialComponents.ProgressIndicator.Circular.Indeterminate" | ||||
|         android:layout_width="70dp" | ||||
|         android:layout_height="70dp" | ||||
|         android:layout_gravity="center" | ||||
|         tools:visibility="visible" /> | ||||
| </FrameLayout> | ||||
| @ -135,7 +135,8 @@ | ||||
|                         android:layout_width="48dp" | ||||
|                         android:layout_height="48dp" | ||||
|                         android:src="@drawable/ic_baseline_add_24" | ||||
|                         app:tint="?buttonBackground" /> | ||||
|                         app:tint="?buttonBackground" | ||||
|                         android:contentDescription="@string/my_list" /> | ||||
|  | ||||
|                     <TextView | ||||
|                         android:id="@+id/text_my_list_action" | ||||
| @ -159,4 +160,20 @@ | ||||
|         </LinearLayout> | ||||
|     </androidx.core.widget.NestedScrollView> | ||||
|  | ||||
|     <FrameLayout | ||||
|         android:id="@+id/frame_loading" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent" | ||||
|         android:background="?themePrimary" | ||||
|         android:visibility="gone"> | ||||
|  | ||||
|         <com.google.android.material.progressindicator.ProgressIndicator | ||||
|             android:id="@+id/loadingIndicator" | ||||
|             style="@style/Widget.MaterialComponents.ProgressIndicator.Circular.Indeterminate" | ||||
|             android:layout_width="70dp" | ||||
|             android:layout_height="70dp" | ||||
|             android:layout_gravity="center" | ||||
|             tools:visibility="visible" /> | ||||
|     </FrameLayout> | ||||
|  | ||||
| </FrameLayout> | ||||
		Reference in New Issue
	
	Block a user