From 474b72df49d5c6751da16c383f9eed93fd5c09db Mon Sep 17 00:00:00 2001 From: Jannik Date: Thu, 15 Oct 2020 21:00:31 +0200 Subject: [PATCH] add favorite list to home screen --- .../java/org/mosad/teapod/MainActivity.kt | 3 ++ .../mosad/teapod/ui/fragments/HomeFragment.kt | 36 +++++++++++++- .../teapod/ui/fragments/LibraryFragment.kt | 4 -- .../teapod/ui/fragments/MediaFragment.kt | 16 +++++-- .../teapod/ui/fragments/SearchFragment.kt | 5 -- .../java/org/mosad/teapod/util/CacheHelper.kt | 47 +++++++++++++++++++ .../teapod/util/adapter/MediaItemAdapter.kt | 5 +- .../res/drawable/ic_baseline_favorite_24.xml | 10 ++++ .../ic_baseline_favorite_border_24.xml | 10 ++++ .../main/res/drawable/sl_favourite_24dp.xml | 11 +++++ app/src/main/res/layout/fragment_home.xml | 35 ++++++++++++++ app/src/main/res/layout/fragment_library.xml | 6 ++- app/src/main/res/layout/fragment_media.xml | 17 ++++++- app/src/main/res/layout/fragment_search.xml | 6 ++- app/src/main/res/layout/item_media.xml | 24 ++++++---- 15 files changed, 206 insertions(+), 29 deletions(-) create mode 100644 app/src/main/java/org/mosad/teapod/util/CacheHelper.kt create mode 100644 app/src/main/res/drawable/ic_baseline_favorite_24.xml create mode 100644 app/src/main/res/drawable/ic_baseline_favorite_border_24.xml create mode 100644 app/src/main/res/drawable/sl_favourite_24dp.xml diff --git a/app/src/main/java/org/mosad/teapod/MainActivity.kt b/app/src/main/java/org/mosad/teapod/MainActivity.kt index e8ec4f8..94a7943 100644 --- a/app/src/main/java/org/mosad/teapod/MainActivity.kt +++ b/app/src/main/java/org/mosad/teapod/MainActivity.kt @@ -42,6 +42,7 @@ import org.mosad.teapod.ui.fragments.HomeFragment import org.mosad.teapod.ui.fragments.LibraryFragment import org.mosad.teapod.ui.fragments.SearchFragment import org.mosad.teapod.ui.fragments.LoadingFragment +import org.mosad.teapod.util.CacheHelper import org.mosad.teapod.util.Media import org.mosad.teapod.util.TMDBApiController import kotlin.system.measureTimeMillis @@ -111,6 +112,8 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS showLoginDialog(true) } + CacheHelper.load(this) + // TODO save last loginSuccess, if false show login dialog even if credentials are present // running login and list in parallel does not bring any speed improvements val time = measureTimeMillis { diff --git a/app/src/main/java/org/mosad/teapod/ui/fragments/HomeFragment.kt b/app/src/main/java/org/mosad/teapod/ui/fragments/HomeFragment.kt index d0fb92d..b1b80dc 100644 --- a/app/src/main/java/org/mosad/teapod/ui/fragments/HomeFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/fragments/HomeFragment.kt @@ -5,11 +5,23 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.android.synthetic.main.fragment_home.* +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.parser.AoDParser +import org.mosad.teapod.util.CacheHelper +import org.mosad.teapod.util.adapter.MediaItemAdapter +import org.mosad.teapod.util.decoration.MediaItemDecoration class HomeFragment : Fragment() { + private lateinit var adapter: MediaItemAdapter + private lateinit var layoutManager: LinearLayoutManager override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_home, container, false) @@ -18,6 +30,28 @@ class HomeFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - text_home.text = "This is the home fragment" + GlobalScope.launch { + if (AoDParser.mediaList.isEmpty()) { + AoDParser().listAnimes() + } + + val myListMedia = AoDParser.mediaList.filter { CacheHelper.myList.contains(it.link) } + + withContext(Dispatchers.Main) { + context?.let { + layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) + adapter = MediaItemAdapter(myListMedia) + adapter.onItemClick = { media, _ -> + (activity as MainActivity).showMediaFragment(media) + } + + recycler_my_list.layoutManager = layoutManager + recycler_my_list.adapter = adapter + recycler_my_list.addItemDecoration(MediaItemDecoration(9)) + } + } + + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/mosad/teapod/ui/fragments/LibraryFragment.kt b/app/src/main/java/org/mosad/teapod/ui/fragments/LibraryFragment.kt index dc9b8b4..a6fdffd 100644 --- a/app/src/main/java/org/mosad/teapod/ui/fragments/LibraryFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/fragments/LibraryFragment.kt @@ -5,7 +5,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment -import androidx.recyclerview.widget.GridLayoutManager import kotlinx.android.synthetic.main.fragment_library.* import kotlinx.coroutines.* import org.mosad.teapod.MainActivity @@ -17,7 +16,6 @@ import org.mosad.teapod.util.adapter.MediaItemAdapter class LibraryFragment : Fragment() { private lateinit var adapter: MediaItemAdapter - private lateinit var layoutManager: GridLayoutManager override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_library, container, false) @@ -35,13 +33,11 @@ class LibraryFragment : Fragment() { // create and set the adapter, needs context withContext(Dispatchers.Main) { context?.let { - layoutManager = GridLayoutManager(context, 2) adapter = MediaItemAdapter(AoDParser.mediaList) adapter.onItemClick = { media, _ -> (activity as MainActivity).showMediaFragment(media) } - recycler_media_library.layoutManager = layoutManager recycler_media_library.adapter = adapter recycler_media_library.addItemDecoration(MediaItemDecoration(9)) } diff --git a/app/src/main/java/org/mosad/teapod/ui/fragments/MediaFragment.kt b/app/src/main/java/org/mosad/teapod/ui/fragments/MediaFragment.kt index c74d4f2..55e36f8 100644 --- a/app/src/main/java/org/mosad/teapod/ui/fragments/MediaFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/fragments/MediaFragment.kt @@ -17,6 +17,7 @@ import kotlinx.android.synthetic.main.fragment_media.* import org.mosad.teapod.MainActivity import org.mosad.teapod.R import org.mosad.teapod.parser.AoDParser +import org.mosad.teapod.util.CacheHelper import org.mosad.teapod.util.DataTypes.MediaType import org.mosad.teapod.util.adapter.EpisodeItemAdapter import org.mosad.teapod.util.Media @@ -59,6 +60,7 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : text_year.text = media.info.year.toString() text_age.text = media.info.age.toString() text_overview.text = media.info.shortDesc + check_my_list.isChecked = CacheHelper.myList.contains(media.link) // specific gui if (media.type == MediaType.TVSHOW) { @@ -81,9 +83,6 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : private fun initActions() { button_play.setOnClickListener { - println(media.episodes) - - when (media.type) { MediaType.MOVIE -> playStream(media.episodes.first().streamUrl) MediaType.TVSHOW -> playStream(media.episodes.first().streamUrl) @@ -91,6 +90,17 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : } } + // add or remove media from myList + check_my_list.setOnCheckedChangeListener { buttonView, isChecked -> + if (isChecked) { + CacheHelper.myList.add(media.link) + } else { + CacheHelper.myList.remove(media.link) + } + CacheHelper.saveMyList(requireContext()) + // TODO notify home fragment on change + } + // set onItemClick only in adapter is initialized if (this::adapterRecEpisodes.isInitialized) { adapterRecEpisodes.onItemClick = { _, position -> diff --git a/app/src/main/java/org/mosad/teapod/ui/fragments/SearchFragment.kt b/app/src/main/java/org/mosad/teapod/ui/fragments/SearchFragment.kt index 9168772..0053d6c 100644 --- a/app/src/main/java/org/mosad/teapod/ui/fragments/SearchFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/fragments/SearchFragment.kt @@ -6,7 +6,6 @@ import android.view.View import android.view.ViewGroup import android.widget.SearchView import androidx.fragment.app.Fragment -import androidx.recyclerview.widget.GridLayoutManager import kotlinx.android.synthetic.main.fragment_search.* import kotlinx.coroutines.* import org.mosad.teapod.MainActivity @@ -18,8 +17,6 @@ import org.mosad.teapod.util.adapter.MediaItemAdapter class SearchFragment : Fragment() { private var adapter : MediaItemAdapter? = null - private lateinit var layoutManager: GridLayoutManager - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_search, container, false) @@ -36,14 +33,12 @@ class SearchFragment : Fragment() { // create and set the adapter, needs context withContext(Dispatchers.Main) { context?.let { - layoutManager = GridLayoutManager(context, 2) adapter = MediaItemAdapter(AoDParser.mediaList) adapter!!.onItemClick = { media, _ -> search_text.clearFocus() (activity as MainActivity).showMediaFragment(media) } - recycler_media_search.layoutManager = layoutManager recycler_media_search.adapter = adapter recycler_media_search.addItemDecoration(MediaItemDecoration(9)) } diff --git a/app/src/main/java/org/mosad/teapod/util/CacheHelper.kt b/app/src/main/java/org/mosad/teapod/util/CacheHelper.kt new file mode 100644 index 0000000..b40bbce --- /dev/null +++ b/app/src/main/java/org/mosad/teapod/util/CacheHelper.kt @@ -0,0 +1,47 @@ +package org.mosad.teapod.util + +import android.content.Context +import android.util.Log +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import kotlinx.coroutines.* +import java.io.File + +/** + * myList should be saved in a db + */ +object CacheHelper { + + private const val fileNameMyList = "my_list.json" + + val myList = ArrayList() // a list of saved links + + fun load(context: Context) { + val file = File(context.filesDir, fileNameMyList) + + if (!file.exists()) runBlocking { saveMyList(context).join() } + + myList.clear() + myList.addAll( + GsonBuilder().create().fromJson(file.readText(), ArrayList().javaClass) + ) + } + + + fun saveMyList(context: Context): Job { + val file = File(context.filesDir, fileNameMyList) + + return GlobalScope.launch(Dispatchers.IO) { + file.writeText(Gson().toJson(myList)) + } + } + + private fun save(file: File, text: String) { + try { + file.writeText(text) + } catch (ex: Exception) { + Log.e(javaClass.name, "failed to write file \"${file.absoluteFile}\"", ex) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemAdapter.kt b/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemAdapter.kt index 215225a..ccb65af 100644 --- a/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemAdapter.kt +++ b/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemAdapter.kt @@ -11,9 +11,8 @@ import kotlinx.android.synthetic.main.item_media.view.* import org.mosad.teapod.R import org.mosad.teapod.util.Media import java.util.* -import kotlin.collections.ArrayList -class MediaItemAdapter(private val media: ArrayList) : RecyclerView.Adapter(), Filterable { +class MediaItemAdapter(private val media: List) : RecyclerView.Adapter(), Filterable { var onItemClick: ((Media, Int) -> Unit)? = null private val filter = MediaFilter() @@ -72,7 +71,7 @@ class MediaItemAdapter(private val media: ArrayList) : RecyclerView.Adapt * suppressing unchecked cast is safe, since we only use Media */ override fun publishResults(constraint: CharSequence?, results: FilterResults?) { - filteredMedia = results?.values as java.util.ArrayList + filteredMedia = results?.values as List notifyDataSetChanged() } } diff --git a/app/src/main/res/drawable/ic_baseline_favorite_24.xml b/app/src/main/res/drawable/ic_baseline_favorite_24.xml new file mode 100644 index 0000000..52d4d9b --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_favorite_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_favorite_border_24.xml b/app/src/main/res/drawable/ic_baseline_favorite_border_24.xml new file mode 100644 index 0000000..3edfe1d --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_favorite_border_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/sl_favourite_24dp.xml b/app/src/main/res/drawable/sl_favourite_24dp.xml new file mode 100644 index 0000000..ba8bf14 --- /dev/null +++ b/app/src/main/res/drawable/sl_favourite_24dp.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 82694a4..fd30f17 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -7,6 +7,41 @@ android:background="#f5f5f5" tools:context=".ui.fragments.HomeFragment"> + + + + + + + + + + + + + + + app:layout_constraintTop_toTopOf="parent" + app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" + app:spanCount="2" + tools:listitem="@layout/item_media" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_media.xml b/app/src/main/res/layout/fragment_media.xml index 88c3dee..9ed9d99 100644 --- a/app/src/main/res/layout/fragment_media.xml +++ b/app/src/main/res/layout/fragment_media.xml @@ -113,6 +113,20 @@ android:layout_marginEnd="12dp" android:text="@string/text_overview_ex" /> + + + tools:layout_editor_absoluteY="298dp" + tools:listitem="@layout/item_episode" /> diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml index af3348f..d139319 100644 --- a/app/src/main/res/layout/fragment_search.xml +++ b/app/src/main/res/layout/fragment_search.xml @@ -28,10 +28,14 @@ android:layout_height="0dp" android:clipToPadding="false" android:padding="3dp" + android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/search_text"> + app:layout_constraintTop_toBottomOf="@+id/search_text" + app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" + app:spanCount="2" + tools:listitem="@layout/item_media"> diff --git a/app/src/main/res/layout/item_media.xml b/app/src/main/res/layout/item_media.xml index 8b1ab8c..bc7e3ec 100644 --- a/app/src/main/res/layout/item_media.xml +++ b/app/src/main/res/layout/item_media.xml @@ -1,26 +1,28 @@ - + android:layout_height="match_parent"> - + android:textSize="15sp" + app:layout_constraintTop_toBottomOf="@+id/image_poster" /> + + \ No newline at end of file