summaryrefslogtreecommitdiff
path: root/org.fox.ttrss
diff options
context:
space:
mode:
Diffstat (limited to 'org.fox.ttrss')
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/Application.java33
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java113
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsModel.java172
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesFragment.java71
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesModel.java159
-rwxr-xr-xorg.fox.ttrss/src/main/res/xml/preferences.xml5
6 files changed, 322 insertions, 231 deletions
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/Application.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/Application.java
index 17ae7ccf..56546a33 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/Application.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/Application.java
@@ -65,7 +65,7 @@ public class Application extends android.app.Application {
public void setApiLevel(int apiLevel) {
m_apiLevel = apiLevel;
}
-
+
public void save(Bundle out) {
out.setClassLoader(getClass().getClassLoader());
@@ -100,20 +100,21 @@ public class Application extends android.app.Application {
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
- ACRA.init(this, new CoreConfigurationBuilder()
- .withBuildConfigClass(BuildConfig.class)
- .withReportFormat(StringFormat.JSON)
- .withPluginConfigurations(
- new DialogConfigurationBuilder()
- .withText(getString(R.string.crash_dialog_text_email))
- .withResTheme(R.style.Theme_AppCompat_Dialog)
- .build(),
- new MailSenderConfigurationBuilder()
- .withMailTo("cthulhoo+ttrss-acra@gmail.com")
- .withReportAsFile(true)
- .withReportFileName("crash.txt")
- .build()
- )
- .build());
+ if (!BuildConfig.DEBUG)
+ ACRA.init(this, new CoreConfigurationBuilder()
+ .withBuildConfigClass(BuildConfig.class)
+ .withReportFormat(StringFormat.JSON)
+ .withPluginConfigurations(
+ new DialogConfigurationBuilder()
+ .withText(getString(R.string.crash_dialog_text_email))
+ .withResTheme(R.style.Theme_AppCompat_Dialog)
+ .build(),
+ new MailSenderConfigurationBuilder()
+ .withMailTo("cthulhoo+ttrss-acra@gmail.com")
+ .withReportAsFile(true)
+ .withReportFileName("crash.txt")
+ .build()
+ )
+ .build());
}
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java
index d86969cc..8dcda413 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java
@@ -68,77 +68,6 @@ public class FeedsFragment extends Fragment implements OnSharedPreferenceChangeL
m_enableParentBtn = enableParentBtn;
}
- @SuppressLint("DefaultLocale")
- static class FeedUnreadComparator implements Comparator<Feed> {
-
- @Override
- public int compare(Feed a, Feed b) {
- if (a.unread != b.unread)
- return b.unread - a.unread;
- else
- return a.title.toUpperCase().compareTo(b.title.toUpperCase());
- }
-
- }
-
- @SuppressLint("DefaultLocale")
- static class FeedTitleComparator implements Comparator<Feed> {
-
- @Override
- public int compare(Feed a, Feed b) {
- if (a.is_cat && b.is_cat)
- return a.title.toUpperCase().compareTo(b.title.toUpperCase());
- else if (a.is_cat && !b.is_cat)
- return -1;
- else if (!a.is_cat && b.is_cat)
- return 1;
- else if (a.id >= 0 && b.id >= 0)
- return a.title.toUpperCase().compareTo(b.title.toUpperCase());
- else
- return a.id - b.id;
- }
-
- }
-
- @SuppressLint("DefaultLocale")
- static class SpecialOrderComparator implements Comparator<Feed> {
- static List<Integer> order = Arrays.asList(Feed.ALL_ARTICLES, Feed.FRESH, Feed.MARKED,
- Feed.PUBLISHED, Feed.ARCHIVED, Feed.RECENTLY_READ);
-
- @Override
- public int compare(Feed a, Feed b) {
- return Integer.valueOf(order.indexOf(a.id)).compareTo(order.indexOf(b.id));
- }
- }
-
- @SuppressLint("DefaultLocale")
- static class FeedOrderComparator implements Comparator<Feed> {
-
- @Override
- public int compare(Feed a, Feed b) {
- if (a.id >= 0 && b.id >= 0)
- if (a.is_cat && b.is_cat)
- if (a.order_id != 0 && b.order_id != 0)
- return a.order_id - b.order_id;
- else
- return a.title.toUpperCase().compareTo(b.title.toUpperCase());
- else if (a.is_cat)
- return -1;
- else if (b.is_cat)
- return 1;
- else if (a.order_id != 0 && b.order_id != 0)
- return a.order_id - b.order_id;
- else
- return a.title.toUpperCase().compareTo(b.title.toUpperCase());
- else
- if (a.id < CommonActivity.LABEL_BASE_INDEX && b.id < CommonActivity.LABEL_BASE_INDEX)
- return a.title.toUpperCase().compareTo(b.title.toUpperCase());
- else
- return a.id - b.id;
- }
-
- }
-
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
@@ -284,7 +213,7 @@ public class FeedsFragment extends Fragment implements OnSharedPreferenceChangeL
});
}
- FeedsModel model = new ViewModelProvider(this).get(FeedsModel.class);
+ FeedsModel model = getModel();
model.getUpdatesData().observe(m_activity, lastUpdate -> {
Log.d(TAG, "observed update=" + lastUpdate);
@@ -334,16 +263,13 @@ public class FeedsFragment extends Fragment implements OnSharedPreferenceChangeL
return view;
}
+ protected FeedsModel getModel() {
+ return new ViewModelProvider(this).get(FeedsModel.class);
+ }
+
protected void onFeedsLoaded(List<Feed> loadedFeeds) {
List<Feed> feedsWork = new ArrayList<>();
- if (m_activity.getUnreadOnly() && m_rootFeed.id != Feed.CAT_SPECIAL)
- loadedFeeds = loadedFeeds.stream()
- .filter(f -> f.unread > 0)
- .collect(Collectors.toList());
-
- sortFeeds(loadedFeeds, m_rootFeed);
-
if (m_enableParentBtn) {
feedsWork.add(0, new Feed(Feed.TYPE_GOBACK));
@@ -403,8 +329,7 @@ public class FeedsFragment extends Fragment implements OnSharedPreferenceChangeL
if (!isAdded())
return;
- FeedsModel model = new ViewModelProvider(this).get(FeedsModel.class);
- model.startLoading(m_rootFeed, false);
+ getModel().startLoading(m_rootFeed);
}
private class FeedViewHolder extends RecyclerView.ViewHolder {
@@ -582,35 +507,11 @@ public class FeedsFragment extends Fragment implements OnSharedPreferenceChangeL
return feed.id == Feed.CAT_SPECIAL || feed.id == Feed.CAT_LABELS;
}
- protected void sortFeeds(List<Feed> feeds, Feed feed) {
- Comparator<Feed> cmp;
-
- if (feed.id == -1) {
- cmp = new SpecialOrderComparator();
- } else {
- if (m_prefs.getBoolean("sort_feeds_by_unread", false)) {
- cmp = new FeedUnreadComparator();
- } else {
- if (m_activity.getApiLevel() >= 3) {
- cmp = new FeedOrderComparator();
- } else {
- cmp = new FeedTitleComparator();
- }
- }
- }
-
- try {
- feeds.sort(cmp);
- } catch (IllegalArgumentException e) {
- //
- }
- }
-
protected int getIconForFeed(Feed feed) {
if (feed.id == Feed.TYPE_GOBACK) {
return R.drawable.baseline_arrow_back_24;
} else if (feed.id == Feed.CAT_LABELS && feed.is_cat) {
- return R.drawable.outline_label_24;
+ return R.drawable.baseline_label_24;
} else if (feed.id == Feed.CAT_SPECIAL && feed.is_cat) {
return R.drawable.baseline_folder_special_24;
} else if (feed.id == Feed.TYPE_TOGGLE_UNREAD) {
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsModel.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsModel.java
index 171fb29a..66fd0443 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsModel.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsModel.java
@@ -1,14 +1,18 @@
package org.fox.ttrss;
+import android.annotation.SuppressLint;
import android.app.Application;
+import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
+import androidx.preference.PreferenceManager;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
@@ -20,6 +24,8 @@ import org.fox.ttrss.types.Feed;
import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
@@ -28,28 +34,28 @@ import java.util.stream.Collectors;
public class FeedsModel extends AndroidViewModel implements ApiCommon.ApiCaller {
private final String TAG = this.getClass().getSimpleName();
- private MutableLiveData<List<Feed>> m_feeds = new MutableLiveData<>(new ArrayList<>());
- private MutableLiveData<Integer> m_loadingProgress = new MutableLiveData<>(Integer.valueOf(0));
- private MutableLiveData<Long> m_lastUpdate = new MutableLiveData<>(Long.valueOf(0));
- private MutableLiveData<Boolean> m_isLoading = new MutableLiveData<>(Boolean.valueOf(false));
+ protected MutableLiveData<List<Feed>> m_feeds = new MutableLiveData<>(new ArrayList<>());
+ protected MutableLiveData<Integer> m_loadingProgress = new MutableLiveData<>(Integer.valueOf(0));
+ protected MutableLiveData<Long> m_lastUpdate = new MutableLiveData<>(Long.valueOf(0));
+ protected MutableLiveData<Boolean> m_isLoading = new MutableLiveData<>(Boolean.valueOf(false));
- private Feed m_feed;
+ protected Feed m_feed;
- private ExecutorService m_executor;
- private Handler m_mainHandler = new Handler(Looper.getMainLooper());
+ protected ExecutorService m_executor = Executors.newSingleThreadExecutor();
+ protected Handler m_mainHandler = new Handler(Looper.getMainLooper());
private final int m_responseCode = 0;
protected String m_responseMessage;
private int m_apiStatusCode = 0;
private String m_lastErrorMessage;
private ApiCommon.ApiError m_lastError;
- private boolean m_rootMode;
+
+ protected SharedPreferences m_prefs;
public FeedsModel(@NonNull Application application) {
super(application);
- // do we need concurrency or not?
- m_executor = Executors.newSingleThreadExecutor();
+ m_prefs = PreferenceManager.getDefaultSharedPreferences(application);
Log.d(TAG, this + " created");
}
@@ -69,11 +75,10 @@ public class FeedsModel extends AndroidViewModel implements ApiCommon.ApiCaller
m_lastErrorMessage = message;
}
- public void startLoading(Feed feed, boolean rootMode) {
+ public void startLoading(Feed feed) {
Log.d(TAG, "startLoading feed id=" + feed.id + " cat=" + feed.is_cat);
m_feed = feed;
- m_rootMode = rootMode;
loadInBackground();
}
@@ -83,48 +88,45 @@ public class FeedsModel extends AndroidViewModel implements ApiCommon.ApiCaller
m_loadingProgress.postValue(progress);
}
- protected HashMap<String,String> constructParams() {
- HashMap<String,String> params = new HashMap<>();
+ protected void loadInBackground() {
+ Log.d(TAG, this + " loadInBackground");
+
+ m_isLoading.postValue(true);
- if (m_rootMode) {
- params.put("op", "getCategories");
+ m_executor.execute(() -> {
+ final HashMap<String,String> params = new HashMap<>();
- // this confusingly named option means "return top level categories only"
- params.put("enable_nested", "true");
- } else {
params.put("op", "getFeeds");
params.put("cat_id", String.valueOf(m_feed.id));
params.put("include_nested", "true");
- }
+ params.put("sid", ((org.fox.ttrss.Application)getApplication()).getSessionId());
- params.put("sid", ((org.fox.ttrss.Application)getApplication()).getSessionId());
-
- return params;
- }
-
- private void loadInBackground() {
- Log.d(TAG, this + " loadInBackground");
-
- m_isLoading.postValue(true);
-
- HashMap<String,String> params = constructParams();
-
- m_executor.execute(() -> {
- JsonElement result = ApiCommon.performRequest(getApplication(), params, this);
+ final JsonElement result = ApiCommon.performRequest(getApplication(), params, this);
Log.d(TAG, "got result=" + result);
+ boolean unreadOnly = m_prefs.getBoolean("show_unread_only", true);
+
try {
JsonArray content = result.getAsJsonArray();
if (content != null) {
Type listType = new TypeToken<List<Feed>>() {}.getType();
- List<Feed> feeds = new Gson().fromJson(content, listType);
+ List<Feed> feedsJson = new Gson().fromJson(content, listType);
- feeds = feeds.stream().peek(Feed::fixNullFields).collect(Collectors.toList());
+ // seems to be necessary evil because of deserialization
+ feedsJson = feedsJson.stream().peek(Feed::fixNullFields).collect(Collectors.toList());
- m_feeds.postValue(feeds);
+
+ if (unreadOnly && m_feed.id != Feed.CAT_SPECIAL)
+ feedsJson = feedsJson.stream()
+ .filter(f -> f.unread > 0)
+ .collect(Collectors.toList());
+
+ sortFeeds(feedsJson, m_feed, null);
+
+ m_feeds.postValue(feedsJson);
}
} catch (Exception e) {
e.printStackTrace();
@@ -160,4 +162,100 @@ public class FeedsModel extends AndroidViewModel implements ApiCommon.ApiCaller
return m_lastErrorMessage;
}
+ @SuppressLint("DefaultLocale")
+ static class FeedOrderComparator implements Comparator<Feed> {
+
+ @Override
+ public int compare(Feed a, Feed b) {
+ if (a.id >= 0 && b.id >= 0)
+ if (a.is_cat && b.is_cat)
+ if (a.order_id != 0 && b.order_id != 0)
+ return a.order_id - b.order_id;
+ else
+ return a.title.toUpperCase().compareTo(b.title.toUpperCase());
+ else if (a.is_cat)
+ return -1;
+ else if (b.is_cat)
+ return 1;
+ else if (a.order_id != 0 && b.order_id != 0)
+ return a.order_id - b.order_id;
+ else
+ return a.title.toUpperCase().compareTo(b.title.toUpperCase());
+ else
+ if (a.id < CommonActivity.LABEL_BASE_INDEX && b.id < CommonActivity.LABEL_BASE_INDEX)
+ return a.title.toUpperCase().compareTo(b.title.toUpperCase());
+ else
+ return a.id - b.id;
+ }
+
+ }
+
+ @SuppressLint("DefaultLocale")
+ static class FeedUnreadComparator implements Comparator<Feed> {
+
+ @Override
+ public int compare(Feed a, Feed b) {
+ if (a.unread != b.unread)
+ return b.unread - a.unread;
+ else
+ return a.title.toUpperCase().compareTo(b.title.toUpperCase());
+ }
+
+ }
+
+ @SuppressLint("DefaultLocale")
+ static class FeedTitleComparator implements Comparator<Feed> {
+
+ @Override
+ public int compare(Feed a, Feed b) {
+ if (a.is_cat && b.is_cat)
+ return a.title.toUpperCase().compareTo(b.title.toUpperCase());
+ else if (a.is_cat && !b.is_cat)
+ return -1;
+ else if (!a.is_cat && b.is_cat)
+ return 1;
+ else if (a.id >= 0 && b.id >= 0)
+ return a.title.toUpperCase().compareTo(b.title.toUpperCase());
+ else
+ return a.id - b.id;
+ }
+
+ }
+
+ @SuppressLint("DefaultLocale")
+ static class SpecialOrderComparator implements Comparator<Feed> {
+ static List<Integer> order = Arrays.asList(Feed.ALL_ARTICLES, Feed.FRESH, Feed.MARKED,
+ Feed.PUBLISHED, Feed.ARCHIVED, Feed.RECENTLY_READ);
+
+ @Override
+ public int compare(Feed a, Feed b) {
+ return Integer.valueOf(order.indexOf(a.id)).compareTo(order.indexOf(b.id));
+ }
+ }
+
+ protected void sortFeeds(@NonNull List<Feed> feeds, @NonNull Feed feed, @Nullable Comparator<Feed> comparator) {
+
+ if (comparator == null) {
+ if (feed.id == -1) {
+ comparator = new SpecialOrderComparator();
+ } else {
+ if (m_prefs.getBoolean("sort_feeds_by_unread", false)) {
+ comparator = new FeedUnreadComparator();
+ } else {
+ if (org.fox.ttrss.Application.getInstance().getApiLevel() >= 3) {
+ comparator = new FeedOrderComparator();
+ } else {
+ comparator = new FeedTitleComparator();
+ }
+ }
+ }
+ }
+
+ try {
+ feeds.sort(comparator);
+ } catch (IllegalArgumentException e) {
+ //
+ }
+ }
+
} \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesFragment.java
index e94d0405..7e548879 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesFragment.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesFragment.java
@@ -24,75 +24,8 @@ import java.util.stream.Collectors;
public class RootCategoriesFragment extends FeedsFragment {
private final String TAG = this.getClass().getSimpleName();
- @SuppressLint("DefaultLocale")
- static class CatOrderComparator implements Comparator<Feed> {
-
- @Override
- public int compare(Feed a, Feed b) {
- if (a.id >= 0 && b.id >= 0)
- if (a.order_id != 0 && b.order_id != 0)
- return a.order_id - b.order_id;
- else
- return a.title.toUpperCase().compareTo(b.title.toUpperCase());
- else
- return a.id - b.id;
- }
-
- }
-
@Override
- protected void sortFeeds(List<Feed> feeds, Feed feed) {
- try {
- feeds.sort(new CatOrderComparator());
- } catch (IllegalArgumentException e) {
- //
- }
- }
-
- @Override
- public void refresh() {
- if (!isAdded())
- return;
-
- FeedsModel model = new ViewModelProvider(this).get(FeedsModel.class);
- model.startLoading(m_rootFeed, true);
- }
-
- @Override
- protected void onFeedsLoaded(List<Feed> loadedFeeds) {
- List<Feed> feedsWork = new ArrayList<>();
-
- sortFeeds(loadedFeeds, m_rootFeed);
-
- // virtual cats implemented in getCategories since api level 1
- if (m_activity.getApiLevel() == 0) {
- feedsWork.add(0, new Feed(-2, getString(R.string.cat_labels), true));
- feedsWork.add(1, new Feed(-1, getString(R.string.cat_special), true));
- feedsWork.add(new Feed(0, getString(R.string.cat_uncategorized), true));
- }
-
- if (m_activity.getUnreadOnly())
- loadedFeeds = loadedFeeds.stream()
- .filter(f -> f.id == Feed.CAT_SPECIAL || f.unread > 0)
- .collect(Collectors.toList());
-
- loadedFeeds = loadedFeeds.stream()
- .peek(f -> f.is_cat = true)
- .collect(Collectors.toList());
-
- /* if (m_prefs.getBoolean("expand_special_cat", true)) {
- loadedFeeds = loadedFeeds.stream()
- .filter(f -> f.id != Feed.CAT_SPECIAL && f.id != Feed.CAT_LABELS)
- .collect(Collectors.toList());
- } */
-
- feedsWork.addAll(loadedFeeds);
-
- feedsWork.add(new Feed(Feed.TYPE_DIVIDER));
- feedsWork.add(new Feed(Feed.TYPE_TOGGLE_UNREAD, getString(R.string.unread_only), true));
-
- m_adapter.submitList(feedsWork);
-
+ protected FeedsModel getModel() {
+ return new ViewModelProvider(this).get(RootCategoriesModel.class);
}
}
-
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesModel.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesModel.java
new file mode 100644
index 00000000..d5668aa8
--- /dev/null
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesModel.java
@@ -0,0 +1,159 @@
+package org.fox.ttrss;
+
+import android.annotation.SuppressLint;
+import android.app.Application;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.reflect.TypeToken;
+
+import org.fox.ttrss.types.Feed;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class RootCategoriesModel extends FeedsModel {
+ private final String TAG = this.getClass().getSimpleName();
+
+ public RootCategoriesModel(@NonNull Application application) {
+ super(application);
+ }
+
+ @Override
+ protected void loadInBackground() {
+ Log.d(TAG, this + " loadInBackground");
+
+ m_isLoading.postValue(true);
+
+ boolean expandSpecial = m_prefs.getBoolean("expand_special_cat", true);
+
+ final List<Feed> feedsCombined = new ArrayList<>();
+
+ m_executor.execute(() -> {
+
+ // get special category with counters for embedding
+ if (expandSpecial) {
+ final HashMap<String, String> params = new HashMap<>();
+
+ params.put("op", "getFeeds");
+ params.put("cat_id", String.valueOf(Feed.CAT_SPECIAL));
+ params.put("include_nested", "true");
+ params.put("sid", ((org.fox.ttrss.Application)getApplication()).getSessionId());
+
+ final JsonElement result = ApiCommon.performRequest(getApplication(), params, this);
+
+ Log.d(TAG, "got result=" + result);
+
+ try {
+ JsonArray content = result.getAsJsonArray();
+ if (content != null) {
+
+ Type listType = new TypeToken<List<Feed>>() { }.getType();
+
+ List<Feed> feedsJson = new Gson().fromJson(content, listType);
+
+ // seems to be necessary evil because of deserialization
+ feedsJson = feedsJson.stream().peek(Feed::fixNullFields).collect(Collectors.toList());
+
+ sortFeeds(feedsJson, m_feed, new SpecialOrderComparator());
+
+ feedsCombined.addAll(feedsJson);
+
+ feedsCombined.add(new Feed(Feed.TYPE_DIVIDER));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ // get all root categories
+ final HashMap<String,String> params = new HashMap<>();
+
+ params.put("op", "getCategories");
+ params.put("sid", ((org.fox.ttrss.Application)getApplication()).getSessionId());
+
+ // this confusingly named option means "return top level categories only"
+ params.put("enable_nested", "true");
+
+ final JsonElement result = ApiCommon.performRequest(getApplication(), params, this);
+
+ Log.d(TAG, "got result=" + result);
+
+ boolean unreadOnly = m_prefs.getBoolean("show_unread_only", true);
+
+ try {
+ JsonArray content = result.getAsJsonArray();
+ if (content != null) {
+
+ Type listType = new TypeToken<List<Feed>>() {}.getType();
+
+ List<Feed> feedsJson = new Gson().fromJson(content, listType);
+
+ // seems to be necessary evil because of deserialization
+ feedsJson = feedsJson.stream().peek(Feed::fixNullFields).collect(Collectors.toList());
+
+ sortFeeds(feedsJson, m_feed, new CatOrderComparator());
+
+ // virtual cats implemented in getCategories since api level 1
+ if (org.fox.ttrss.Application.getInstance().getApiLevel() == 0) {
+ feedsCombined.add(0, new Feed(-2, getApplication().getString(R.string.cat_labels), true));
+
+ if (!expandSpecial)
+ feedsCombined.add(1, new Feed(-1, getApplication().getString(R.string.cat_special), true));
+
+ feedsCombined.add(new Feed(0, getApplication().getString(R.string.cat_uncategorized), true));
+ }
+
+ if (unreadOnly)
+ feedsJson = feedsJson.stream()
+ .filter(f -> f.id == Feed.CAT_SPECIAL || f.unread > 0)
+ .collect(Collectors.toList());
+
+ // force returned objects to become categories
+ feedsJson = feedsJson.stream()
+ .peek(f -> f.is_cat = true)
+ .collect(Collectors.toList());
+
+ if (expandSpecial) {
+ feedsJson = feedsJson.stream()
+ .filter(f -> f.id != Feed.CAT_SPECIAL)
+ .collect(Collectors.toList());
+ }
+
+ feedsCombined.addAll(feedsJson);
+
+ m_feeds.postValue(feedsCombined);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ m_isLoading.postValue(false);
+ });
+ }
+
+ @SuppressLint("DefaultLocale")
+ static class CatOrderComparator implements Comparator<Feed> {
+
+ @Override
+ public int compare(Feed a, Feed b) {
+ if (a.id >= 0 && b.id >= 0)
+ if (a.order_id != 0 && b.order_id != 0)
+ return a.order_id - b.order_id;
+ else
+ return a.title.toUpperCase().compareTo(b.title.toUpperCase());
+ else
+ return a.id - b.id;
+ }
+
+ }
+
+}
diff --git a/org.fox.ttrss/src/main/res/xml/preferences.xml b/org.fox.ttrss/src/main/res/xml/preferences.xml
index a5a49e04..df3dbc42 100755
--- a/org.fox.ttrss/src/main/res/xml/preferences.xml
+++ b/org.fox.ttrss/src/main/res/xml/preferences.xml
@@ -62,12 +62,11 @@
android:summary="@string/browse_cats_like_feeds_summary"
android:title="@string/browse_cats_like_feeds" />
- <!--
<SwitchPreferenceCompat
android:defaultValue="true"
- android:dependency="@string/enable_cats"
+ android:dependency="enable_cats"
android:key="expand_special_cat"
- android:title="@string/expand_special_cat" /> -->
+ android:title="@string/expand_special_cat" />
<ListPreference
android:defaultValue="0"