add numberStr to AoDEpisode type & show tmdb episode info in player
* use numberStr instead of index to display the correct episode number, allowing for number such as "12.5" * show tmdb episode description in player if found and aod description is missing
This commit is contained in:
		| @ -393,7 +393,8 @@ object AoDParser { | ||||
|                         description = episode.description, | ||||
|                         shortDesc = episodesInfo[episode.mediaid]?.shortDesc ?: "", | ||||
|                         imageURL = episode.image, | ||||
|                         number = index, | ||||
|                         numberStr = episode.title.substringAfter(", Ep. ", ""), // TODO move to parsePalylist | ||||
|                         index = index, | ||||
|                         watched = episodesInfo[episode.mediaid]?.watched ?: false, | ||||
|                         watchedCallback = episodesInfo[episode.mediaid]?.watchedCallback ?: "", | ||||
|                         streams = mutableListOf(Stream(episode.sources.first().file, aodPlaylist.language)) | ||||
|  | ||||
| @ -81,7 +81,7 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic | ||||
|     fun updateNextEpisode(episodeId: Int) { | ||||
|         if (media.type == MediaType.MOVIE) return // return if movie | ||||
|  | ||||
|         nextEpisodeId = media.playlist.firstOrNull { it.number > media.getEpisodeById(episodeId).number }?.mediaId | ||||
|         nextEpisodeId = media.playlist.firstOrNull { it.index > media.getEpisodeById(episodeId).index }?.mediaId | ||||
|             ?: media.playlist.first().mediaId | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -20,6 +20,8 @@ import org.mosad.teapod.R | ||||
| import org.mosad.teapod.parser.AoDParser | ||||
| import org.mosad.teapod.preferences.Preferences | ||||
| import org.mosad.teapod.util.* | ||||
| import org.mosad.teapod.util.tmdb.TMDBApiController | ||||
| import org.mosad.teapod.util.tmdb.TMDBTVSeason | ||||
| import java.util.* | ||||
| import kotlin.collections.ArrayList | ||||
|  | ||||
| @ -46,6 +48,8 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application) | ||||
|         internal set | ||||
|     var nextEpisode: AoDEpisode? = null | ||||
|         internal set | ||||
|     var tmdbTVSeason: TMDBTVSeason? =null | ||||
|         internal set | ||||
|     var mediaMeta: Meta? = null | ||||
|         internal set | ||||
|     var currentEpisodeMeta: EpisodeMeta? = null | ||||
| @ -83,6 +87,15 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application) | ||||
|             mediaMeta = loadMediaMeta(media.aodId) // can be done blocking, since it should be cached | ||||
|         } | ||||
|  | ||||
|         // run async as it should be loaded by the time the episodes a | ||||
|         viewModelScope.launch { | ||||
|             // get season info, if metaDB knows the tv show | ||||
|             if (media.type == DataTypes.MediaType.TVSHOW && mediaMeta != null) { | ||||
|                 val tvShowMeta = mediaMeta as TVShowMeta | ||||
|                 //tmdbTVSeason = TMDBApiController().getTVSeasonDetails(tvShowMeta.tmdbId, tvShowMeta.tmdbSeasonNumber) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         currentEpisode = media.getEpisodeById(episodeId) | ||||
|         nextEpisode = selectNextEpisode() | ||||
|         currentEpisodeMeta = getEpisodeMetaByAoDMediaId(currentEpisode.mediaId) | ||||
| @ -159,7 +172,7 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application) | ||||
|         return if (media.type == DataTypes.MediaType.TVSHOW) { | ||||
|             getApplication<Application>().getString( | ||||
|                 R.string.component_episode_title, | ||||
|                 currentEpisode.number, | ||||
|                 currentEpisode.numberStr, | ||||
|                 currentEpisode.description | ||||
|             ) | ||||
|         } else { | ||||
| @ -189,7 +202,7 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application) | ||||
|      * episode, return null | ||||
|      */ | ||||
|     private fun selectNextEpisode(): AoDEpisode? { | ||||
|         return media.playlist.firstOrNull { it.number > media.getEpisodeById(currentEpisode.mediaId).number } | ||||
|         return media.playlist.firstOrNull { it.index > media.getEpisodeById(currentEpisode.mediaId).index } | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -28,16 +28,15 @@ class EpisodesListPlayer @JvmOverloads constructor( | ||||
|         } | ||||
|  | ||||
|         model?.let { | ||||
|             adapterRecEpisodes = PlayerEpisodeItemAdapter(model.media.playlist) | ||||
|  | ||||
|             adapterRecEpisodes = PlayerEpisodeItemAdapter(model.media.playlist, model.tmdbTVSeason?.episodes) | ||||
|             adapterRecEpisodes.onImageClick = { _, position -> | ||||
|                 (this.parent as ViewGroup).removeView(this) | ||||
|                 model.playEpisode(model.media.playlist[position], replace = true) | ||||
|             } | ||||
|             adapterRecEpisodes.currentSelected = model.currentEpisode.number - 1 | ||||
|             adapterRecEpisodes.currentSelected = model.currentEpisode.index | ||||
|  | ||||
|             binding.recyclerEpisodesPlayer.adapter = adapterRecEpisodes | ||||
|             binding.recyclerEpisodesPlayer.scrollToPosition(model.currentEpisode.number - 1) // number != index | ||||
|             binding.recyclerEpisodesPlayer.scrollToPosition(model.currentEpisode.index) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| package org.mosad.teapod.util | ||||
|  | ||||
| import java.util.* | ||||
| import kotlin.collections.ArrayList | ||||
| import java.util.Locale | ||||
|  | ||||
| class DataTypes { | ||||
|     enum class MediaType { | ||||
| @ -41,9 +40,6 @@ data class ItemMedia( | ||||
|     val posterUrl: String | ||||
| ) | ||||
|  | ||||
| /** | ||||
|  * TODO the episodes workflow could use a clean up/rework | ||||
|  */ | ||||
| // TODO replace playlist: List<AoDEpisode> with a map? | ||||
| data class AoDMedia( | ||||
|     val aodId: Int, | ||||
| @ -56,7 +52,6 @@ data class AoDMedia( | ||||
|     val similar: List<ItemMedia>, | ||||
|     val playlist: List<AoDEpisode>, | ||||
| ) { | ||||
|     fun hasEpisode(mediaId: Int) = playlist.any { it.mediaId == mediaId } | ||||
|     fun getEpisodeById(mediaId: Int) = playlist.firstOrNull { it.mediaId == mediaId } | ||||
|         ?: AoDEpisodeNone | ||||
| } | ||||
| @ -67,7 +62,8 @@ data class AoDEpisode( | ||||
|     val description: String, | ||||
|     val shortDesc: String, | ||||
|     val imageURL: String, | ||||
|     val number: Int, | ||||
|     val numberStr: String, | ||||
|     val index: Int, | ||||
|     var watched: Boolean, | ||||
|     val watchedCallback: String, | ||||
|     val streams: MutableList<Stream>, | ||||
| @ -113,6 +109,7 @@ val AoDEpisodeNone = AoDEpisode( | ||||
|     "", | ||||
|     "", | ||||
|     "", | ||||
|     "", | ||||
|     -1, | ||||
|     false, | ||||
|     "", | ||||
|  | ||||
| @ -27,9 +27,9 @@ class EpisodeItemAdapter(private val episodes: List<AoDEpisode>, private val tmd | ||||
|         val ep = episodes[position] | ||||
|  | ||||
|         val titleText = if (ep.hasDub()) { | ||||
|             context.getString(R.string.component_episode_title, ep.number, ep.description) | ||||
|             context.getString(R.string.component_episode_title, ep.numberStr, ep.description) | ||||
|         } else { | ||||
|             context.getString(R.string.component_episode_title_sub, ep.number, ep.description) | ||||
|             context.getString(R.string.component_episode_title_sub, ep.numberStr, ep.description) | ||||
|         } | ||||
|  | ||||
|         holder.binding.textEpisodeTitle.text = titleText | ||||
|  | ||||
| @ -10,8 +10,9 @@ import jp.wasabeef.glide.transformations.RoundedCornersTransformation | ||||
| import org.mosad.teapod.R | ||||
| import org.mosad.teapod.databinding.ItemEpisodePlayerBinding | ||||
| import org.mosad.teapod.util.AoDEpisode | ||||
| import org.mosad.teapod.util.tmdb.TMDBTVEpisode | ||||
|  | ||||
| class PlayerEpisodeItemAdapter(private val episodes: List<AoDEpisode>) : RecyclerView.Adapter<PlayerEpisodeItemAdapter.EpisodeViewHolder>() { | ||||
| class PlayerEpisodeItemAdapter(private val episodes: List<AoDEpisode>, private val tmdbEpisodes: List<TMDBTVEpisode>?) : RecyclerView.Adapter<PlayerEpisodeItemAdapter.EpisodeViewHolder>() { | ||||
|  | ||||
|     var onImageClick: ((String, Int) -> Unit)? = null | ||||
|     var currentSelected: Int = -1 // -1, since position should never be < 0 | ||||
| @ -25,13 +26,19 @@ class PlayerEpisodeItemAdapter(private val episodes: List<AoDEpisode>) : Recycle | ||||
|         val ep = episodes[position] | ||||
|  | ||||
|         val titleText = if (ep.hasDub()) { | ||||
|             context.getString(R.string.component_episode_title, ep.number, ep.description) | ||||
|             context.getString(R.string.component_episode_title, ep.numberStr, ep.description) | ||||
|         } else { | ||||
|             context.getString(R.string.component_episode_title_sub, ep.number, ep.description) | ||||
|             context.getString(R.string.component_episode_title_sub, ep.numberStr, ep.description) | ||||
|         } | ||||
|  | ||||
|         holder.binding.textEpisodeTitle2.text = titleText | ||||
|         holder.binding.textEpisodeDesc2.text = ep.shortDesc | ||||
|         holder.binding.textEpisodeDesc2.text = if (ep.shortDesc.isNotEmpty()) { | ||||
|             ep.shortDesc | ||||
|         } else if (tmdbEpisodes != null && position < tmdbEpisodes.size){ | ||||
|             tmdbEpisodes[position].overview | ||||
|         } else { | ||||
|             "" | ||||
|         } | ||||
|  | ||||
|         if (ep.imageURL.isNotEmpty()) { | ||||
|             Glide.with(context).load(ep.imageURL) | ||||
|  | ||||
| @ -51,7 +51,8 @@ | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent" | ||||
|         android:layout_marginTop="5dp" | ||||
|         android:maxLines="10" | ||||
|         android:text="@string/text_overview_ex" | ||||
|         android:textColor="@color/textPrimaryDark"/> | ||||
|         android:textColor="@color/textPrimaryDark" /> | ||||
|  | ||||
| </LinearLayout> | ||||
| @ -27,8 +27,8 @@ | ||||
|         <item quantity="other">%d Minuten</item> | ||||
|     </plurals> | ||||
|     <string name="similar_titles">Ähnliche Titel</string> | ||||
|     <string name="component_episode_title">Flg. %1$d %2$s</string> | ||||
|     <string name="component_episode_title_sub">Flg. %1$d %2$s (OmU)</string> | ||||
|     <string name="component_episode_title">Flg. %1$s %2$s</string> | ||||
|     <string name="component_episode_title_sub">Flg. %1$s %2$s (OmU)</string> | ||||
|  | ||||
|     <!-- settings fragment --> | ||||
|     <string name="account">Account</string> | ||||
|  | ||||
| @ -34,8 +34,8 @@ | ||||
|         <item quantity="other">%d Minutes</item> | ||||
|     </plurals> | ||||
|     <string name="similar_titles">Similar titles</string> | ||||
|     <string name="component_episode_title">Ep. %1$d %2$s</string> | ||||
|     <string name="component_episode_title_sub">Ep. %1$d %2$s (Sub)</string> | ||||
|     <string name="component_episode_title">Ep. %1$s %2$s</string> | ||||
|     <string name="component_episode_title_sub">Ep. %1$s %2$s (Sub)</string> | ||||
|     <string name="component_poster_desc" translatable="false">episode poster</string> | ||||
|     <string name="component_watched_desc" translatable="false">already watched</string> | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user