add top ten to home screen & minor fixes
* use plural for runtime and episodes * code clean up
This commit is contained in:
		| @ -1,27 +1,24 @@ | ||||
| package org.mosad.teapod.activity.main.fragments | ||||
|  | ||||
| import android.graphics.drawable.Drawable | ||||
| import android.os.Bundle | ||||
| import android.util.Log | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.TextView | ||||
| import androidx.fragment.app.Fragment | ||||
| 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.GlobalScope | ||||
| import kotlinx.coroutines.launch | ||||
| import org.mosad.teapod.activity.main.MainActivity | ||||
| import org.mosad.teapod.R | ||||
| import org.mosad.teapod.activity.main.MainActivity | ||||
| import org.mosad.teapod.databinding.FragmentHomeBinding | ||||
| import org.mosad.teapod.parser.AoDParser | ||||
| import org.mosad.teapod.util.ItemMedia | ||||
| import org.mosad.teapod.util.StorageController | ||||
| import org.mosad.teapod.util.adapter.MediaItemAdapter | ||||
| import org.mosad.teapod.util.decoration.MediaItemDecoration | ||||
| import org.mosad.teapod.util.setDrawableTop | ||||
| import org.mosad.teapod.util.showFragment | ||||
|  | ||||
| class HomeFragment : Fragment() { | ||||
| @ -31,6 +28,7 @@ class HomeFragment : Fragment() { | ||||
|     private lateinit var adapterNewEpisodes: MediaItemAdapter | ||||
|     private lateinit var adapterNewSimulcasts: MediaItemAdapter | ||||
|     private lateinit var adapterNewTitles: MediaItemAdapter | ||||
|     private lateinit var adapterTopTen: MediaItemAdapter | ||||
|  | ||||
|     private lateinit var highlightMedia: ItemMedia | ||||
|  | ||||
| @ -60,9 +58,9 @@ class HomeFragment : Fragment() { | ||||
|                 .into(binding.imageHighlight) | ||||
|  | ||||
|             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 { | ||||
|                 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.recyclerNewSimulcasts.addItemDecoration(MediaItemDecoration(9)) | ||||
|         binding.recyclerNewTitles.addItemDecoration(MediaItemDecoration(9)) | ||||
|         binding.recyclerTopTen.addItemDecoration(MediaItemDecoration(9)) | ||||
|  | ||||
|         // my list | ||||
|         val myListMedia = StorageController.myList.map { elementId -> | ||||
| @ -93,6 +92,10 @@ class HomeFragment : Fragment() { | ||||
|         // new titles | ||||
|         adapterNewTitles = MediaItemAdapter(AoDParser.newTitlesList) | ||||
|         binding.recyclerNewTitles.adapter = adapterNewTitles | ||||
|  | ||||
|         // top ten | ||||
|         adapterTopTen = MediaItemAdapter(AoDParser.topTenList) | ||||
|         binding.recyclerTopTen.adapter = adapterTopTen | ||||
|     } | ||||
|  | ||||
|     private fun initActions() { | ||||
| @ -109,10 +112,10 @@ class HomeFragment : Fragment() { | ||||
|         binding.textHighlightMyList.setOnClickListener { | ||||
|             if (StorageController.myList.contains(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 { | ||||
|                 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()) | ||||
|  | ||||
| @ -138,6 +141,10 @@ class HomeFragment : Fragment() { | ||||
|         adapterNewTitles.onItemClick = { mediaId, _ -> | ||||
|             activity?.showFragment(MediaFragment(mediaId)) | ||||
|         } | ||||
|  | ||||
|         adapterTopTen.onItemClick = { mediaId, _ -> | ||||
|             activity?.showFragment(MediaFragment(mediaId)) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @ -157,18 +164,4 @@ class HomeFragment : Fragment() { | ||||
|         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) | ||||
|                 } | ||||
|  | ||||
|             }) | ||||
|     } | ||||
| } | ||||
| @ -56,7 +56,7 @@ class MediaFragment(private val mediaId: Int) : Fragment() { | ||||
|         // only notify adapter, if initialized | ||||
|         if (this::adapterRecEpisodes.isInitialized) { | ||||
|             // TODO find a better solution for this | ||||
|             media.episodes.forEachIndexed() { index, episode -> | ||||
|             media.episodes.forEachIndexed { index, episode -> | ||||
|                 adapterRecEpisodes.updateWatchedState(episode.watched, index) | ||||
|             } | ||||
|             adapterRecEpisodes.notifyDataSetChanged() | ||||
| @ -94,7 +94,12 @@ class MediaFragment(private val mediaId: Int) : Fragment() { | ||||
|             adapterRecEpisodes = EpisodeItemAdapter(media.episodes) | ||||
|             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 | ||||
|             nextEpisode = if (media.episodes.firstOrNull{ !it.watched } != null) { | ||||
| @ -109,7 +114,11 @@ class MediaFragment(private val mediaId: Int) : Fragment() { | ||||
|             recyclerEpisodes.visibility = View.GONE | ||||
|  | ||||
|             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 { | ||||
|                 textEpisodesOrRuntime.visibility = View.GONE | ||||
|             } | ||||
|  | ||||
| @ -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) { | ||||
|         //launchMainActivity() // currently not used in Teapod | ||||
|     } | ||||
|  | ||||
| @ -53,6 +53,7 @@ object AoDParser { | ||||
|     val newEpisodesList = arrayListOf<ItemMedia>() | ||||
|     val newSimulcastsList = arrayListOf<ItemMedia>() | ||||
|     val newTitlesList = arrayListOf<ItemMedia>() | ||||
|     val topTenList = arrayListOf<ItemMedia>() | ||||
|  | ||||
|     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 (highlightsList.isEmpty()) { | ||||
|             if (newTitlesList.isNotEmpty()) { | ||||
|  | ||||
							
								
								
									
										7
									
								
								app/src/main/java/org/mosad/teapod/util/Utils.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								app/src/main/java/org/mosad/teapod/util/Utils.kt
									
									
									
									
									
										Normal 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) | ||||
| } | ||||
| @ -10,7 +10,7 @@ | ||||
|         android:layout_height="48dp" | ||||
|         android:layout_alignParentEnd="true" | ||||
|         android:background="@drawable/ic_baseline_rewind_10_24" | ||||
|         android:contentDescription="@string/forward_10" /> | ||||
|         android:contentDescription="@string/rewind_10" /> | ||||
|  | ||||
|     <TextView | ||||
|         android:id="@+id/textView" | ||||
|  | ||||
| @ -219,6 +219,34 @@ | ||||
|                     tools:listitem="@layout/item_media" /> | ||||
|             </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> | ||||
|     </ScrollView> | ||||
|  | ||||
|  | ||||
| @ -11,14 +11,22 @@ | ||||
|     <string name="new_episodes">Neue Episoden</string> | ||||
|     <string name="new_simulcasts">Neue Simulcasts</string> | ||||
|     <string name="new_titles">Neue Titel</string> | ||||
|     <string name="top_ten">Top 10</string> | ||||
|  | ||||
|     <!-- search fragment --> | ||||
|     <string name="search_hint">Suche nach Filmen und Serien</string> | ||||
|  | ||||
|     <!-- media fragment --> | ||||
|     <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> | ||||
|     <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_sub">Flg. %1$d %2$s (OmU)</string> | ||||
|  | ||||
|  | ||||
| @ -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> | ||||
| @ -11,6 +11,7 @@ | ||||
|     <string name="new_episodes">New episodes</string> | ||||
|     <string name="new_simulcasts">New simulcasts</string> | ||||
|     <string name="new_titles">New titles</string> | ||||
|     <string name="top_ten">Top 10</string> | ||||
|  | ||||
|     <!-- search fragment --> | ||||
|     <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_year_ex" translatable="false">2016</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> | ||||
|     <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_sub">Ep. %1$d %2$s (Sub)</string> | ||||
|     <string name="component_poster_desc" translatable="false">episode poster</string> | ||||
|  | ||||
| @ -41,10 +41,6 @@ | ||||
|         <item name="colorControlHighlight">@color/controlHighlightDark</item> | ||||
|     </style> | ||||
|  | ||||
|     <style name="LicensesDialogTheme.Dark" parent="Theme.AppCompat.Dialog"> | ||||
|         <item name="android:windowBackground">@color/themeSecondaryDark</item> | ||||
|     </style> | ||||
|  | ||||
|     <!-- player theme --> | ||||
|     <style name="PlayerTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> | ||||
|         <item name="android:windowNoTitle">true</item> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user