add similar media to MediaFragment

* parse similar media in AoDParser
This commit is contained in:
Jannik 2021-01-31 22:11:08 +01:00
parent f44dc4ddac
commit a21ef195c9
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
31 changed files with 133 additions and 83 deletions

View File

@ -13,7 +13,7 @@
android:supportsRtl="true"
android:theme="@style/AppTheme.Dark">
<activity
android:name=".activity.SplashActivity"
android:name="org.mosad.teapod.ui.activity.SplashActivity"
android:label="@string/app_name"
android:theme="@style/SplashTheme"
android:screenOrientation="portrait">
@ -23,24 +23,24 @@
</intent-filter>
</activity>
<activity
android:name=".activity.onboarding.OnboardingActivity"
android:name="org.mosad.teapod.ui.activity.onboarding.OnboardingActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustPan">
</activity>
<activity
android:name=".activity.main.MainActivity"
android:name="org.mosad.teapod.ui.activity.main.MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
</activity>
<activity
android:name="org.mosad.teapod.activity.player.PlayerActivity"
android:name="org.mosad.teapod.ui.activity.player.PlayerActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|layoutDirection"
android:excludeFromRecents="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:parentActivityName=".activity.main.MainActivity"
android:parentActivityName="org.mosad.teapod.ui.activity.main.MainActivity"
android:supportsPictureInPicture="true"
android:taskAffinity=".player.PlayerActivity"
android:theme="@style/PlayerTheme"

View File

@ -1,18 +0,0 @@
package org.mosad.teapod.activity.main.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.databinding.FragmentMediaSimilarBinding
class MediaSimilarFragment : Fragment() {
private lateinit var binding: FragmentMediaSimilarBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = FragmentMediaSimilarBinding.inflate(inflater, container, false)
return binding.root
}
}

View File

