Fix addons content sort

Don't specify a sort method in the listing of addon contents, so that the addon can sort its contents as it sees fit.
This commit is contained in:
Synced Synapse 2019-06-27 13:05:53 +01:00 committed by Martijn Brekhof
parent e7a17e87ae
commit a2e4362564
5 changed files with 73 additions and 45 deletions

View File

@ -60,12 +60,12 @@ public class Files {
* Enums for File.Media * Enums for File.Media
*/ */
public interface Media { public interface Media {
public final static String VIDEO = "video"; String VIDEO = "video";
public final static String MUSIC = "music"; String MUSIC = "music";
public final static String PICTURES = "pictures"; String PICTURES = "pictures";
public final static String FILES = "files"; String FILES = "files";
public final static String PROGRAMS = "programs"; String PROGRAMS = "programs";
public final static String[] allValues = new String[] { String[] allValues = new String[] {
VIDEO, MUSIC, PICTURES, FILES, PROGRAMS VIDEO, MUSIC, PICTURES, FILES, PROGRAMS
}; };
} }
@ -96,7 +96,7 @@ public class Files {
ArrayNode items = resultNode.has(SOURCE_NODE) ? ArrayNode items = resultNode.has(SOURCE_NODE) ?
(ArrayNode) resultNode.get(SOURCE_NODE) : null; (ArrayNode) resultNode.get(SOURCE_NODE) : null;
if (items == null) { if (items == null) {
return new ArrayList<ItemType.Source>(0); return new ArrayList<>(0);
} }
ArrayList<ItemType.Source> result = new ArrayList<ItemType.Source>(items.size()); ArrayList<ItemType.Source> result = new ArrayList<ItemType.Source>(items.size());
@ -115,17 +115,6 @@ public class Files {
public final static String SORT_NODE = "sort"; public final static String SORT_NODE = "sort";
public final static String FILE_NODE = "files"; public final static String FILE_NODE = "files";
/**
* Get the directories and files in the given directory
* @param directory full path name
* @param sort_params sorting criteria
*/
public GetDirectory(String directory, ListType.Sort sort_params) {
super();
addParameterToRequest("directory", directory);
addParameterToRequest(SORT_NODE, sort_params.toJsonNode());
}
/** /**
* Get the directories and files in the given directory * Get the directories and files in the given directory
* @param directory Full path name * @param directory Full path name
@ -141,7 +130,9 @@ public class Files {
addParameterToRequest("directory", directory); addParameterToRequest("directory", directory);
addParameterToRequest("media", media); addParameterToRequest("media", media);
addParameterToRequest("properties", properties); addParameterToRequest("properties", properties);
addParameterToRequest(SORT_NODE, sort_params.toJsonNode()); if (sort_params != null) {
addParameterToRequest(SORT_NODE, sort_params.toJsonNode());
}
} }
@Override @Override
@ -152,10 +143,10 @@ public class Files {
JsonNode fileNode = jsonObject.get(RESULT_NODE) JsonNode fileNode = jsonObject.get(RESULT_NODE)
.get(FILE_NODE); .get(FILE_NODE);
if (fileNode == null || fileNode.isNull()) { if (fileNode == null || fileNode.isNull()) {
return new ArrayList<ListType.ItemFile>(0); return new ArrayList<>(0);
} }
ArrayNode items = (ArrayNode) fileNode; ArrayNode items = (ArrayNode) fileNode;
ArrayList<ListType.ItemFile> result = new ArrayList<ListType.ItemFile>(items.size()); ArrayList<ListType.ItemFile> result = new ArrayList<>(items.size());
for (JsonNode item : items) { for (JsonNode item : items) {
String regex = "\\[.*?\\]"; String regex = "\\[.*?\\]";
JsonNode label = item.get("label"); JsonNode label = item.get("label");

View File

@ -15,6 +15,9 @@
*/ */
package org.xbmc.kore.jsonrpc.type; package org.xbmc.kore.jsonrpc.type;
import android.os.Parcel;
import android.os.Parcelable;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
@ -580,7 +583,7 @@ public class ListType {
/** /**
* List.Sort * List.Sort
*/ */
public static class Sort implements ApiParameter { public static class Sort implements ApiParameter, Parcelable {
public static final String SORT_METHOD_NONE = "none"; public static final String SORT_METHOD_NONE = "none";
public static final String SORT_METHOD_LABEL = "label"; public static final String SORT_METHOD_LABEL = "label";
public static final String SORT_METHOD_DATE = "date"; public static final String SORT_METHOD_DATE = "date";
@ -588,7 +591,7 @@ public class ListType {
public static final String SORT_METHOD_FILE = "file"; public static final String SORT_METHOD_FILE = "file";
public static final String SORT_METHOD_PATH = "path"; public static final String SORT_METHOD_PATH = "path";
public static final String SORT_METHOD_DRIVETYPE = "drivetype"; public static final String SORT_METHOD_DRIVETYPE = "drivetype";
public static final String SORT_METHOD_TYPE = "title"; public static final String SORT_METHOD_TITLE = "title";
public static final String SORT_METHOD_TRACK = "track"; public static final String SORT_METHOD_TRACK = "track";
public static final String SORT_METHOD_TIME = "time"; public static final String SORT_METHOD_TIME = "time";
public static final String SORT_METHOD_ARTIST = "artist"; public static final String SORT_METHOD_ARTIST = "artist";
@ -643,5 +646,31 @@ public class ListType {
node.put(METHOD, sort_method); node.put(METHOD, sort_method);
return node; return node;
} }
private Sort(Parcel in) {
this.sort_method = in.readString();
this.ascending_order = (in.readInt() != 0);
this.ignore_article = (in.readInt() != 0);
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeString(sort_method);
out.writeInt(ascending_order ? 1 : 0);
out.writeInt(ignore_article ? 1 : 0);
}
public static final Parcelable.Creator<Sort> CREATOR = new Parcelable.Creator<Sort>() {
public Sort createFromParcel(Parcel in) {
return new Sort(in);
}
public Sort[] newArray(int size) {
return new Sort[size];
}
};
} }
} }

View File

@ -22,6 +22,8 @@ import android.preference.PreferenceManager;
import org.xbmc.kore.R; import org.xbmc.kore.R;
import org.xbmc.kore.Settings; import org.xbmc.kore.Settings;
import org.xbmc.kore.host.HostManager; import org.xbmc.kore.host.HostManager;
import org.xbmc.kore.jsonrpc.method.Files;
import org.xbmc.kore.jsonrpc.type.ListType;
import org.xbmc.kore.ui.AbstractInfoFragment; import org.xbmc.kore.ui.AbstractInfoFragment;
import org.xbmc.kore.ui.AbstractTabsFragment; import org.xbmc.kore.ui.AbstractTabsFragment;
import org.xbmc.kore.ui.sections.file.MediaFileListFragment; import org.xbmc.kore.ui.sections.file.MediaFileListFragment;
@ -46,7 +48,7 @@ public class AddonListContainerFragment extends AbstractTabsFragment {
if (arguments == null) if (arguments == null)
arguments = new Bundle(); arguments = new Bundle();
/** /*
* Following check required to support testing AddonsActivity. * Following check required to support testing AddonsActivity.
* The database with host info is setup after initializing AddonsActivity using * The database with host info is setup after initializing AddonsActivity using
* ActivityTestRule from the test support library. This means getHostInfo() will * ActivityTestRule from the test support library. This means getHostInfo() will
@ -66,6 +68,7 @@ public class AddonListContainerFragment extends AbstractTabsFragment {
String name = prefs.getString(Settings.getNameBookmarkedAddonsPrefKey(hostId) + path, Settings.DEFAULT_PREF_NAME_BOOKMARKED_ADDON); String name = prefs.getString(Settings.getNameBookmarkedAddonsPrefKey(hostId) + path, Settings.DEFAULT_PREF_NAME_BOOKMARKED_ADDON);
arguments.putParcelable(MediaFileListFragment.ROOT_PATH, arguments.putParcelable(MediaFileListFragment.ROOT_PATH,
new MediaFileListFragment.FileLocation(name, "plugin://" + path, true)); new MediaFileListFragment.FileLocation(name, "plugin://" + path, true));
arguments.putString(MediaFileListFragment.MEDIA_TYPE, Files.Media.FILES);
tabsAdapter.addTab(MediaFileListFragment.class, arguments, name, ++baseFragmentId); tabsAdapter.addTab(MediaFileListFragment.class, arguments, name, ++baseFragmentId);
} }

View File

@ -20,6 +20,7 @@ import android.os.Bundle;
import org.xbmc.kore.R; import org.xbmc.kore.R;
import org.xbmc.kore.jsonrpc.method.Files; import org.xbmc.kore.jsonrpc.method.Files;
import org.xbmc.kore.jsonrpc.type.ListType;
import org.xbmc.kore.ui.AbstractTabsFragment; import org.xbmc.kore.ui.AbstractTabsFragment;
import org.xbmc.kore.ui.OnBackPressedListener; import org.xbmc.kore.ui.OnBackPressedListener;
import org.xbmc.kore.utils.TabsAdapter; import org.xbmc.kore.utils.TabsAdapter;
@ -32,12 +33,20 @@ public class FileListFragment extends AbstractTabsFragment
@Override @Override
protected TabsAdapter createTabsAdapter(DataHolder dataHolder) { protected TabsAdapter createTabsAdapter(DataHolder dataHolder) {
ListType.Sort sortMethod = new ListType.Sort(ListType.Sort.SORT_METHOD_PATH, true, true);
Bundle videoFileListArgs = new Bundle(); Bundle videoFileListArgs = new Bundle();
videoFileListArgs.putString(MediaFileListFragment.MEDIA_TYPE, Files.Media.VIDEO); videoFileListArgs.putString(MediaFileListFragment.MEDIA_TYPE, Files.Media.VIDEO);
videoFileListArgs.putParcelable(MediaFileListFragment.SORT_METHOD, sortMethod);
Bundle musicFileListArgs = new Bundle(); Bundle musicFileListArgs = new Bundle();
musicFileListArgs.putString(MediaFileListFragment.MEDIA_TYPE, Files.Media.MUSIC); musicFileListArgs.putString(MediaFileListFragment.MEDIA_TYPE, Files.Media.MUSIC);
musicFileListArgs.putParcelable(MediaFileListFragment.SORT_METHOD, sortMethod);
Bundle pictureFileListArgs = new Bundle(); Bundle pictureFileListArgs = new Bundle();
pictureFileListArgs.putString(MediaFileListFragment.MEDIA_TYPE, Files.Media.PICTURES); pictureFileListArgs.putString(MediaFileListFragment.MEDIA_TYPE, Files.Media.PICTURES);
pictureFileListArgs.putParcelable(MediaFileListFragment.SORT_METHOD, sortMethod);
return new TabsAdapter(getActivity(), getChildFragmentManager()) return new TabsAdapter(getActivity(), getChildFragmentManager())
.addTab(MediaFileListFragment.class, videoFileListArgs, R.string.video, 1) .addTab(MediaFileListFragment.class, videoFileListArgs, R.string.video, 1)
.addTab(MediaFileListFragment.class, musicFileListArgs, R.string.music, 2) .addTab(MediaFileListFragment.class, musicFileListArgs, R.string.music, 2)

View File

@ -61,6 +61,7 @@ public class MediaFileListFragment extends AbstractListFragment {
private static final String TAG = LogUtils.makeLogTag(MediaFileListFragment.class); private static final String TAG = LogUtils.makeLogTag(MediaFileListFragment.class);
public static final String MEDIA_TYPE = "mediaType"; public static final String MEDIA_TYPE = "mediaType";
public static final String SORT_METHOD = "sortMethod";
public static final String PATH_CONTENTS = "pathContents"; public static final String PATH_CONTENTS = "pathContents";
public static final String ROOT_PATH_CONTENTS = "rootPathContents"; public static final String ROOT_PATH_CONTENTS = "rootPathContents";
public static final String ROOT_VISITED = "rootVisited"; public static final String ROOT_VISITED = "rootVisited";
@ -74,32 +75,22 @@ public class MediaFileListFragment extends AbstractListFragment {
*/ */
private Handler callbackHandler = new Handler(); private Handler callbackHandler = new Handler();
String mediaType = Files.Media.MUSIC; String mediaType = Files.Media.FILES;
ListType.Sort sortMethod = null;
String parentDirectory = null; String parentDirectory = null;
int playlistId = PlaylistType.MUSIC_PLAYLISTID; // this is the ID of the music player int playlistId = PlaylistType.MUSIC_PLAYLISTID; // this is the ID of the music player
// private MediaFileListAdapter adapter = null; // private MediaFileListAdapter adapter = null;
boolean browseRootAlready = false; boolean browseRootAlready = false;
FileLocation loadOnVisible = null; FileLocation loadOnVisible = null;
ArrayList<FileLocation> rootFileLocation = new ArrayList<FileLocation>(); ArrayList<FileLocation> rootFileLocation = new ArrayList<>();
Queue<FileLocation> mediaQueueFileLocation = new LinkedList<>(); Queue<FileLocation> mediaQueueFileLocation = new LinkedList<>();
// @InjectView(R.id.list) GridView folderGridView;
// @InjectView(R.id.swipe_refresh_layout) SwipeRefreshLayout swipeRefreshLayout;
// @InjectView(android.R.id.empty) TextView emptyView;
public static MediaFileListFragment newInstance(final String media) {
MediaFileListFragment fragment = new MediaFileListFragment();
Bundle args = new Bundle();
args.putString(MEDIA_TYPE, media);
fragment.setArguments(args);
return fragment;
}
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putString(MEDIA_TYPE, mediaType); outState.putString(MEDIA_TYPE, mediaType);
outState.putParcelable(SORT_METHOD, sortMethod);
try { try {
outState.putParcelableArrayList(PATH_CONTENTS, (ArrayList<FileLocation>) ((MediaFileListAdapter) getAdapter()).getFileItemList()); outState.putParcelableArrayList(PATH_CONTENTS, (ArrayList<FileLocation>) ((MediaFileListAdapter) getAdapter()).getFileItemList());
} catch (NullPointerException npe) { } catch (NullPointerException npe) {
@ -138,6 +129,7 @@ public class MediaFileListFragment extends AbstractListFragment {
} else if (mediaType.equalsIgnoreCase(Files.Media.PICTURES)) { } else if (mediaType.equalsIgnoreCase(Files.Media.PICTURES)) {
playlistId = PlaylistType.PICTURE_PLAYLISTID; playlistId = PlaylistType.PICTURE_PLAYLISTID;
} }
sortMethod = args.getParcelable(SORT_METHOD);
} }
hostManager = HostManager.getInstance(getActivity()); hostManager = HostManager.getInstance(getActivity());
@ -151,13 +143,14 @@ public class MediaFileListFragment extends AbstractListFragment {
}); });
if (savedInstanceState != null) { if (savedInstanceState != null) {
mediaType = savedInstanceState.getString(MEDIA_TYPE); mediaType = savedInstanceState.getString(MEDIA_TYPE, Files.Media.FILES);
//currentPath = savedInstanceState.getString(CURRENT_PATH); //currentPath = savedInstanceState.getString(CURRENT_PATH);
if (mediaType.equalsIgnoreCase(Files.Media.VIDEO)) { if (mediaType.equalsIgnoreCase(Files.Media.VIDEO)) {
playlistId = PlaylistType.VIDEO_PLAYLISTID; playlistId = PlaylistType.VIDEO_PLAYLISTID;
} else if (mediaType.equalsIgnoreCase(Files.Media.PICTURES)) { } else if (mediaType.equalsIgnoreCase(Files.Media.PICTURES)) {
playlistId = PlaylistType.PICTURE_PLAYLISTID; playlistId = PlaylistType.PICTURE_PLAYLISTID;
} }
sortMethod = savedInstanceState.getParcelable(SORT_METHOD);
ArrayList<FileLocation> list = savedInstanceState.getParcelableArrayList(PATH_CONTENTS); ArrayList<FileLocation> list = savedInstanceState.getParcelableArrayList(PATH_CONTENTS);
rootFileLocation = savedInstanceState.getParcelableArrayList(ROOT_PATH_CONTENTS); rootFileLocation = savedInstanceState.getParcelableArrayList(ROOT_PATH_CONTENTS);
browseRootAlready = savedInstanceState.getBoolean(ROOT_VISITED); browseRootAlready = savedInstanceState.getBoolean(ROOT_VISITED);
@ -217,7 +210,8 @@ public class MediaFileListFragment extends AbstractListFragment {
return true; return true;
else else
// if we still see "..", it is not the real root directory // if we still see "..", it is not the real root directory
return fl.isRootDir() && (fl.title.contentEquals("..") == false); return fl.isRootDir() &&
(fl.title != null) && !fl.title.contentEquals("..");
} }
/** /**
@ -234,7 +228,8 @@ public class MediaFileListFragment extends AbstractListFragment {
rootFileLocation.clear(); rootFileLocation.clear();
FileLocation fl; FileLocation fl;
for (ItemType.Source item : result) { for (ItemType.Source item : result) {
if (!item.file.contains(ADDON_SOURCE)) { if ((item.file != null) &&
(!item.file.contains(ADDON_SOURCE))) {
fl = new FileLocation(item.label, item.file, true); fl = new FileLocation(item.label, item.file, true);
fl.setRootDir(true); fl.setRootDir(true);
rootFileLocation.add(fl); rootFileLocation.add(fl);
@ -271,7 +266,8 @@ public class MediaFileListFragment extends AbstractListFragment {
String path; String path;
for (FileLocation fl : rootFileLocation) { for (FileLocation fl : rootFileLocation) {
path = fl.file; path = fl.file;
if (dir.file.contentEquals(path)) { if ((path != null) && (dir.file != null) &&
(dir.file.contentEquals(path))) {
rootPath = fl.file; rootPath = fl.file;
break; break;
} }
@ -279,7 +275,7 @@ public class MediaFileListFragment extends AbstractListFragment {
if (rootPath != null) { if (rootPath != null) {
parentDirectory = rootPath; parentDirectory = rootPath;
dir.setRootDir(true); dir.setRootDir(true);
} else { } else if (dir.file != null) {
parentDirectory = getParentDirectory(dir.file); parentDirectory = getParentDirectory(dir.file);
} }
} }
@ -322,14 +318,14 @@ public class MediaFileListFragment extends AbstractListFragment {
Files.GetDirectory action = new Files.GetDirectory(dir.file, Files.GetDirectory action = new Files.GetDirectory(dir.file,
mediaType, mediaType,
new ListType.Sort(ListType.Sort.SORT_METHOD_PATH, true, true), sortMethod,
properties); properties);
action.execute(hostManager.getConnection(), new ApiCallback<List<ListType.ItemFile>>() { action.execute(hostManager.getConnection(), new ApiCallback<List<ListType.ItemFile>>() {
@Override @Override
public void onSuccess(List<ListType.ItemFile> result) { public void onSuccess(List<ListType.ItemFile> result) {
if (!isAdded()) return; if (!isAdded()) return;
ArrayList<FileLocation> flList = new ArrayList<FileLocation>(); ArrayList<FileLocation> flList = new ArrayList<>();
if (dir.hasParent) { if (dir.hasParent) {
// insert the parent directory as the first item in the list // insert the parent directory as the first item in the list