add top ten to home screen & minor fixes

* use plural for runtime and episodes
* code clean up
This commit is contained in:
Jannik 2021-01-21 18:22:53 +01:00
parent c6874d0e54
commit 4c5d6e6e24
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
11 changed files with 101 additions and 39 deletions

View File

@ -1,27 +1,24 @@
package org.mosad.teapod.activity.main.fragments package org.mosad.teapod.activity.main.fragments
import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.R import org.mosad.teapod.R
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.databinding.FragmentHomeBinding import org.mosad.teapod.databinding.FragmentHomeBinding
import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.util.ItemMedia import org.mosad.teapod.util.ItemMedia
import org.mosad.teapod.util.StorageController import org.mosad.teapod.util.StorageController
import org.mosad.teapod.util.adapter.MediaItemAdapter import org.mosad.teapod.util.adapter.MediaItemAdapter
import org.mosad.teapod.util.decoration.MediaItemDecoration import org.mosad.teapod.util.decoration.MediaItemDecoration
import org.mosad.teapod.util.setDrawableTop
import org.mosad.teapod.util.showFragment import org.mosad.teapod.util.showFragment
class HomeFragment : Fragment() { class HomeFragment : Fragment() {
@ -31,6 +28,7 @@ class HomeFragment : Fragment() {
private lateinit var adapterNewEpisodes: MediaItemAdapter private lateinit var adapterNewEpisodes: MediaItemAdapter
private lateinit var adapterNewSimulcasts: MediaItemAdapter private lateinit var adapterNewSimulcasts: MediaItemAdapter
private lateinit var adapterNewTitles: MediaItemAdapter private lateinit var adapterNewTitles: MediaItemAdapter
private lateinit var adapterTopTen: MediaItemAdapter
private lateinit var highlightMedia: ItemMedia private lateinit var highlightMedia: ItemMedia
@ -60,9 +58,9 @@ class HomeFragment : Fragment() {
.into(binding.imageHighlight) .into(binding.imageHighlight)
if (StorageController.myList.contains(highlightMedia.id)) { if (StorageController.myList.contains(highlightMedia.id)) {
loadIntoCompoundDrawable(R.drawable.ic_baseline_check_24, binding.textHighlightMyList) binding.textHighlightMyList.setDrawableTop(R.drawable.ic_baseline_check_24)
} else { } else {
loadIntoCompoundDrawable(R.drawable.ic_baseline_add_24, binding.textHighlightMyList) binding.textHighlightMyList.setDrawableTop(R.drawable.ic_baseline_add_24)
} }
} }
} }
@ -72,6 +70,7 @@ class HomeFragment : Fragment() {
binding.recyclerNewEpisodes.addItemDecoration(MediaItemDecoration(9)) binding.recyclerNewEpisodes.addItemDecoration(MediaItemDecoration(9))
binding.recyclerNewSimulcasts.addItemDecoration(MediaItemDecoration(9)) binding.recyclerNewSimulcasts.addItemDecoration(MediaItemDecoration(9))
binding.recyclerNewTitles.addItemDecoration(MediaItemDecoration(9)) binding.recyclerNewTitles.addItemDecoration(MediaItemDecoration(9))
binding.recyclerTopTen.addItemDecoration(MediaItemDecoration(9))
// my list // my list
val myListMedia = StorageController.myList.map { elementId -> val myListMedia = StorageController.myList.map { elementId ->
@ -93,6 +92,10 @@ class HomeFragment : Fragment() {
// new titles // new titles
adapterNewTitles = MediaItemAdapter(AoDParser.newTitlesList) adapterNewTitles = MediaItemAdapter(AoDParser.newTitlesList)
binding.recyclerNewTitles.adapter = adapterNewTitles binding.recyclerNewTitles.adapter = adapterNewTitles
// top ten
adapterTopTen = MediaItemAdapter(AoDParser.topTenList)
binding.recyclerTopTen.adapter = adapterTopTen
} }
private fun initActions() { private fun initActions() {
@ -109,10 +112,10 @@ class HomeFragment : Fragment() {
binding.textHighlightMyList.setOnClickListener { binding.textHighlightMyList.setOnClickListener {
if (StorageController.myList.contains(highlightMedia.id)) { if (StorageController.myList.contains(highlightMedia.id)) {
StorageController.myList.remove(highlightMedia.id) StorageController.myList.remove(highlightMedia.id)
loadIntoCompoundDrawable(R.drawable.ic_baseline_add_24, binding.textHighlightMyList) binding.textHighlightMyList.setDrawableTop(R.drawable.ic_baseline_add_24)
} else { } else {
StorageController.myList.add(highlightMedia.id) StorageController.myList.add(highlightMedia.id)
loadIntoCompoundDrawable(R.drawable.ic_baseline_check_24, binding.textHighlightMyList) binding.textHighlightMyList.setDrawableTop(R.drawable.ic_baseline_check_24)
} }
StorageController.saveMyList(requireContext()) StorageController.saveMyList(requireContext())
@ -138,6 +141,10 @@ class HomeFragment : Fragment() {
adapterNewTitles.onItemClick = { mediaId, _ -> adapterNewTitles.onItemClick = { mediaId, _ ->
activity?.showFragment(MediaFragment(mediaId)) activity?.showFragment(MediaFragment(mediaId))
} }
adapterTopTen.onItemClick = { mediaId, _ ->
activity?.showFragment(MediaFragment(mediaId))
}
} }
/** /**
@ -157,18 +164,4 @@ class HomeFragment : Fragment() {
adapterMyList.notifyDataSetChanged() adapterMyList.notifyDataSetChanged()
} }
private fun loadIntoCompoundDrawable(drawable: Int, textView: TextView) {
Glide.with(requireContext())
.load(drawable)
.into(object : CustomTarget<Drawable>(48, 48) {
override fun onLoadCleared(drawable: Drawable?) {
textView.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null)
}
override fun onResourceReady(res: Drawable, transition: Transition<in Drawable>?) {
textView.setCompoundDrawablesWithIntrinsicBounds(null, res, null, null)
}
})
}
} }

View File

@ -56,7 +56,7 @@ class MediaFragment(private val mediaId: Int) : Fragment() {
// only notify adapter, if initialized // only notify adapter, if initialized
if (this::adapterRecEpisodes.isInitialized) { if (this::adapterRecEpisodes.isInitialized) {
// TODO find a better solution for this // TODO find a better solution for this
media.episodes.forEachIndexed() { index, episode -> media.episodes.forEachIndexed { index, episode ->
adapterRecEpisodes.updateWatchedState(episode.watched, index) adapterRecEpisodes.updateWatchedState(episode.watched, index)
} }
adapterRecEpisodes.notifyDataSetChanged() adapterRecEpisodes.notifyDataSetChanged()
@ -94,7 +94,12 @@ class MediaFragment(private val mediaId: Int) : Fragment() {
adapterRecEpisodes = EpisodeItemAdapter(media.episodes) adapterRecEpisodes = EpisodeItemAdapter(media.episodes)
recyclerEpisodes.adapter = adapterRecEpisodes recyclerEpisodes.adapter = adapterRecEpisodes
binding.textEpisodesOrRuntime.text = getString(R.string.text_episodes_count, media.info.episodesCount) // episodes count
binding.textEpisodesOrRuntime.text = resources.getQuantityString(
R.plurals.text_episodes_count,
media.info.episodesCount,
media.info.episodesCount
)
// get next episode // get next episode
nextEpisode = if (media.episodes.firstOrNull{ !it.watched } != null) { nextEpisode = if (media.episodes.firstOrNull{ !it.watched } != null) {
@ -109,7 +114,11 @@ class MediaFragment(private val mediaId: Int) : Fragment() {
recyclerEpisodes.visibility = View.GONE recyclerEpisodes.visibility = View.GONE
if (tmdb.runtime > 0) { if (tmdb.runtime > 0) {
textEpisodesOrRuntime.text = getString(R.string.text_runtime, tmdb.runtime) textEpisodesOrRuntime.text = resources.getQuantityString(
R.plurals.text_runtime,
tmdb.runtime,
tmdb.runtime
)
} else { } else {
textEpisodesOrRuntime.visibility = View.GONE textEpisodesOrRuntime.visibility = View.GONE
} }

View File

@ -53,6 +53,10 @@ class OnboardingActivity : AppCompatActivity() {
} }
} }
fun btnNextClick(@Suppress("UNUSED_PARAMETER")v: View) {
//nextFragment() // currently not used in Teapod
}
fun btnSkipClick(@Suppress("UNUSED_PARAMETER")v: View) { fun btnSkipClick(@Suppress("UNUSED_PARAMETER")v: View) {
//launchMainActivity() // currently not used in Teapod //launchMainActivity() // currently not used in Teapod
} }

View File

@ -53,6 +53,7 @@ object AoDParser {
val newEpisodesList = arrayListOf<ItemMedia>() val newEpisodesList = arrayListOf<ItemMedia>()
val newSimulcastsList = arrayListOf<ItemMedia>() val newSimulcastsList = arrayListOf<ItemMedia>()
val newTitlesList = arrayListOf<ItemMedia>() val newTitlesList = arrayListOf<ItemMedia>()
val topTenList = arrayListOf<ItemMedia>()
fun login(): Boolean = runBlocking { fun login(): Boolean = runBlocking {
@ -236,6 +237,19 @@ object AoDParser {
} }
} }
// get top ten from AoD
topTenList.clear()
resHome.select("h2:contains(Anime Top 10)").next().select("li").forEach {
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) {
topTenList.add(ItemMedia(mediaId, mediaTitle, mediaImage))
}
}
// if highlights is empty, add a random new title // if highlights is empty, add a random new title
if (highlightsList.isEmpty()) { if (highlightsList.isEmpty()) {
if (newTitlesList.isNotEmpty()) { if (newTitlesList.isNotEmpty()) {

View File

@ -0,0 +1,7 @@
package org.mosad.teapod.util
import android.widget.TextView
fun TextView.setDrawableTop(drawable: Int) {
this.setCompoundDrawablesWithIntrinsicBounds(0, drawable, 0, 0)
}

View File

@ -10,7 +10,7 @@
android:layout_height="48dp" android:layout_height="48dp"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:background="@drawable/ic_baseline_rewind_10_24" android:background="@drawable/ic_baseline_rewind_10_24"
android:contentDescription="@string/forward_10" /> android:contentDescription="@string/rewind_10" />
<TextView <TextView
android:id="@+id/textView" android:id="@+id/textView"

View File

@ -219,6 +219,34 @@
tools:listitem="@layout/item_media" /> tools:listitem="@layout/item_media" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/linear_top_ten"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="7dp">
<TextView
android:id="@+id/text_top_ten"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:paddingTop="15dp"
android:paddingEnd="5dp"
android:paddingBottom="5dp"
android:text="@string/top_ten"
android:textSize="16sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_top_ten"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_media" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View File

@ -11,14 +11,22 @@
<string name="new_episodes">Neue Episoden</string> <string name="new_episodes">Neue Episoden</string>
<string name="new_simulcasts">Neue Simulcasts</string> <string name="new_simulcasts">Neue Simulcasts</string>
<string name="new_titles">Neue Titel</string> <string name="new_titles">Neue Titel</string>
<string name="top_ten">Top 10</string>
<!-- search fragment --> <!-- search fragment -->
<string name="search_hint">Suche nach Filmen und Serien</string> <string name="search_hint">Suche nach Filmen und Serien</string>
<!-- media fragment --> <!-- media fragment -->
<string name="button_play">Abspielen</string> <string name="button_play">Abspielen</string>
<string name="text_episodes_count">%1$d Episoden</string> <plurals name="text_episodes_count">
<item quantity="one">%d Episode</item>
<item quantity="other">%d Episoden</item>
</plurals>
<string name="text_runtime">%1$d Minuten</string> <string name="text_runtime">%1$d Minuten</string>
<plurals name="text_runtime">
<item quantity="one">%d Minute</item>
<item quantity="other">%d Minuten</item>
</plurals>
<string name="component_episode_title">Flg. %1$d %2$s</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_sub">Flg. %1$d %2$s (OmU)</string>

View File

@ -1,6 +0,0 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="text_margin">16dp</dimen>
</resources>

View File

@ -11,6 +11,7 @@
<string name="new_episodes">New episodes</string> <string name="new_episodes">New episodes</string>
<string name="new_simulcasts">New simulcasts</string> <string name="new_simulcasts">New simulcasts</string>
<string name="new_titles">New titles</string> <string name="new_titles">New titles</string>
<string name="top_ten">Top 10</string>
<!-- search fragment --> <!-- search fragment -->
<string name="search_hint">Search for movies and series</string> <string name="search_hint">Search for movies and series</string>
@ -23,8 +24,16 @@
<string name="text_overview_ex" translatable="false">Shouya Ishida starts bullying the new girl in class …</string> <string name="text_overview_ex" translatable="false">Shouya Ishida starts bullying the new girl in class …</string>
<string name="text_year_ex" translatable="false">2016</string> <string name="text_year_ex" translatable="false">2016</string>
<string name="text_age_ex" translatable="false">6</string> <string name="text_age_ex" translatable="false">6</string>
<string name="text_episodes_count">%1$d episodes</string> <string name="text_episodes_count" translatable="false">1$d episodes</string>
<plurals name="text_episodes_count">
<item quantity="one">%d episode</item>
<item quantity="other">%d episodes</item>
</plurals>
<string name="text_runtime">%1$d Minutes</string> <string name="text_runtime">%1$d Minutes</string>
<plurals name="text_runtime">
<item quantity="one">%d Minute</item>
<item quantity="other">%d Minutes</item>
</plurals>
<string name="component_episode_title">Ep. %1$d %2$s</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_sub">Ep. %1$d %2$s (Sub)</string>
<string name="component_poster_desc" translatable="false">episode poster</string> <string name="component_poster_desc" translatable="false">episode poster</string>

View File

@ -41,10 +41,6 @@
<item name="colorControlHighlight">@color/controlHighlightDark</item> <item name="colorControlHighlight">@color/controlHighlightDark</item>
</style> </style>
<style name="LicensesDialogTheme.Dark" parent="Theme.AppCompat.Dialog">
<item name="android:windowBackground">@color/themeSecondaryDark</item>
</style>
<!-- player theme --> <!-- player theme -->
<style name="PlayerTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> <style name="PlayerTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="android:windowNoTitle">true</item> <item name="android:windowNoTitle">true</item>