Skip to content

Commit 42162ed

Browse files
authored
Merge pull request #998 from UweTrottmann/standalone-new-episodes-screen
Standalone new episodes screen with filters
2 parents d9be918 + 1c121fb commit 42162ed

29 files changed

+794
-464
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Version 73
1515
----------
1616
*in development*
1717

18+
* 🌟 Discover: add new episodes screen with year and language filters, similar to popular shows screen.
1819
* 🔧 History: sort Trakt friends by latest activity first.
1920
* 🔨 Comments: do not display misleading "Could not modify data" message when commenting on a show.
2021

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@
156156
</activity>
157157
<activity android:name=".shows.search.similar.SimilarShowsActivity" />
158158
<activity
159-
android:name=".shows.search.discover.TraktShowsActivity"
159+
android:name=".shows.search.discover.DiscoverShowsActivity"
160160
android:parentActivityName=".ui.SearchActivity" />
161161

162162
<!-- Movies -->

app/src/main/java/com/battlelancer/seriesguide/movies/MoviesDiscoverAdapter.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222

2323
public class MoviesDiscoverAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
2424

25-
static final int VIEW_TYPE_LINK = R.layout.item_discover_link;
26-
static final int VIEW_TYPE_HEADER = R.layout.item_discover_header;
25+
static final int VIEW_TYPE_LINK = R.layout.item_discover_movies_link;
26+
static final int VIEW_TYPE_HEADER = R.layout.item_discover_movies_header;
2727
static final int VIEW_TYPE_MOVIE = R.layout.item_movie;
2828

