Merge ByLetterActivity and ByGenreActivity into a single activity (#1222)

* Merge ByLetterActivity, BrowsePersonsActivity and ByGenreActivity into a single activity

* Remove unused code from BrowseFolderFragment

* Remove unused BrowsePersonsFragment

* Merge CustomViewFragment into BrowseFolderFragment

* Fix wrong constant used

* Remove unused code from StdBrowseFragment (activity is never BaseActivity)
This commit is contained in:
Niels van Velzen
2021-12-13 16:08:18 +01:00
committed by GitHub
parent e059a51032
commit 61a96d7eea
13 changed files with 59 additions and 313 deletions
+1 -9
View File
@@ -137,11 +137,7 @@
android:screenOrientation="landscape" />
<activity
android:name=".ui.browsing.ByLetterActivity"
android:screenOrientation="landscape" />
<activity
android:name=".ui.browsing.ByGenreActivity"
android:name=".ui.browsing.GroupedItemsActivity"
android:screenOrientation="landscape" />
<activity
@@ -152,10 +148,6 @@
android:name=".ui.browsing.SuggestedMoviesActivity"
android:screenOrientation="landscape" />
<activity
android:name=".ui.browsing.BrowsePersonsActivity"
android:screenOrientation="landscape" />
<activity
android:name=".ui.search.SearchActivity"
android:screenOrientation="landscape" />
@@ -1,6 +1,6 @@
package org.jellyfin.androidtv.constant
object Extras {
const val Folder = "Folder"
const val IncludeType = "IncludeType"
const val Folder = "folder"
const val IncludeType = "type_include"
}
@@ -2,124 +2,27 @@ package org.jellyfin.androidtv.ui.browsing;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import androidx.leanback.widget.ArrayObjectAdapter;
import androidx.leanback.widget.HeaderItem;
import androidx.leanback.widget.ListRow;
import androidx.leanback.widget.OnItemViewClickedListener;
import androidx.leanback.widget.Presenter;
import androidx.leanback.widget.Row;
import androidx.leanback.widget.RowPresenter;
import org.jellyfin.androidtv.R;
import org.jellyfin.androidtv.TvApp;
import org.jellyfin.androidtv.constant.Extras;
import org.jellyfin.androidtv.ui.GridButton;
import org.jellyfin.androidtv.ui.presentation.GridButtonPresenter;
import org.jellyfin.sdk.model.api.BaseItemDto;
import kotlinx.serialization.json.Json;
import timber.log.Timber;
public class BrowseFolderFragment extends StdBrowseFragment {
protected static final int BY_LETTER = 0;
protected static final int GENRES = 1;
protected static final int YEARS = 2;
protected static final int PERSONS = 3;
protected static final int SUGGESTED = 4;
protected String includeType;
protected BaseItemDto mFolder;
protected String itemTypeString;
protected boolean showViews = true;
@Override
public void onCreate(Bundle savedInstanceState) {
mFolder = Json.Default.decodeFromString(BaseItemDto.Companion.serializer(), getActivity().getIntent().getStringExtra(Extras.Folder));
if (MainTitle == null) MainTitle = mFolder.getName();
Intent intent = requireActivity().getIntent();
mFolder = Json.Default.decodeFromString(BaseItemDto.Companion.serializer(), intent.getStringExtra(GroupedItemsActivity.EXTRA_FOLDER));
includeType = intent.getStringExtra(GroupedItemsActivity.EXTRA_INCLUDE_TYPE);
MainTitle = mFolder.getName();
ShowBadge = false;
if (mFolder.getCollectionType() != null) {
switch (mFolder.getCollectionType()) {
case "movies":
itemTypeString = "Movie";
break;
case "tvshows":
itemTypeString = "Series";
break;
case "folders":
showViews = false;
break;
default:
showViews = false;
}
} else {
showViews = false;
}
Timber.d("Item type: %s", includeType);
super.onCreate(savedInstanceState);
}
@Override
protected void addAdditionalRows(ArrayObjectAdapter rowAdapter) {
super.addAdditionalRows(rowAdapter);
if (showViews) {
HeaderItem gridHeader = new HeaderItem(rowAdapter.size(), TvApp.getApplication().getString(R.string.lbl_views));
GridButtonPresenter mGridPresenter = new GridButtonPresenter();
ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(mGridPresenter);
gridRowAdapter.add(new GridButton(BY_LETTER, TvApp.getApplication().getString(R.string.lbl_by_letter), R.drawable.tile_letters, null));
if (itemTypeString != null && itemTypeString.equals("Movie"))
gridRowAdapter.add(new GridButton(SUGGESTED, TvApp.getApplication().getString(R.string.lbl_suggested), R.drawable.tile_suggestions, null));
gridRowAdapter.add(new GridButton(GENRES, TvApp.getApplication().getString(R.string.lbl_genres), R.drawable.tile_genres, null));
gridRowAdapter.add(new GridButton(PERSONS, TvApp.getApplication().getString(R.string.lbl_performers), R.drawable.tile_actors, null));
rowAdapter.add(new ListRow(gridHeader, gridRowAdapter));
}
}
@Override
protected void setupEventListeners() {
super.setupEventListeners();
if (showViews) mClickedListener.registerListener(new ItemViewClickedListener());
}
private final class ItemViewClickedListener implements OnItemViewClickedListener {
@Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
RowPresenter.ViewHolder rowViewHolder, Row row) {
if (item instanceof GridButton) {
switch (((GridButton) item).getId()) {
case BY_LETTER:
Intent intent = new Intent(getActivity(), ByLetterActivity.class);
intent.putExtra(Extras.Folder, Json.Default.encodeToString(BaseItemDto.Companion.serializer(), mFolder));
intent.putExtra(Extras.IncludeType, itemTypeString);
getActivity().startActivity(intent);
break;
case GENRES:
Intent genreIntent = new Intent(getActivity(), ByGenreActivity.class);
genreIntent.putExtra(Extras.Folder, Json.Default.encodeToString(BaseItemDto.Companion.serializer(), mFolder));
genreIntent.putExtra(Extras.IncludeType, itemTypeString);
getActivity().startActivity(genreIntent);
break;
case SUGGESTED:
Intent suggIntent = new Intent(getActivity(), SuggestedMoviesActivity.class);
suggIntent.putExtra(Extras.Folder, Json.Default.encodeToString(BaseItemDto.Companion.serializer(), mFolder));
suggIntent.putExtra(Extras.IncludeType, itemTypeString);
getActivity().startActivity(suggIntent);
break;
case PERSONS:
Intent personIntent = new Intent(getActivity(), BrowsePersonsActivity.class);
personIntent.putExtra(Extras.Folder, Json.Default.encodeToString(BaseItemDto.Companion.serializer(), mFolder));
personIntent.putExtra(Extras.IncludeType, itemTypeString);
getActivity().startActivity(personIntent);
break;
default:
Toast.makeText(getActivity(), item.toString() + TvApp.getApplication().getString(R.string.msg_not_implemented), Toast.LENGTH_SHORT).show();
break;
}
}
}
}
}
@@ -1,15 +0,0 @@
package org.jellyfin.androidtv.ui.browsing
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
class BrowsePersonsActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager
.beginTransaction()
.replace(android.R.id.content, BrowsePersonsFragment())
.commit()
}
}
@@ -1,48 +0,0 @@
package org.jellyfin.androidtv.ui.browsing;
import org.jellyfin.androidtv.R;
import org.jellyfin.androidtv.TvApp;
import org.jellyfin.androidtv.util.Utils;
import org.jellyfin.apiclient.model.querying.ItemSortBy;
import org.jellyfin.apiclient.model.querying.PersonsQuery;
public class BrowsePersonsFragment extends CustomViewFragment {
private static String letters = TvApp.getApplication().getResources().getString(R.string.byletter_letters);
@Override
protected void setupQueries(IRowLoader rowLoader) {
if (Utils.getSafeValue(mFolder.getChildCount(), 0) > 0) {
//First add a '#' item
PersonsQuery numbers = new PersonsQuery();
numbers.setParentId(mFolder.getId().toString());
numbers.setSortBy(new String[]{ItemSortBy.SortName});
if (includeType != null) numbers.setIncludeItemTypes(new String[]{includeType});
numbers.setNameLessThan("A");
numbers.setRecursive(true);
mRows.add(new BrowseRowDef("#", numbers, 25));
//Then all the defined letters
for (Character letter : letters.toCharArray()) {
PersonsQuery letterQuery = new PersonsQuery();
letterQuery.setParentId(mFolder.getId().toString());
letterQuery.setSortBy(new String[]{ItemSortBy.SortName});
if (includeType != null) letterQuery.setIncludeItemTypes(new String[]{includeType});
letterQuery.setNameStartsWith(letter.toString());
letterQuery.setRecursive(true);
mRows.add(new BrowseRowDef(letter.toString(), letterQuery, 25));
}
if (mRows.size() < 2) setHeadersState(HEADERS_DISABLED);
rowLoader.loadRows(mRows);
}
else {
setHeadersState(HEADERS_DISABLED);
}
}
}
@@ -1,15 +0,0 @@
package org.jellyfin.androidtv.ui.browsing
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
class ByGenreActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager
.beginTransaction()
.replace(android.R.id.content, ByGenreFragment())
.commit()
}
}
@@ -1,7 +1,5 @@
package org.jellyfin.androidtv.ui.browsing;
import android.os.Bundle;
import org.jellyfin.androidtv.TvApp;
import org.jellyfin.androidtv.data.querying.StdItemQuery;
import org.jellyfin.androidtv.util.Utils;
@@ -13,12 +11,7 @@ import org.jellyfin.apiclient.model.querying.ItemsByNameQuery;
import org.jellyfin.apiclient.model.querying.ItemsResult;
import org.koin.java.KoinJavaComponent;
public class ByGenreFragment extends CustomViewFragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
public class ByGenreFragment extends BrowseFolderFragment {
@Override
protected void setupQueries(final IRowLoader rowLoader) {
if (Utils.getSafeValue(mFolder.getChildCount(), 0) > 0) {
@@ -1,15 +0,0 @@
package org.jellyfin.androidtv.ui.browsing
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
class ByLetterActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager
.beginTransaction()
.replace(android.R.id.content, ByLetterFragment())
.commit()
}
}
@@ -6,20 +6,18 @@ import org.jellyfin.androidtv.data.querying.StdItemQuery;
import org.jellyfin.androidtv.util.Utils;
import org.jellyfin.apiclient.model.querying.ItemSortBy;
public class ByLetterFragment extends CustomViewFragment {
public class ByLetterFragment extends BrowseFolderFragment {
private static String letters = TvApp.getApplication().getResources().getString(R.string.byletter_letters);
@Override
protected void setupQueries(IRowLoader rowLoader) {
if (Utils.getSafeValue(mFolder.getChildCount(), 0) > 0) {
//First add a '#' item
StdItemQuery numbers = new StdItemQuery();
numbers.setParentId(mFolder.getId().toString());
numbers.setSortBy(new String[]{ItemSortBy.SortName});
if (includeType != null) numbers.setIncludeItemTypes(new String[]{includeType});
numbers.setNameLessThan(letters.substring(0,1));
numbers.setNameLessThan(letters.substring(0, 1));
numbers.setRecursive(true);
mRows.add(new BrowseRowDef("#", numbers, 40));
@@ -37,12 +35,8 @@ public class ByLetterFragment extends CustomViewFragment {
if (mRows.size() < 2) setHeadersState(HEADERS_DISABLED);
rowLoader.loadRows(mRows);
}
else {
} else {
setHeadersState(HEADERS_DISABLED);
}
}
}
@@ -1,20 +0,0 @@
package org.jellyfin.androidtv.ui.browsing;
import android.os.Bundle;
import org.jellyfin.androidtv.constant.Extras;
import timber.log.Timber;
public class CustomViewFragment extends BrowseFolderFragment {
protected String includeType;
@Override
public void onCreate(Bundle savedInstanceState) {
includeType = getActivity().getIntent().getStringExtra(Extras.IncludeType);
Timber.d("Item type: %s", includeType);
showViews = false;
super.onCreate(savedInstanceState);
}
}
@@ -71,7 +71,6 @@ public class EnhancedBrowseFragment extends Fragment implements IRowLoader {
protected static final int BY_LETTER = 0;
protected static final int GENRES = 1;
protected static final int PERSONS = 3;
protected static final int SUGGESTED = 4;
protected static final int GRID = 6;
protected static final int ALBUMS = 7;
@@ -388,23 +387,25 @@ public class EnhancedBrowseFragment extends Fragment implements IRowLoader {
mFolder.setDisplayPreferencesId(mFolder.getId() + "AR");
Intent artistsIntent = new Intent(getActivity(), GenericGridActivity.class);
artistsIntent.putExtra(Extras.Folder, serializer.getValue().SerializeToString(mFolder));
artistsIntent.putExtra(Extras.IncludeType, "AlbumArtist");
artistsIntent.putExtra(GroupedItemsActivity.EXTRA_FOLDER, serializer.getValue().SerializeToString(mFolder));
artistsIntent.putExtra(GroupedItemsActivity.EXTRA_INCLUDE_TYPE, "AlbumArtist");
requireActivity().startActivity(artistsIntent);
break;
case BY_LETTER:
Intent intent = new Intent(getActivity(), ByLetterActivity.class);
intent.putExtra(Extras.Folder, serializer.getValue().SerializeToString(mFolder));
intent.putExtra(Extras.IncludeType, itemTypeString);
Intent letterIntent = new Intent(getActivity(), GroupedItemsActivity.class);
letterIntent.putExtra(GroupedItemsActivity.EXTRA_GROUPING_TYPE, GroupedItemsActivity.GroupingType.LETTER.toString());
letterIntent.putExtra(GroupedItemsActivity.EXTRA_FOLDER, serializer.getValue().SerializeToString(mFolder));
letterIntent.putExtra(GroupedItemsActivity.EXTRA_INCLUDE_TYPE, itemTypeString);
requireActivity().startActivity(intent);
requireActivity().startActivity(letterIntent);
break;
case GENRES:
Intent genreIntent = new Intent(getActivity(), ByGenreActivity.class);
genreIntent.putExtra(Extras.Folder, serializer.getValue().SerializeToString(mFolder));
genreIntent.putExtra(Extras.IncludeType, itemTypeString);
Intent genreIntent = new Intent(getActivity(), GroupedItemsActivity.class);
genreIntent.putExtra(GroupedItemsActivity.EXTRA_GROUPING_TYPE, GroupedItemsActivity.GroupingType.GENRE.toString());
genreIntent.putExtra(GroupedItemsActivity.EXTRA_FOLDER, serializer.getValue().SerializeToString(mFolder));
genreIntent.putExtra(GroupedItemsActivity.EXTRA_INCLUDE_TYPE, itemTypeString);
requireActivity().startActivity(genreIntent);
break;
@@ -417,14 +418,6 @@ public class EnhancedBrowseFragment extends Fragment implements IRowLoader {
requireActivity().startActivity(suggIntent);
break;
case PERSONS:
Intent personIntent = new Intent(getActivity(), BrowsePersonsActivity.class);
personIntent.putExtra(Extras.Folder, serializer.getValue().SerializeToString(mFolder));
personIntent.putExtra(Extras.IncludeType, itemTypeString);
requireActivity().startActivity(personIntent);
break;
case FAVSONGS:
Intent favIntent = new Intent(getActivity(), ItemListActivity.class);
favIntent.putExtra("ItemId", ItemListActivity.FAV_SONGS);
@@ -0,0 +1,32 @@
package org.jellyfin.androidtv.ui.browsing
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.commit
import androidx.fragment.app.replace
class GroupedItemsActivity : FragmentActivity() {
private val groupingType get() = intent.extras?.getString(EXTRA_GROUPING_TYPE)?.let { GroupingType.valueOf(it) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager.commit {
when (groupingType) {
GroupingType.GENRE -> replace<ByGenreFragment>(android.R.id.content)
GroupingType.LETTER -> replace<ByLetterFragment>(android.R.id.content)
}
}
}
enum class GroupingType {
GENRE,
LETTER,
}
companion object {
const val EXTRA_GROUPING_TYPE = "type_grouping"
const val EXTRA_FOLDER = "folder"
const val EXTRA_INCLUDE_TYPE = "type_include"
}
}
@@ -3,9 +3,7 @@ package org.jellyfin.androidtv.ui.browsing;
import static org.koin.java.KoinJavaComponent.inject;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -25,7 +23,6 @@ import androidx.leanback.widget.Row;
import androidx.leanback.widget.RowPresenter;
import org.jellyfin.androidtv.R;
import org.jellyfin.androidtv.constant.CustomMessage;
import org.jellyfin.androidtv.constant.QueryType;
import org.jellyfin.androidtv.data.model.DataRefreshService;
import org.jellyfin.androidtv.data.querying.ViewQuery;
@@ -38,10 +35,6 @@ import org.jellyfin.androidtv.ui.itemhandling.ItemLauncher;
import org.jellyfin.androidtv.ui.itemhandling.ItemRowAdapter;
import org.jellyfin.androidtv.ui.presentation.CardPresenter;
import org.jellyfin.androidtv.ui.presentation.PositionableListRowPresenter;
import org.jellyfin.androidtv.ui.shared.BaseActivity;
import org.jellyfin.androidtv.ui.shared.IKeyListener;
import org.jellyfin.androidtv.ui.shared.IMessageListener;
import org.jellyfin.androidtv.util.KeyProcessor;
import org.jellyfin.androidtv.util.Utils;
import org.jellyfin.apiclient.interaction.EmptyResponse;
import org.jellyfin.apiclient.model.dto.BaseItemType;
@@ -56,7 +49,6 @@ import timber.log.Timber;
public class StdBrowseFragment extends BrowseSupportFragment implements IRowLoader {
protected String MainTitle;
protected boolean ShowBadge = true;
protected BaseActivity mActivity;
protected BaseRowItem mCurrentItem;
protected ListRow mCurrentRow;
protected CompositeClickedListener mClickedListener = new CompositeClickedListener();
@@ -74,8 +66,6 @@ public class StdBrowseFragment extends BrowseSupportFragment implements IRowLoad
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getActivity() instanceof BaseActivity) mActivity = (BaseActivity)getActivity();
backgroundService.getValue().attach(requireActivity());
setupUIElements();
@@ -111,7 +101,6 @@ public class StdBrowseFragment extends BrowseSupportFragment implements IRowLoad
//Re-retrieve anything that needs it but delay slightly so we don't take away gui landing
if (mRowsAdapter != null) {
refreshCurrentItem();
refreshRows();
}
} else {
@@ -119,22 +108,6 @@ public class StdBrowseFragment extends BrowseSupportFragment implements IRowLoad
}
}
protected void refreshRows() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (mActivity == null || mActivity.isFinishing()) return;
for (int i = 0; i < mRowsAdapter.size(); i++) {
if (mRowsAdapter.get(i) instanceof ListRow) {
if (((ListRow) mRowsAdapter.get(i)).getAdapter() instanceof ItemRowAdapter) {
((ItemRowAdapter) ((ListRow) mRowsAdapter.get(i)).getAdapter()).ReRetrieveIfNeeded();
}
}
}
}
},1500);
}
public void loadRows(List<BrowseRowDef> rows) {
mRowsAdapter = new ArrayObjectAdapter(new PositionableListRowPresenter());
mCardPresenter = new CardPresenter();
@@ -246,27 +219,6 @@ public class StdBrowseFragment extends BrowseSupportFragment implements IRowLoad
setOnItemViewSelectedListener(mSelectedListener);
mSelectedListener.registerListener(new ItemViewSelectedListener());
if (mActivity != null) {
mActivity.registerKeyListener(new IKeyListener() {
@Override
public boolean onKeyUp(int key, KeyEvent event) {
return KeyProcessor.HandleKey(key, mCurrentItem, mActivity);
}
});
mActivity.registerMessageListener(new IMessageListener() {
@Override
public void onMessageReceived(CustomMessage message) {
switch (message) {
case RefreshCurrentItem:
refreshCurrentItem();
break;
}
}
});
}
}
private void refreshCurrentItem() {