@ -323,7 +323,7 @@ object AoDParser {
}
Log.i(javaClass.name, "Loaded playlists successfully")
// parse additional info from the media page
// additional info from the media page
res.select("table.vertical-table").select("tr").forEach { row ->
when (row.select("th").text().toLowerCase(Locale.ROOT)) {
"produktionsjahr" -> media.info.year = row.select("td").text().toInt()
@ -337,7 +337,21 @@ object AoDParser {
}
}
// parse additional information for tv shows the episode title (description) is loaded from the "api"
// similar titles from media page
media.info.similar = res.select("h2:contains(Ähnliche Animes)").next().select("li").mapNotNull {
val mediaId = it.select("a.thumbs").attr("href")
.substringAfterLast("/").toIntOrNull()
val mediaImage = it.select("a.thumbs > img").attr("src")
val mediaTitle = it.select("a").text()
if (mediaId != null) {
ItemMedia(mediaId, mediaTitle, mediaImage)
} else {
null
}
}
// additional information for tv shows the episode title (description) is loaded from the "api"
if (media.type == MediaType.TVSHOW) {
res.select("div.three-box-container > div.episodebox").forEach { episodebox ->
// make sure the episode has a streaming link

View File

@ -1,9 +1,9 @@
package org.mosad.teapod.activity
package org.mosad.teapod.ui.activity
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.ui.activity.main.MainActivity
class SplashActivity : AppCompatActivity() {

View File

@ -20,7 +20,7 @@
*
*/
package org.mosad.teapod.activity.main
package org.mosad.teapod.ui.activity.main
import android.content.Intent
import android.os.Bundle
@ -31,27 +31,25 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.commit
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.callbacks.onDismiss
import com.afollestad.materialdialogs.utils.MDUtil.isLandscape
import com.google.android.material.bottomnavigation.BottomNavigationView
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.runBlocking
import org.mosad.teapod.R
import org.mosad.teapod.databinding.ActivityMainBinding
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.activity.player.PlayerActivity
import org.mosad.teapod.ui.activity.player.PlayerActivity
import org.mosad.teapod.preferences.EncryptedPreferences
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.components.LoginDialog
import org.mosad.teapod.activity.main.fragments.AccountFragment
import org.mosad.teapod.activity.main.fragments.HomeFragment
import org.mosad.teapod.activity.main.fragments.LibraryFragment
import org.mosad.teapod.activity.main.fragments.SearchFragment
import org.mosad.teapod.activity.onboarding.OnboardingActivity
import org.mosad.teapod.ui.activity.main.fragments.AccountFragment
import org.mosad.teapod.ui.activity.main.fragments.HomeFragment
import org.mosad.teapod.ui.activity.main.fragments.LibraryFragment
import org.mosad.teapod.ui.activity.main.fragments.SearchFragment
import org.mosad.teapod.ui.activity.onboarding.OnboardingActivity
import org.mosad.teapod.util.DataTypes
import org.mosad.teapod.util.StorageController
import org.mosad.teapod.util.exitAndRemoveTask
import java.net.SocketTimeoutException
import kotlin.system.exitProcess
import kotlin.system.measureTimeMillis
class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener {

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.main.fragments
package org.mosad.teapod.ui.activity.main.fragments
import android.content.Intent
import android.net.Uri

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.main.fragments
package org.mosad.teapod.ui.activity.main.fragments
import android.os.Bundle
import android.util.Log
@ -9,7 +9,7 @@ import androidx.fragment.app.Fragment
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.listItemsSingleChoice
import org.mosad.teapod.BuildConfig
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.ui.activity.main.MainActivity
import org.mosad.teapod.R
import org.mosad.teapod.databinding.FragmentAccountBinding
import org.mosad.teapod.parser.AoDParser

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.main.fragments
package org.mosad.teapod.ui.activity.main.fragments
import android.os.Bundle
import android.util.Log
@ -11,7 +11,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.mosad.teapod.R
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.ui.activity.main.MainActivity
import org.mosad.teapod.databinding.FragmentHomeBinding
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.util.ItemMedia

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.main.fragments
package org.mosad.teapod.ui.activity.main.fragments
import android.os.Bundle
import android.view.LayoutInflater
@ -9,7 +9,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.databinding.FragmentLibraryBinding
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.util.adapter.MediaItemAdapter

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.main.fragments
package org.mosad.teapod.ui.activity.main.fragments
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
@ -17,14 +17,16 @@ import com.google.android.material.tabs.TabLayoutMediator
import jp.wasabeef.glide.transformations.BlurTransformation
import kotlinx.coroutines.*
import org.mosad.teapod.R
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.activity.main.viewmodel.MediaFragmentViewModel
import org.mosad.teapod.ui.activity.main.MainActivity
import org.mosad.teapod.ui.activity.main.viewmodel.MediaFragmentViewModel
import org.mosad.teapod.databinding.FragmentMediaBinding
import org.mosad.teapod.util.*
import org.mosad.teapod.util.DataTypes.MediaType
/**
* TODO use a shared ViewModel for MediaFragment and it's sibling Fragments (episodes and similar)
* The media detail fragment.
* Note: the fragment is created only once, when selecting a similar title etc.
* therefore fragments may be not empty and model may be the old one
*/
class MediaFragment(private val mediaId: Int) : Fragment() {
@ -98,6 +100,10 @@ class MediaFragment(private val mediaId: Int) : Fragment() {
Glide.with(requireContext()).load(R.drawable.ic_baseline_add_24).into(binding.imageMyListAction)
}
// clear fragments, since it lives in onCreate scope (don't do this in onPause/onStop -> FragmentManager transaction)
fragments.clear()
pagerAdapter.notifyDataSetChanged()
// specific gui
if (media.type == MediaType.TVSHOW) {
// get next episode
@ -134,8 +140,10 @@ class MediaFragment(private val mediaId: Int) : Fragment() {
}
// if has similar titles
fragments.add(MediaSimilarFragment())
pagerAdapter.notifyDataSetChanged()
if (media.info.similar.isNotEmpty()) {
fragments.add(MediaFragmentSimilar())
pagerAdapter.notifyDataSetChanged()
}
binding.frameLoading.visibility = View.GONE // hide loading indicator
}

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.main.fragments
package org.mosad.teapod.ui.activity.main.fragments
import android.os.Bundle
import android.util.Log
@ -7,8 +7,8 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.activity.main.viewmodel.MediaFragmentViewModel
import org.mosad.teapod.ui.activity.main.MainActivity
import org.mosad.teapod.ui.activity.main.viewmodel.MediaFragmentViewModel
import org.mosad.teapod.databinding.FragmentMediaEpisodesBinding
import org.mosad.teapod.util.Episode
import org.mosad.teapod.util.adapter.EpisodeItemAdapter

View File

@ -0,0 +1,39 @@
package org.mosad.teapod.ui.activity.main.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import org.mosad.teapod.databinding.FragmentMediaSimilarBinding
import org.mosad.teapod.ui.activity.main.viewmodel.MediaFragmentViewModel
import org.mosad.teapod.util.adapter.MediaItemAdapter
import org.mosad.teapod.util.showFragment
class MediaFragmentSimilar : Fragment() {
private lateinit var binding: FragmentMediaSimilarBinding
private val model: MediaFragmentViewModel by activityViewModels()
private lateinit var adapterSimilar: MediaItemAdapter
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = FragmentMediaSimilarBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
adapterSimilar = MediaItemAdapter(model.media.info.similar)
binding.recyclerMediaSimilar.adapter = adapterSimilar
// set onItemClick only in adapter is initialized
if (this::adapterSimilar.isInitialized) {
adapterSimilar.onItemClick = { mediaId, _ ->
activity?.showFragment(MediaFragment(mediaId))
}
}
}
}

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.main.fragments
package org.mosad.teapod.ui.activity.main.fragments
import android.os.Bundle
import android.view.LayoutInflater
@ -7,7 +7,6 @@ import android.view.ViewGroup
import android.widget.SearchView
import androidx.fragment.app.Fragment
import kotlinx.coroutines.*
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.databinding.FragmentSearchBinding
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.util.decoration.MediaItemDecoration

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.main.viewmodel
package org.mosad.teapod.ui.activity.main.viewmodel
import android.app.Application
import androidx.lifecycle.AndroidViewModel
@ -18,6 +18,9 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic
var tmdb = TMDBResponse()
internal set
/**
* set media, tmdb and nextEpisode
*/
suspend fun load(mediaId: Int) {
media = AoDParser.getMediaById(mediaId)
tmdb = TMDBApiController().search(media.info.title, media.type)

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.onboarding
package org.mosad.teapod.ui.activity.onboarding
import android.os.Bundle
import android.view.LayoutInflater

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.onboarding
package org.mosad.teapod.ui.activity.onboarding
import android.os.Bundle
import android.view.LayoutInflater

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.onboarding
package org.mosad.teapod.ui.activity.onboarding
import android.content.Intent
import android.os.Bundle
@ -8,7 +8,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.tabs.TabLayoutMediator
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.ui.activity.main.MainActivity
import org.mosad.teapod.databinding.ActivityOnboardingBinding
class OnboardingActivity : AppCompatActivity() {

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.player
package org.mosad.teapod.ui.activity.player
import android.animation.Animator
import android.animation.AnimatorListenerAdapter

View File

@ -1,4 +1,4 @@
package org.mosad.teapod.activity.player
package org.mosad.teapod.ui.activity.player
import android.app.Application
import android.net.Uri

View File

@ -6,7 +6,7 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.LinearLayout
import org.mosad.teapod.databinding.PlayerEpisodesListBinding
import org.mosad.teapod.activity.player.PlayerViewModel
import org.mosad.teapod.ui.activity.player.PlayerViewModel
import org.mosad.teapod.util.adapter.PlayerEpisodeItemAdapter
class EpisodesListPlayer @JvmOverloads constructor(

View File

@ -13,7 +13,7 @@ import android.widget.TextView
import androidx.core.view.children
import org.mosad.teapod.R
import org.mosad.teapod.databinding.PlayerLanguageSettingsBinding
import org.mosad.teapod.activity.player.PlayerViewModel
import org.mosad.teapod.ui.activity.player.PlayerViewModel
import java.util.*
class LanguageSettingsPlayer @JvmOverloads constructor(

View File

@ -62,7 +62,8 @@ data class Info(
var description: String = "",
var year: Int = 0,
var age: Int = 0,
var episodesCount: Int = 0
var episodesCount: Int = 0,
var similar: List<ItemMedia> = listOf()
)
/**

View File

@ -7,7 +7,7 @@
android:layout_height="match_parent"
android:background="#000000"
android:keepScreenOn="true"
tools:context=".activity.player.PlayerActivity">
tools:context=".ui.activity.player.PlayerActivity">
<com.google.android.exoplayer2.ui.StyledPlayerView
android:id="@+id/video_view"

View File

@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".activity.main.fragments.AboutFragment">
tools:context=".ui.activity.main.fragments.AboutFragment">
<LinearLayout
android:layout_width="match_parent"

View File

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".activity.main.fragments.AccountFragment">
tools:context=".ui.activity.main.fragments.AccountFragment">
<ScrollView
android:layout_width="match_parent"

View File

@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".activity.main.fragments.HomeFragment">
tools:context=".ui.activity.main.fragments.HomeFragment">
<ScrollView
android:layout_width="match_parent"

View File

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".activity.main.fragments.LibraryFragment">
tools:context=".ui.activity.main.fragments.LibraryFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_media_library"

View File

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".activity.main.fragments.MediaFragment">
tools:context=".ui.activity.main.fragments.MediaFragment">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"

View File

@ -2,17 +2,24 @@
<androidx.constraintlayout.widget.ConstraintLayout
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">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:text="similar media"
android:textColor="?textPrimary"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_media_similar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="3dp"
android:clipToPadding="false"
android:orientation="vertical"
android:padding="3dp"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="parent"
app:spanCount="2"
tools:listitem="@layout/item_media" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".activity.main.fragments.SearchFragment">
tools:context=".ui.activity.main.fragments.SearchFragment">
<SearchView
android:id="@+id/search_text"

View File

@ -7,25 +7,25 @@
<fragment
android:id="@+id/navigation_home"
android:name="org.mosad.teapod.activity.main.fragments.HomeFragment"
android:name="org.mosad.teapod.ui.activity.main.fragments.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/navigation_library"
android:name="org.mosad.teapod.activity.main.fragments.LibraryFragment"
android:name="org.mosad.teapod.ui.activity.main.fragments.LibraryFragment"
android:label="@string/title_library"
tools:layout="@layout/fragment_library" />
<fragment
android:id="@+id/navigation_search"
android:name="org.mosad.teapod.activity.main.fragments.SearchFragment"
android:name="org.mosad.teapod.ui.activity.main.fragments.SearchFragment"
android:label="@string/title_search"
tools:layout="@layout/fragment_search" />
<fragment
android:id="@+id/navigation_account"
android:name="org.mosad.teapod.activity.main.fragments.AccountFragment"
android:name="org.mosad.teapod.ui.activity.main.fragments.AccountFragment"
android:label="@string/title_account"
tools:layout="@layout/fragment_account" />