2929
interface ItemClickListener extends MovieClickListener {
@@ -137,7 +137,7 @@ static class HeaderViewHolder extends RecyclerView.ViewHolder {
137137
public static HeaderViewHolder inflate(ViewGroup parent) {
138138
return new HeaderViewHolder(
139139
LayoutInflater.from(parent.getContext())
140-
.inflate(R.layout.item_discover_header, parent, false)
140+
.inflate(R.layout.item_discover_movies_header, parent, false)
141141
);
142142
}
143143
}
@@ -163,7 +163,7 @@ public static LinkViewHolder inflate(
163163
) {
164164
return new LinkViewHolder(
165165
LayoutInflater.from(parent.getContext())
166-
.inflate(R.layout.item_discover_link, parent, false),
166+
.inflate(R.layout.item_discover_movies_link, parent, false),
167167
itemClickListener
168168
);
169169
}

app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/TraktShowsActivity.kt renamed to app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/DiscoverShowsActivity.kt

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,57 @@ import android.content.Intent
88
import android.os.Bundle
99
import androidx.core.view.isVisible
1010
import com.battlelancer.seriesguide.R
11-
import com.battlelancer.seriesguide.databinding.ActivityTraktShowsBinding
11+
import com.battlelancer.seriesguide.databinding.ActivityDiscoverShowsBinding
12+
import com.battlelancer.seriesguide.shows.search.newepisodes.ShowsNewEpisodesFragment
13+
import com.battlelancer.seriesguide.shows.search.popular.ShowsDiscoverPagingFragment
1214
import com.battlelancer.seriesguide.shows.search.popular.ShowsPopularFragment
1315
import com.battlelancer.seriesguide.shows.search.similar.SimilarShowsActivity
1416
import com.battlelancer.seriesguide.shows.search.similar.SimilarShowsFragment
1517
import com.battlelancer.seriesguide.ui.BaseMessageActivity
1618
import com.battlelancer.seriesguide.util.TaskManager
1719
import com.battlelancer.seriesguide.util.ThemeUtils
1820

19-
class TraktShowsActivity : BaseMessageActivity(), AddShowDialogFragment.OnAddShowListener {
21+
class DiscoverShowsActivity : BaseMessageActivity(), AddShowDialogFragment.OnAddShowListener {
2022

21-
lateinit var binding: ActivityTraktShowsBinding
23+
lateinit var binding: ActivityDiscoverShowsBinding
2224

2325
override fun onCreate(savedInstanceState: Bundle?) {
2426
super.onCreate(savedInstanceState)
25-
binding = ActivityTraktShowsBinding.inflate(layoutInflater)
27+
binding = ActivityDiscoverShowsBinding.inflate(layoutInflater)
2628
setContentView(binding.root)
2729
ThemeUtils.configureForEdgeToEdge(binding.root)
2830

29-
val link = TraktShowsLink.fromId(intent.getIntExtra(EXTRA_LINK, -1))
31+
val link = DiscoverShowsLink.fromId(intent.getIntExtra(EXTRA_LINK, -1))
3032

3133
// Change the scrolling view the AppBarLayout should use to determine if it should lift.
3234
// This is required so the AppBarLayout does not flicker its background when scrolling.
3335
binding.sgAppBarLayout.liftOnScrollTargetViewId = when (link) {
34-
TraktShowsLink.POPULAR -> ShowsPopularFragment.liftOnScrollTargetViewId
36+
DiscoverShowsLink.POPULAR, DiscoverShowsLink.NEW_EPISODES -> ShowsDiscoverPagingFragment.liftOnScrollTargetViewId
3537
else -> TraktAddFragment.liftOnScrollTargetViewId
3638
}
37-
// Filters currently only supported for the popular screen
38-
binding.scrollViewTraktShowsChips.isVisible = link == TraktShowsLink.POPULAR
39+
// Filters only supported on TMDB provided lists
40+
binding.scrollViewTraktShowsChips.isVisible =
41+
link == DiscoverShowsLink.POPULAR || link == DiscoverShowsLink.NEW_EPISODES
3942
setupActionBar(link)
4043

4144
if (savedInstanceState == null) {
4245
val fragment = when (link) {
43-
TraktShowsLink.POPULAR -> ShowsPopularFragment()
46+
DiscoverShowsLink.POPULAR -> ShowsPopularFragment()
47+
DiscoverShowsLink.NEW_EPISODES -> ShowsNewEpisodesFragment()
4448
else -> TraktAddFragment.newInstance(link)
4549
}
4650
supportFragmentManager
47-
.beginTransaction()
48-
.add(R.id.containerTraktShowsFragment, fragment)
49-
.commit()
51+
.beginTransaction()
52+
.add(R.id.containerTraktShowsFragment, fragment)
53+
.commit()
5054
}
5155

5256
SimilarShowsFragment.displaySimilarShowsEventLiveData.observe(this) {
5357
startActivity(SimilarShowsActivity.intent(this, it.tmdbId, it.title))
5458
}
5559
}
5660

57-
fun setupActionBar(link: TraktShowsLink) {
61+
fun setupActionBar(link: DiscoverShowsLink) {
5862
setupActionBar()
5963
supportActionBar?.setDisplayHomeAsUpEnabled(true)
6064
setTitle(link.titleRes)
@@ -68,8 +72,8 @@ class TraktShowsActivity : BaseMessageActivity(), AddShowDialogFragment.OnAddSho
6872
const val EXTRA_LINK = "LINK"
6973

7074
@JvmStatic
71-
fun intent(context: Context, link: TraktShowsLink): Intent {
72-
return Intent(context, TraktShowsActivity::class.java).putExtra(EXTRA_LINK, link.id)
75+
fun intent(context: Context, link: DiscoverShowsLink): Intent {
76+
return Intent(context, DiscoverShowsActivity::class.java).putExtra(EXTRA_LINK, link.id)
7377
}
7478
}
7579

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright 2018-2024 Uwe Trottmann
3+
4+
package com.battlelancer.seriesguide.shows.search.discover;
5+
6+
import androidx.annotation.StringRes;
7+
import androidx.collection.SparseArrayCompat;
8+
import com.battlelancer.seriesguide.R;
9+
10+
public enum DiscoverShowsLink {
11+
POPULAR(0, R.string.title_popular),
12+
NEW_EPISODES(1, R.string.title_new_episodes),
13+
WATCHED(2, R.string.watched_shows),
14+
COLLECTION(3, R.string.shows_collection),
15+
WATCHLIST(4, R.string.watchlist);
16+
17+
final int id;
18+
final int titleRes;
19+
20+
DiscoverShowsLink(int id, @StringRes int titleRes) {
21+
this.id = id;
22+
this.titleRes = titleRes;
23+
}
24+
25+
private static final SparseArrayCompat<DiscoverShowsLink> MAPPING = new SparseArrayCompat<>();
26+
27+
static {
28+
for (DiscoverShowsLink link : values()) {
29+
MAPPING.put(link.id, link);
30+
}
31+
}
32+
33+
static DiscoverShowsLink fromId(int id) {
34+
DiscoverShowsLink discoverShowsLink = MAPPING.get(id);
35+
return discoverShowsLink == null ? POPULAR : discoverShowsLink;
36+
}
37+
}

app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/ShowsDiscoverAdapter.kt

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// Copyright 2023 Uwe Trottmann
21
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright 2018-2024 Uwe Trottmann
33

44
package com.battlelancer.seriesguide.shows.search.discover
55

@@ -12,8 +12,8 @@ import androidx.annotation.StringRes
1212
import androidx.recyclerview.widget.RecyclerView
1313
import com.battlelancer.seriesguide.R
1414
import com.battlelancer.seriesguide.databinding.ItemAddshowBinding
15-
import com.battlelancer.seriesguide.databinding.ItemGridHeaderBinding
16-
import com.battlelancer.seriesguide.databinding.ItemGridLinkBinding
15+
import com.battlelancer.seriesguide.databinding.ItemDiscoverShowsHeaderBinding
16+
import com.battlelancer.seriesguide.databinding.ItemDiscoverShowsLinkBinding
1717
import com.battlelancer.seriesguide.traktapi.TraktCredentials
1818
import com.battlelancer.seriesguide.util.ImageTools
1919
import com.battlelancer.seriesguide.util.ViewTools
@@ -29,15 +29,15 @@ class ShowsDiscoverAdapter(
2929
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
3030

3131
private val searchResults = mutableListOf<SearchResult>()
32-
private val links: MutableList<TraktShowsLink> = mutableListOf()
32+
private val links: MutableList<DiscoverShowsLink> = mutableListOf()
3333
private var showOnlyResults = false
3434

3535
init {
36-
links.add(TraktShowsLink.POPULAR)
36+
links.add(DiscoverShowsLink.POPULAR)
3737
if (TraktCredentials.get(context).hasCredentials()) {
38-
links.add(TraktShowsLink.WATCHED)
39-
links.add(TraktShowsLink.COLLECTION)
40-
links.add(TraktShowsLink.WATCHLIST)
38+
links.add(DiscoverShowsLink.WATCHED)
39+
links.add(DiscoverShowsLink.COLLECTION)
40+
links.add(DiscoverShowsLink.WATCHLIST)
4141
}
4242
}
4343

@@ -106,7 +106,7 @@ class ShowsDiscoverAdapter(
106106
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
107107
return when (viewType) {
108108
VIEW_TYPE_LINK -> LinkViewHolder.inflate(parent, itemClickListener)
109-
VIEW_TYPE_HEADER -> HeaderViewHolder.inflate(parent)
109+
VIEW_TYPE_HEADER -> HeaderViewHolder.inflate(parent, itemClickListener)
110110
VIEW_TYPE_SHOW -> ShowViewHolder.inflate(parent, itemClickListener)
111111
else -> throw IllegalArgumentException("View type $viewType is unknown")
112112
}
@@ -117,9 +117,11 @@ class ShowsDiscoverAdapter(
117117
is LinkViewHolder -> {
118118
holder.bindTo(context, links[position])
119119
}
120+
120121
is HeaderViewHolder -> {
121-
holder.bindTo(R.string.title_new_episodes)
122+
holder.bindTo(R.string.title_new_episodes, DiscoverShowsLink.NEW_EPISODES)
122123
}
124+
123125
is ShowViewHolder -> {
124126
val item = getSearchResultFor(position)
125127
holder.bindTo(context, item, showMenuWatchlist, hideMenuWatchlistIfAdded)
@@ -128,18 +130,18 @@ class ShowsDiscoverAdapter(
128130
}
129131

130132
interface OnItemClickListener {
131-
fun onLinkClick(anchor: View, link: TraktShowsLink)
133+
fun onLinkClick(anchor: View, link: DiscoverShowsLink)
132134
fun onItemClick(item: SearchResult)
133135
fun onAddClick(item: SearchResult)
134136
fun onMenuWatchlistClick(view: View, showTmdbId: Int)
135137
}
136138

137139
class LinkViewHolder(
138-
private val binding: ItemGridLinkBinding,
140+
private val binding: ItemDiscoverShowsLinkBinding,
139141
onItemClickListener: OnItemClickListener
140142
) : RecyclerView.ViewHolder(binding.root) {
141143

142-
private var link: TraktShowsLink? = null
144+
private var link: DiscoverShowsLink? = null
143145

144146
init {
145147
itemView.setOnClickListener {
@@ -149,11 +151,11 @@ class ShowsDiscoverAdapter(
149151
}
150152
}
151153

152-
fun bindTo(context: Context, link: TraktShowsLink) {
154+
fun bindTo(context: Context, link: DiscoverShowsLink) {
153155
this.link = link
154156
binding.textViewGridLink.text = context.getString(link.titleRes)
155157
// Add Trakt icon to highlight Trakt profile specific links.
156-
if (link != TraktShowsLink.POPULAR) {
158+
if (link != DiscoverShowsLink.POPULAR) {
157159
ViewTools.setVectorDrawableLeft(
158160
binding.textViewGridLink,
159161
R.drawable.ic_trakt_icon_primary_24dp
@@ -166,7 +168,7 @@ class ShowsDiscoverAdapter(
166168
companion object {
167169
fun inflate(parent: ViewGroup, onItemClickListener: OnItemClickListener) =
168170
LinkViewHolder(
169-
ItemGridLinkBinding.inflate(
171+
ItemDiscoverShowsLinkBinding.inflate(
170172
LayoutInflater.from(parent.context),
171173
parent,
172174
false
@@ -176,16 +178,36 @@ class ShowsDiscoverAdapter(
176178
}
177179
}
178180

179-
class HeaderViewHolder(private val binding: ItemGridHeaderBinding) :
180-
RecyclerView.ViewHolder(binding.root) {
181-
fun bindTo(@StringRes text: Int) {
181+
class HeaderViewHolder(
182+
private val binding: ItemDiscoverShowsHeaderBinding,
183+
onItemClickListener: OnItemClickListener
184+
) : RecyclerView.ViewHolder(binding.root) {
185+
186+
private var link: DiscoverShowsLink? = null
187+
188+
init {
189+
itemView.setOnClickListener {
190+
link?.let {
191+
onItemClickListener.onLinkClick(itemView, it)
192+
}
193+
}
194+
}
195+
196+
fun bindTo(@StringRes text: Int, link: DiscoverShowsLink) {
182197
binding.textViewGridHeader.setText(text)
198+
this.link = link
183199
}
184200

185201
companion object {
186-
fun inflate(parent: ViewGroup) = HeaderViewHolder(
187-
ItemGridHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false)
188-
)
202+
fun inflate(parent: ViewGroup, onItemClickListener: OnItemClickListener) =
203+
HeaderViewHolder(
204+
ItemDiscoverShowsHeaderBinding.inflate(
205+
LayoutInflater.from(parent.context),
206+
parent,
207+
false
208+
),
209+
onItemClickListener
210+
)
189211
}
190212
}
191213

@@ -208,7 +230,12 @@ class ShowsDiscoverAdapter(
208230
}
209231
}
210232

211-
fun bindTo(context: Context, item: SearchResult, showMenuWatchlist: Boolean, hideMenuWatchlistIfAdded: Boolean) {
233+
fun bindTo(
234+
context: Context,
235+
item: SearchResult,
236+
showMenuWatchlist: Boolean,
237+
hideMenuWatchlistIfAdded: Boolean
238+
) {
212239
this.item = item
213240

214241
// hide watchlist menu if not useful
@@ -230,7 +257,11 @@ class ShowsDiscoverAdapter(
230257
binding.textViewAddTitle.text = showTitle
231258
binding.textViewAddDescription.text = item.overview
232259

233-
ImageTools.loadShowPosterResizeCrop(context, binding.imageViewAddPoster, item.posterPath)
260+
ImageTools.loadShowPosterResizeCrop(
261+
context,
262+
binding.imageViewAddPoster,
263+
item.posterPath
264+
)
234265
}
235266

236267
companion object {
@@ -243,7 +274,7 @@ class ShowsDiscoverAdapter(
243274
}
244275

245276
companion object {
246-
val VIEW_TYPE_LINK = R.layout.item_grid_link
277+
val VIEW_TYPE_LINK = R.layout.item_discover_shows_link
247278
val VIEW_TYPE_HEADER = R.layout.item_grid_header
248279
val VIEW_TYPE_SHOW = R.layout.item_addshow
249280
}

app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/ShowsDiscoverFragment.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// Copyright 2023 Uwe Trottmann
21
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright 2018-2024 Uwe Trottmann
33

44
package com.battlelancer.seriesguide.shows.search.discover
55

@@ -138,10 +138,10 @@ class ShowsDiscoverFragment : BaseAddShowsFragment() {
138138
}
139139

140140
private val discoverItemClickListener = object : ShowsDiscoverAdapter.OnItemClickListener {
141-
override fun onLinkClick(anchor: View, link: TraktShowsLink) {
141+
override fun onLinkClick(anchor: View, link: DiscoverShowsLink) {
142142
Utils.startActivityWithAnimation(
143143
activity,
144-
TraktShowsActivity.intent(requireContext(), link),
144+
DiscoverShowsActivity.intent(requireContext(), link),
145145
anchor
146146
)
147147
}

app/src/main/java/com/battlelancer/seriesguide/shows/search/discover/ShowsDiscoverLiveData.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// Copyright 2023 Uwe Trottmann
21
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright 2018-2024 Uwe Trottmann
33

44
package com.battlelancer.seriesguide.shows.search.discover
55

@@ -94,8 +94,15 @@ class ShowsDiscoverLiveData(
9494
val tmdb = SgApp.getServicesComponent(context.applicationContext).tmdb()
9595
val languageActual = language
9696
val watchRegion = StreamingSearch.getCurrentRegionOrNull(context)
97-
val results =
98-
TmdbTools2().getShowsWithNewEpisodes(tmdb, language, watchProviderIds, watchRegion)
97+
val results = TmdbTools2().getShowsWithNewEpisodes(
98+
tmdb = tmdb,
99+
language = language,
100+
page = 1,
101+
firstReleaseYear = null,
102+
originalLanguage = null,
103+
watchProviderIds = watchProviderIds,
104+
watchRegion = watchRegion
105+
)?.results
99106
return@withContext if (results != null) {
100107
val searchResults = SearchTools.mapTvShowsToSearchResults(languageActual, results)
101108
SearchTools.markLocalShowsAsAddedAndPreferLocalPoster(context, searchResults)

0 commit comments

Comments
 (0)