summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xorg.fox.ttrss/build.gradle28
-rwxr-xr-xorg.fox.ttrss/src/main/AndroidManifest.xml4
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/ApiCommon.java8
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/ApiLoader.java2
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/ApiRequest.java2
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/Application.java31
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java4
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleModel.java315
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java262
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/BaseFeedlistFragment.java6
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/CommonActivity.java20
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java54
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/FeedCategoriesFragment.java17
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java33
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesEventListener.java2
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java566
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java22
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java145
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/share/CommonActivity.java14
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/share/ShareActivity.java2
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/share/SubscribeActivity.java4
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java62
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java23
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/util/ArticleDiffItemCallback.java21
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/util/DiffFragmentStateAdapter.java54
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesRequest.java106
-rw-r--r--org.fox.ttrss/src/main/res/drawable/ic_launcher_background_variant.xml42
-rw-r--r--org.fox.ttrss/src/main/res/drawable/rss.xml1
-rw-r--r--org.fox.ttrss/src/main/res/drawable/rss_box.xml1
-rw-r--r--org.fox.ttrss/src/main/res/layout-sw600dp-land/activity_detail.xml2
-rw-r--r--org.fox.ttrss/src/main/res/layout-sw600dp-land/activity_master.xml2
-rw-r--r--org.fox.ttrss/src/main/res/layout/activity_gallery.xml2
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/feeds_goback.xml2
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/feeds_row.xml2
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/feeds_row_selected.xml2
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/feeds_row_toggle.xml2
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/fragment_headlines.xml1
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/headlines_row.xml10
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/headlines_row_compact.xml2
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/headlines_row_compact_active.xml3
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/headlines_row_compact_active_unread.xml2
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/headlines_row_compact_unread.xml2
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/headlines_row_unread.xml10
-rw-r--r--org.fox.ttrss/src/main/res/layout/layout_detail_phone.xml2
-rw-r--r--org.fox.ttrss/src/main/res/layout/layout_master_phone.xml2
-rw-r--r--org.fox.ttrss/src/main/res/mipmap-anydpi-v26/ic_launcher_variant.xml5
-rw-r--r--org.fox.ttrss/src/main/res/values-night/themes.xml23
-rwxr-xr-xorg.fox.ttrss/src/main/res/values/attrs.xml26
-rwxr-xr-xorg.fox.ttrss/src/main/res/values/strings.xml1
-rw-r--r--org.fox.ttrss/src/main/res/values/themes.xml23
-rwxr-xr-xorg.fox.ttrss/src/main/res/xml/preferences.xml3
-rw-r--r--org.fox.ttrss/src_drawable/s_dashclock.svg1071
-rw-r--r--org.fox.ttrss/src_drawable/s_drawer_header.svg257
-rw-r--r--org.fox.ttrss/src_drawable/s_drawer_header_amber.svg257
-rw-r--r--org.fox.ttrss/src_drawable/s_drawer_header_dark.svg257
55 files changed, 1030 insertions, 2792 deletions
diff --git a/org.fox.ttrss/build.gradle b/org.fox.ttrss/build.gradle
index c8d9b3d5..7ffaf523 100755
--- a/org.fox.ttrss/build.gradle
+++ b/org.fox.ttrss/build.gradle
@@ -16,6 +16,9 @@ android {
versionCode getGitVersionCode()
versionName getVersion()
vectorDrawables.useSupportLibrary = true
+ manifestPlaceholders = [
+ appIcon: "@mipmap/ic_launcher"
+ ]
}
signingConfigs {
@@ -36,8 +39,20 @@ android {
}
buildTypes {
+ debug {
+ minifyEnabled false
+ versionNameSuffix "-debug"
+ applicationIdSuffix ".debug"
+ debuggable true
+ resValue "string", "app_name", "Tiny Tiny RSS (debug)"
+ manifestPlaceholders = [
+ appIcon: "@mipmap/ic_launcher_variant"
+ ]
+ }
+
release {
minifyEnabled false
+ versionNameSuffix "-release-unsigned"
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
@@ -46,7 +61,18 @@ android {
versionNameSuffix "-signed"
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
signingConfig signingConfigs.signed
- matchingFallbacks = ['release']
+ }
+
+ branch {
+ minifyEnabled false
+ versionNameSuffix "-signed-branch"
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+ signingConfig signingConfigs.signed
+ applicationIdSuffix ".branch"
+ resValue "string", "app_name", "Tiny Tiny RSS (branch)"
+ manifestPlaceholders = [
+ appIcon: "@mipmap/ic_launcher_variant"
+ ]
}
}
namespace 'org.fox.ttrss'
diff --git a/org.fox.ttrss/src/main/AndroidManifest.xml b/org.fox.ttrss/src/main/AndroidManifest.xml
index feb8a2e1..3388d515 100755
--- a/org.fox.ttrss/src/main/AndroidManifest.xml
+++ b/org.fox.ttrss/src/main/AndroidManifest.xml
@@ -17,7 +17,7 @@
android:name=".Application"
android:allowBackup="true"
android:hardwareAccelerated="true"
- android:icon="@mipmap/ic_launcher"
+ android:icon="${appIcon}"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config" >
@@ -217,7 +217,7 @@
<provider
android:name="androidx.core.content.FileProvider"
- android:authorities="org.fox.ttrss.SharedFileProvider"
+ android:authorities="${applicationId}.SharedFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiCommon.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiCommon.java
index 75963c96..adc0881d 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiCommon.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiCommon.java
@@ -41,13 +41,16 @@ public class ApiCommon {
void setLastErrorMessage(String message);
}
- public enum ApiError { NO_ERROR, HTTP_UNAUTHORIZED, HTTP_FORBIDDEN, HTTP_NOT_FOUND,
+ public enum ApiError {
+ SUCCESS, UNKNOWN_ERROR, HTTP_UNAUTHORIZED, HTTP_FORBIDDEN, HTTP_NOT_FOUND,
HTTP_SERVER_ERROR, HTTP_OTHER_ERROR, SSL_REJECTED, SSL_HOSTNAME_REJECTED, PARSE_ERROR, IO_ERROR, OTHER_ERROR, API_DISABLED,
API_UNKNOWN, LOGIN_FAILED, INVALID_URL, API_INCORRECT_USAGE, NETWORK_UNAVAILABLE, API_UNKNOWN_METHOD }
public static int getErrorMessage(ApiError error) {
switch (error) {
- case NO_ERROR:
+ case SUCCESS:
+ return R.string.error_success;
+ case UNKNOWN_ERROR:
return R.string.error_unknown;
case HTTP_UNAUTHORIZED:
return R.string.error_http_unauthorized;
@@ -154,6 +157,7 @@ public class ApiCommon {
switch (statusCode) {
case API_STATUS_OK:
+ caller.setLastError(ApiError.SUCCESS);
return result.getAsJsonObject().get("content");
case API_STATUS_ERR:
JsonObject contentObj = resultObj.get("content").getAsJsonObject();
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiLoader.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiLoader.java
index 259d7a28..8d83e7bd 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiLoader.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiLoader.java
@@ -27,7 +27,7 @@ public class ApiLoader extends AsyncTaskLoader<JsonElement> implements ApiCommon
super(context);
m_context = context;
- m_lastError = ApiError.NO_ERROR;
+ m_lastError = ApiError.UNKNOWN_ERROR;
m_params = params;
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiRequest.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiRequest.java
index 409047f0..ba8dad20 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiRequest.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ApiRequest.java
@@ -21,7 +21,7 @@ public class ApiRequest extends AsyncTask<HashMap<String,String>, Integer, JsonE
public ApiRequest(Context context) {
m_context = context;
- m_lastError = ApiError.NO_ERROR;
+ m_lastError = ApiError.UNKNOWN_ERROR;
}
@SuppressLint("NewApi")
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 07f1a3b5..75542e3c 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
@@ -1,5 +1,8 @@
package org.fox.ttrss;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
import android.os.Bundle;
import org.fox.ttrss.types.ArticleList;
@@ -8,22 +11,28 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
public class Application extends android.app.Application {
- private static Application m_singleton;
+ public static final int LOADER_HEADLINES = 0;
+ public static final int LOADER_FEEDS = 1;
+ public static final int LOADER_CATS = 2;
- // this is the only instance of a (large) object which contains all currently loaded articles and is
- // used by all fragments and activities concurrently
- private final ArticleList m_articles = new ArticleList();
+ private static Application m_singleton;
private String m_sessionId;
private int m_apiLevel;
public LinkedHashMap<String, String> m_customSortModes = new LinkedHashMap<>();
+ ConnectivityManager m_cmgr;
+ ArticleModel m_articleModel;
public static Application getInstance(){
return m_singleton;
}
public static ArticleList getArticles() {
- return getInstance().m_articles;
+ return getInstance().m_articleModel.getArticles().getValue();
+ }
+
+ public static ArticleModel getArticlesModel() {
+ return getInstance().m_articleModel;
}
@Override
@@ -31,6 +40,8 @@ public class Application extends android.app.Application {
super.onCreate();
m_singleton = this;
+ m_cmgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+ m_articleModel = new ArticleModel(this);
}
public String getSessionId() {
@@ -68,6 +79,14 @@ public class Application extends android.app.Application {
m_customSortModes.clear();
m_customSortModes.putAll(tmp);
}
-
+ }
+
+ public boolean isWifiConnected() {
+ NetworkInfo wifi = m_cmgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+
+ if (wifi != null)
+ return wifi.isConnected();
+
+ return false;
}
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java
index 3ee42976..8794e653 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java
@@ -157,7 +157,7 @@ public class ArticleFragment extends androidx.fragment.app.Fragment {
View noteContainer = view.findViewById(R.id.note_container);
if (note != null && noteContainer != null) {
- if (m_article.note != null && !m_article.note.isEmpty()) {
+ if (!m_article.note.isEmpty()) {
note.setTextSize(TypedValue.COMPLEX_UNIT_SP, m_articleSmallFontSize);
note.setText(m_article.note);
noteContainer.setVisibility(View.VISIBLE);
@@ -259,7 +259,7 @@ public class ArticleFragment extends androidx.fragment.app.Fragment {
String linkHexColor = String.format("#%06X", (0xFFFFFF & tvColorPrimary.data));
cssOverride += " a:link {color: "+linkHexColor+";} a:visited { color: "+linkHexColor+";}";
- String articleContent = m_article.content != null ? m_article.content : "";
+ String articleContent = m_article.content;
ws.setJavaScriptEnabled(false);
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleModel.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleModel.java
new file mode 100644
index 00000000..80467f63
--- /dev/null
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleModel.java
@@ -0,0 +1,315 @@
+package org.fox.ttrss;
+
+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.lifecycle.AndroidViewModel;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.preference.PreferenceManager;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.reflect.TypeToken;
+
+import org.fox.ttrss.types.Article;
+import org.fox.ttrss.types.ArticleList;
+import org.fox.ttrss.types.Feed;
+
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class ArticleModel extends AndroidViewModel implements ApiCommon.ApiCaller {
+ private final String TAG = this.getClass().getSimpleName();
+ private final MutableLiveData<ArticleList> m_articles = new MutableLiveData<>(new ArticleList());
+ private SharedPreferences m_prefs;
+ 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 Feed m_feed;
+ private int m_firstId;
+ private String m_searchQuery = "";
+ private boolean m_firstIdChanged;
+ private int m_offset;
+ private int m_amountLoaded;
+ private int m_resizeWidth;
+ private boolean m_append;
+ private boolean m_lazyLoadEnabled = true;
+ private boolean m_loadingInProgress;
+ private ExecutorService m_executor;
+ private Handler m_mainHandler = new Handler(Looper.getMainLooper());
+ private MutableLiveData<Long> m_lastUpdate = new MutableLiveData<>(Long.valueOf(0));
+
+ public ArticleModel(@NonNull Application application) {
+ super(application);
+
+ m_prefs = PreferenceManager.getDefaultSharedPreferences(application);
+
+ // do we need concurrency or not?
+ m_executor = Executors.newSingleThreadExecutor();
+ }
+
+ public LiveData<Long> getUpdatesData() {
+ return m_lastUpdate;
+ }
+
+ public LiveData<ArticleList> getArticles() {
+ return m_articles;
+ }
+
+
+ public void update(int position, Article article) {
+ m_articles.getValue().set(position, article);
+ m_articles.postValue(m_articles.getValue());
+ }
+
+ public void update(ArticleList articles) {
+ m_articles.postValue(articles);
+ }
+
+ public void startLoading(boolean append, @NonNull Feed feed, int resizeWidth) {
+ Log.d(TAG, "startLoading append=" + append);
+
+ m_resizeWidth = resizeWidth;
+
+ if (!append) {
+ m_append = false;
+ m_lazyLoadEnabled = true;
+ m_feed = feed;
+
+ loadInBackground();
+ } else if (feed != m_feed || m_lazyLoadEnabled && !m_loadingInProgress) {
+ m_append = true;
+ m_feed = feed;
+
+ loadInBackground();
+ } else {
+ m_articles.postValue(m_articles.getValue());
+ }
+ }
+
+ private void loadInBackground() {
+ Log.d(TAG, this + " loadInBackground append=" + m_append + " offset=" + m_offset);
+
+ ArticleList articlesWork = new ArticleList(m_articles.getValue());
+
+ m_loadingInProgress = true;
+
+ final int skip = getSkip(m_append, articlesWork);
+ final boolean allowForceUpdate = org.fox.ttrss.Application.getInstance().getApiLevel() >= 9 &&
+ !m_feed.is_cat && m_feed.id > 0 && !m_append && skip == 0;
+
+ HashMap<String,String> params = new HashMap<>();
+
+ params.put("op", "getHeadlines");
+ params.put("sid", org.fox.ttrss.Application.getInstance().getSessionId());
+ params.put("feed_id", String.valueOf(m_feed.id));
+ params.put("show_excerpt", "true");
+ params.put("excerpt_length", String.valueOf(CommonActivity.EXCERPT_MAX_LENGTH));
+ params.put("show_content", "true");
+ params.put("include_attachments", "true");
+ params.put("view_mode", m_prefs.getString("view_mode", "adaptive"));
+ params.put("limit", m_prefs.getString("headlines_request_size", "15"));
+ params.put("skip", String.valueOf(skip));
+ params.put("include_nested", "true");
+ params.put("has_sandbox", "true");
+ params.put("order_by", m_prefs.getString("headlines_sort_mode", "default"));
+
+ if (m_prefs.getBoolean("enable_image_downsampling", false)) {
+ if (m_prefs.getBoolean("always_downsample_images", false) || !org.fox.ttrss.Application.getInstance().isWifiConnected()) {
+ params.put("resize_width", String.valueOf(m_resizeWidth));
+ }
+ }
+
+ if (m_feed.is_cat)
+ params.put("is_cat", "true");
+
+ if (allowForceUpdate) {
+ params.put("force_update", "true");
+ }
+
+ if (m_searchQuery != null && !m_searchQuery.isEmpty()) {
+ params.put("search", m_searchQuery);
+ params.put("search_mode", "");
+ params.put("match_on", "both");
+ }
+
+ if (m_firstId > 0)
+ params.put("check_first_id", String.valueOf(m_firstId));
+
+ if (org.fox.ttrss.Application.getInstance().getApiLevel() >= 12) {
+ params.put("include_header", "true");
+ }
+
+ Log.d(TAG, "firstId=" + m_firstId + " append=" + m_append + " skip=" + skip + " localSize=" + articlesWork.size());
+
+ m_executor.execute(() -> {
+ JsonElement result = ApiCommon.performRequest(getApplication(), params, this);
+
+ Log.d(TAG, "got result=" + result);
+
+ if (result != null) {
+ try {
+ JsonArray content = result.getAsJsonArray();
+ if (content != null) {
+ final List<Article> articlesJson;
+ final JsonObject header;
+
+ if (org.fox.ttrss.Application.getInstance().getApiLevel() >= 12) {
+ header = content.get(0).getAsJsonObject();
+
+ m_firstIdChanged = header.get("first_id_changed") != null;
+
+ try {
+ m_firstId = header.get("first_id").getAsInt();
+ } catch (NumberFormatException e) {
+ m_firstId = 0;
+ }
+
+ Log.d(TAG, this + " firstID=" + m_firstId + " firstIdChanged=" + m_firstIdChanged);
+
+ Type listType = new TypeToken<List<Article>>() {}.getType();
+ articlesJson = new Gson().fromJson(content.get(1), listType);
+ } else {
+ Type listType = new TypeToken<List<Article>>() {}.getType();
+ articlesJson = new Gson().fromJson(content, listType);
+ }
+
+ if (!m_append)
+ articlesWork.clear();
+
+ m_amountLoaded = articlesJson.size();
+
+ for (Article article : articlesJson)
+ if (!articlesWork.containsId(article.id)) {
+ article.collectMediaInfo();
+ article.cleanupExcerpt();
+ article.fixNullFields();
+ articlesWork.add(article);
+ }
+
+ if (m_firstIdChanged) {
+ Log.d(TAG, "first id changed, disabling lazy load");
+ m_lazyLoadEnabled = false;
+ }
+
+ if (m_amountLoaded < Integer.parseInt(m_prefs.getString("headlines_request_size", "15"))) {
+ Log.d(TAG, this + " amount loaded "+m_amountLoaded+" < request size, disabling lazy load");
+ m_lazyLoadEnabled = false;
+ }
+
+ m_offset += m_amountLoaded;
+ m_loadingInProgress = false;
+
+ Log.d(TAG, this + " loaded headlines=" + m_amountLoaded + " resultingLocalSize=" + articlesWork.size());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ m_mainHandler.post(() -> {
+ m_articles.setValue(articlesWork);
+ m_lastUpdate.setValue(System.currentTimeMillis());
+ });
+ });
+
+ m_loadingInProgress = false;
+
+ }
+
+ private int getSkip(boolean append, ArticleList articles) {
+ int skip = 0;
+
+ if (append) {
+ // adaptive, all_articles, marked, published, unread
+ String viewMode = m_prefs.getString("view_mode", "adaptive");
+
+ int numUnread = Math.toIntExact(articles.getUnreadCount());
+ int numAll = Math.toIntExact(articles.size());
+
+ if ("marked".equals(viewMode)) {
+ skip = numAll;
+ } else if ("published".equals(viewMode)) {
+ skip = numAll;
+ } else if ("unread".equals(viewMode)) {
+ skip = numUnread;
+ } else if (m_searchQuery != null && !m_searchQuery.isEmpty()) {
+ skip = numAll;
+ } else if ("adaptive".equals(viewMode)) {
+ skip = numUnread > 0 ? numUnread : numAll;
+ } else {
+ skip = numAll;
+ }
+ }
+
+ return skip;
+ }
+
+ @Override
+ public void setStatusCode(int statusCode) {
+ m_apiStatusCode = statusCode;
+ }
+
+ @Override
+ public void setLastError(ApiCommon.ApiError lastError) {
+ m_lastError = lastError;
+ }
+
+ @Override
+ public void setLastErrorMessage(String message) {
+ m_lastErrorMessage = message;
+ }
+
+ public boolean getFirstIdChanged() {
+ return m_firstIdChanged;
+ }
+
+ public boolean getAppend() {
+ return m_append;
+ }
+
+ public void setSearchQuery(String searchQuery) {
+ m_searchQuery = searchQuery;
+ }
+
+ public String getSearchQuery() {
+ return m_searchQuery;
+ }
+
+ public int getOffset() {
+ return m_offset;
+ }
+
+ public boolean lazyLoadEnabled() {
+ return m_lazyLoadEnabled;
+ }
+
+ public int getErrorMessage() {
+ return ApiCommon.getErrorMessage(m_lastError);
+ }
+
+ ApiCommon.ApiError getLastError() {
+ return m_lastError;
+ }
+
+ String getLastErrorMessage() {
+ return m_lastErrorMessage;
+ }
+
+ public boolean isLoading() {
+ return m_loadingInProgress;
+ }
+}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java
index da9dc8f3..cf43f4f0 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java
@@ -2,10 +2,7 @@ package org.fox.ttrss;
import android.annotation.SuppressLint;
import android.app.Activity;
-import android.content.SharedPreferences;
-import android.os.BadParcelableException;
import android.os.Bundle;
-import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -13,65 +10,44 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-import androidx.preference.PreferenceManager;
-import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
-import com.google.android.material.snackbar.Snackbar;
-import com.google.gson.JsonElement;
-
import org.fox.ttrss.types.Article;
+import org.fox.ttrss.types.ArticleList;
import org.fox.ttrss.types.Feed;
-import org.fox.ttrss.util.HeadlinesRequest;
-
-import java.util.HashMap;
+import org.fox.ttrss.util.DiffFragmentStateAdapter;
+import org.fox.ttrss.util.ArticleDiffItemCallback;
public class ArticlePager extends androidx.fragment.app.Fragment {
- private final String TAG = "ArticlePager";
+ private final String TAG = this.getClass().getSimpleName();
private PagerAdapter m_adapter;
private HeadlinesEventListener m_listener;
private int m_articleId;
private OnlineActivity m_activity;
- private String m_searchQuery = "";
private Feed m_feed;
- private SharedPreferences m_prefs;
- private int m_firstId = 0;
- private boolean m_refreshInProgress;
- private boolean m_lazyLoadDisabled;
private ViewPager2 m_pager;
- private static class PagerAdapter extends FragmentStateAdapter {
-
- public PagerAdapter(FragmentActivity fa) {
- super(fa);
+ private static class PagerAdapter extends DiffFragmentStateAdapter<Article> {
+
+ public PagerAdapter(@NonNull Fragment fragment) {
+ super(fragment, new ArticleDiffItemCallback());
+ }
+
+ private void syncToSharedArticles() {
+ submitList(new ArticleList(Application.getArticles()));
}
@Override
@NonNull
public Fragment createFragment(int position) {
- try {
- Article article = Application.getArticles().get(position);
-
- if (article != null) {
- ArticleFragment af = new ArticleFragment();
- af.initialize(article);
-
- return af;
- }
- } catch (IndexOutOfBoundsException e) {
- e.printStackTrace();
- }
+ Article article = getItem(position);
- return null;
- }
+ ArticleFragment af = new ArticleFragment();
+ af.initialize(article);
- @Override
- public int getItemCount() {
- return Application.getArticles().size();
+ return af;
}
-
}
public void initialize(int articleId, Feed feed) {
@@ -79,17 +55,12 @@ public class ArticlePager extends androidx.fragment.app.Fragment {
m_feed = feed;
}
- public void setSearchQuery(String searchQuery) {
- m_searchQuery = searchQuery;
- }
-
@Override
public void onSaveInstanceState(Bundle out) {
super.onSaveInstanceState(out);
out.putInt("m_articleId", m_articleId);
out.putParcelable("m_feed", m_feed);
- out.putInt("m_firstId", m_firstId);
}
@Override
@@ -99,7 +70,6 @@ public class ArticlePager extends androidx.fragment.app.Fragment {
if (savedInstanceState != null) {
m_articleId = savedInstanceState.getInt("m_articleId");
m_feed = savedInstanceState.getParcelable("m_feed");
- m_firstId = savedInstanceState.getInt("m_firstId");
}
setRetainInstance(true);
@@ -109,36 +79,42 @@ public class ArticlePager extends androidx.fragment.app.Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_article_pager, container, false);
- m_adapter = new PagerAdapter(getActivity());
+ m_adapter = new PagerAdapter(this);
+ m_adapter.submitList(Application.getArticles());
+
+ ArticleModel model = Application.getArticlesModel();
+
+ // deal with further updates
+ model.getArticles().observe(getActivity(), articles -> {
+ Log.d(TAG, "observed article list size=" + articles.size());
+ m_adapter.submitList(articles);
+ });
m_pager = view.findViewById(R.id.article_pager);
- int position = Application.getArticles().getPositionById(m_articleId);
-
m_listener.onArticleSelected(Application.getArticles().getById(m_articleId), false);
m_pager.setAdapter(m_adapter);
m_pager.setOffscreenPageLimit(3);
- m_pager.setCurrentItem(position, false);
+ int position = Application.getArticles().getPositionById(m_articleId);
+
+ if (position != -1)
+ m_pager.setCurrentItem(position, false);
+
m_pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
Log.d(TAG, "onPageSelected: " + position);
- final Article article = Application.getArticles().get(position);
-
- if (article != null) {
- m_articleId = article.id;
-
- new Handler().postDelayed(() -> m_listener.onArticleSelected(article, false), 250);
+ // wtf
+ if (position != -1) {
+ Article article = Application.getArticles().get(position);
- //Log.d(TAG, "Page #" + position + "/" + m_adapter.getCount());
+ if (article != null) {
+ m_articleId = article.id;
- if (!m_refreshInProgress && !m_lazyLoadDisabled && (m_activity.isSmallScreen() || m_activity.isPortrait()) && position >= m_adapter.getItemCount() - 5) {
- Log.d(TAG, "loading more articles...");
-
- new Handler().postDelayed(() -> refresh(true), 100);
+ m_listener.onArticleSelected(article, false);
}
}
}
@@ -146,170 +122,19 @@ public class ArticlePager extends androidx.fragment.app.Fragment {
return view;
}
-
- protected void refresh(final boolean append) {
-
- if (!append) {
- m_lazyLoadDisabled = false;
- }
-
- m_refreshInProgress = true;
-
- @SuppressLint("StaticFieldLeak") HeadlinesRequest req = new HeadlinesRequest(getActivity().getApplicationContext(), m_activity, Application.getArticles()) {
- @Override
- protected void onPostExecute(JsonElement result) {
- if (isDetached() || !isAdded()) return;
-
- if (!append) {
- m_pager.setCurrentItem(0, false);
- Application.getArticles().clear();
- }
-
- super.onPostExecute(result);
-
- m_refreshInProgress = false;
-
- if (result != null) {
-
- if (m_firstIdChanged) {
- m_lazyLoadDisabled = true;
- }
-
- if (m_firstIdChanged && !(m_activity instanceof DetailActivity && !m_activity.isPortrait())) {
- //m_activity.toast(R.string.headlines_row_top_changed);
-
- Snackbar.make(getView(), R.string.headlines_row_top_changed, Snackbar.LENGTH_LONG)
- .setAction(R.string.reload, v -> refresh(false)).show();
- }
-
- if (m_amountLoaded < Integer.parseInt(m_prefs.getString("headlines_request_size", "15"))) {
- m_lazyLoadDisabled = true;
- }
-
- ArticlePager.this.m_firstId = m_firstId;
-
- try {
- m_adapter.notifyDataSetChanged();
- } catch (BadParcelableException e) {
- if (getActivity() != null) {
- getActivity().finish();
- return;
- }
- }
-
- if (!Application.getArticles().isEmpty()) {
- if (Application.getArticles().getById(m_articleId) == null) {
- Article article = Application.getArticles().get(0);
-
- m_articleId = article.id;
- m_listener.onArticleSelected(article, false);
- }
- }
-
- } else {
- m_lazyLoadDisabled = true;
-
- if (m_lastError == ApiCommon.ApiError.LOGIN_FAILED) {
- m_activity.login(true);
- } else {
- m_activity.toast(getErrorMessage());
- }
- }
- }
- };
-
- final Feed feed = m_feed;
-
- final String sessionId = m_activity.getSessionId();
- int skip = 0;
-
- if (append) {
- // adaptive, all_articles, marked, published, unread
- String viewMode = m_activity.getViewMode();
- int numUnread = 0;
- int numAll = Application.getArticles().size();
-
- for (Article a : Application.getArticles()) {
- if (a.unread) ++numUnread;
- }
-
- if ("marked".equals(viewMode)) {
- skip = numAll;
- } else if ("published".equals(viewMode)) {
- skip = numAll;
- } else if ("unread".equals(viewMode)) {
- skip = numUnread;
- } else if (m_searchQuery != null && !m_searchQuery.isEmpty()) {
- skip = numAll;
- } else if ("adaptive".equals(viewMode)) {
- skip = numUnread > 0 ? numUnread : numAll;
- } else {
- skip = numAll;
- }
- }
-
- final int fskip = skip;
-
- req.setOffset(skip);
-
- HashMap<String,String> map = new HashMap<>();
- map.put("op", "getHeadlines");
- map.put("sid", sessionId);
- map.put("feed_id", String.valueOf(feed.id));
- map.put("show_excerpt", "true");
- map.put("excerpt_length", String.valueOf(CommonActivity.EXCERPT_MAX_LENGTH));
- map.put("show_content", "true");
- map.put("include_attachments", "true");
- map.put("limit", m_prefs.getString("headlines_request_size", "15"));
- map.put("offset", String.valueOf(0));
- map.put("view_mode", m_activity.getViewMode());
- map.put("skip", String.valueOf(fskip));
- map.put("include_nested", "true");
- map.put("has_sandbox", "true");
- map.put("order_by", m_activity.getSortMode());
-
- if (feed.is_cat) map.put("is_cat", "true");
-
- if (m_searchQuery != null && !m_searchQuery.isEmpty()) {
- map.put("search", m_searchQuery);
- map.put("search_mode", "");
- map.put("match_on", "both");
- }
-
- if (m_firstId > 0) map.put("check_first_id", String.valueOf(m_firstId));
-
- if (m_activity.getApiLevel() >= 12) {
- map.put("include_header", "true");
- }
-
- if (m_prefs.getBoolean("enable_image_downsampling", false)) {
- if (m_prefs.getBoolean("always_downsample_images", false) || !m_activity.isWifiConnected()) {
- map.put("resize_width", String.valueOf(m_activity.getResizeWidth()));
- }
- }
-
- Log.d(TAG, "[AP] request more headlines, firstId=" + m_firstId);
- req.execute(map);
- }
-
@Override
public void onAttach(@NonNull Activity activity) {
super.onAttach(activity);
m_listener = (HeadlinesEventListener)activity;
m_activity = (OnlineActivity)activity;
-
- m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
}
@SuppressLint("NewApi")
@Override
public void onResume() {
super.onResume();
-
- //if (m_adapter != null) m_adapter.notifyDataSetChanged();
-
m_activity.invalidateOptionsMenu();
}
@@ -317,7 +142,8 @@ public class ArticlePager extends androidx.fragment.app.Fragment {
if (m_pager != null && articleId != m_articleId) {
int position = Application.getArticles().getPositionById(articleId);
- m_pager.setCurrentItem(position, false);
+ if (position != -1)
+ m_pager.setCurrentItem(position, false);
}
}
@@ -345,7 +171,13 @@ public class ArticlePager extends androidx.fragment.app.Fragment {
return m_articleId;
}
- public void notifyUpdated() {
- m_adapter.notifyDataSetChanged();
+ public void notifyItemChanged(int position) {
+ if (m_adapter != null)
+ m_adapter.notifyItemChanged(position);
+ }
+
+ public void syncToSharedArticles() {
+ if (m_adapter != null)
+ m_adapter.syncToSharedArticles();
}
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/BaseFeedlistFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/BaseFeedlistFragment.java
index 86a31465..b37f7386 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/BaseFeedlistFragment.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/BaseFeedlistFragment.java
@@ -17,7 +17,7 @@ import java.net.URL;
public abstract class BaseFeedlistFragment extends androidx.fragment.app.Fragment {
abstract public void refresh();
- public void initDrawerHeader(LayoutInflater inflater, View view, ListView list, final CommonActivity activity, final SharedPreferences prefs, boolean isRoot) {
+ public void initDrawerHeader(LayoutInflater inflater, View view, ListView list, final CommonActivity activity, final SharedPreferences prefs) {
View layout = inflater.inflate(R.layout.drawer_header, list, false);
list.addHeaderView(layout, null, false);
@@ -62,9 +62,7 @@ public abstract class BaseFeedlistFragment extends androidx.fragment.app.Fragmen
text.setText(R.string.unread_only);
ImageView icon = rowToggle.findViewById(R.id.icon);
- TypedValue tv = new TypedValue();
- getActivity().getTheme().resolveAttribute(R.attr.ic_filter_variant, tv, true);
- icon.setImageResource(tv.resourceId);
+ icon.setImageResource(R.drawable.baseline_filter_alt_24);
final SwitchCompat rowSwitch = rowToggle.findViewById(R.id.row_switch);
rowSwitch.setChecked(activity.getUnreadOnly());
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/CommonActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/CommonActivity.java
index cdc261b7..97e356c4 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/CommonActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/CommonActivity.java
@@ -15,8 +15,6 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -66,7 +64,6 @@ public class CommonActivity extends AppCompatActivity implements SharedPreferenc
public final static String FRAG_ARTICLE = "article";
public final static String FRAG_FEEDS = "feeds";
public final static String FRAG_CATS = "cats";
- public final static String FRAG_DIALOG = "dialog";
public final static String THEME_DEFAULT = "THEME_FOLLOW_DEVICE";
@@ -74,7 +71,6 @@ public class CommonActivity extends AppCompatActivity implements SharedPreferenc
public final static String NOTIFICATION_CHANNEL_PRIORITY = "channel_priority";
public static final int EXCERPT_MAX_LENGTH = 256;
- public static final int EXCERPT_MAX_QUERY_LENGTH = 2048;
public static final int LABEL_BASE_INDEX = -1024;
public static final int PENDING_INTENT_CHROME_SHARE = 1;
@@ -330,22 +326,6 @@ public class CommonActivity extends AppCompatActivity implements SharedPreferenc
});
}
- protected void preloadUriIfAllowed(Uri uri) {
- boolean enableCustomTabs = m_prefs.getBoolean("enable_custom_tabs", true);
-
- if (m_customTabClient != null && enableCustomTabs) {
- ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo info = cm.getActiveNetworkInfo();
-
- if (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI) {
- CustomTabsSession session = getCustomTabSession();
- session.mayLaunchUrl(uri, null, null);
-
- //toast("Preloading: " + uri.toString());
- }
- }
- }
-
protected Intent getShareIntent(String text, String subject) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java
index 6558c2d1..bca2aa40 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java
@@ -6,7 +6,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -94,7 +93,7 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList
saveArticleUnread(article);
if (hf != null) {
- hf.notifyUpdated();
+ hf.notifyItemChanged(Application.getArticles().indexOf(article));
}
}
}
@@ -149,17 +148,16 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- final HeadlinesFragment hf = new HeadlinesFragment();
+ HeadlinesFragment hf = new HeadlinesFragment();
hf.initialize(feed, openedArticleId, true);
hf.setSearchQuery(searchQuery);
ft.replace(R.id.headlines_fragment, hf, FRAG_HEADLINES);
- ArticlePager af = new ArticlePager();
- af.initialize(openedArticleId, feed);
- af.setSearchQuery(searchQuery);
+ ArticlePager ap = new ArticlePager();
+ ap.initialize(openedArticleId, feed);
- ft.replace(R.id.article_fragment, af, FRAG_ARTICLE);
+ ft.replace(R.id.article_fragment, ap, FRAG_ARTICLE);
ft.commit();
@@ -199,8 +197,8 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList
menu.findItem(R.id.article_set_score).setIcon(R.drawable.baseline_trending_flat_24);
}
- menu.findItem(R.id.toggle_unread).setIcon(selectedArticle.unread ? R.drawable.baseline_drafts_24 :
- R.drawable.baseline_email_24);
+ menu.findItem(R.id.toggle_unread).setIcon(selectedArticle.unread ? R.drawable.baseline_email_24 :
+ R.drawable.baseline_drafts_24);
menu.findItem(R.id.toggle_attachments).setVisible(selectedArticle.attachments != null && !selectedArticle.attachments.isEmpty());
}
@@ -261,7 +259,7 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList
}
@Override
- public void onArticleListSelectionChange(ArticleList m_selectedArticles) {
+ public void onArticleListSelectionChange() {
invalidateOptionsMenu();
}
@@ -271,35 +269,23 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList
}
@Override
- public void onArticleSelected(final Article article, boolean open) {
-
- if (article == null) return;
-
+ public void onArticleSelected(Article article, boolean open) {
+
if (article.unread) {
article.unread = false;
saveArticleUnread(article);
}
- try {
- preloadUriIfAllowed(Uri.parse(article.link));
- } catch (Exception e) {
- e.printStackTrace();
- }
-
if (!getSupportActionBar().isShowing()) getSupportActionBar().show();
- if (open) {
-
- new Handler().postDelayed(() -> {
- ArticlePager ap = (ArticlePager) DetailActivity.this.getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
-
- if (ap != null) {
- ap.setActiveArticleId(article.id);
- }
- }, 250);
+ ArticlePager ap = (ArticlePager) DetailActivity.this.getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
+ HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+ if (open) {
+ if (ap != null) {
+ ap.setActiveArticleId(article.id);
+ }
} else {
- HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
if (hf != null) {
hf.setActiveArticleId(article.id);
}
@@ -313,11 +299,11 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList
HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
- if (ap != null) {
- ap.notifyUpdated();
+ if (ap != null) {
+ ap.syncToSharedArticles();
}
- if (hf != null) {
+ /* if (hf != null) {
Article article = Application.getArticles().getById(hf.getActiveArticleId());
if (article == null && !Application.getArticles().isEmpty()) {
@@ -335,7 +321,7 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList
ft.replace(R.id.article_fragment, af, FRAG_ARTICLE);
ft.commitAllowingStateLoss();
}
- }
+ } */
}
@Override
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedCategoriesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedCategoriesFragment.java
index 08a656e4..34127013 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedCategoriesFragment.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedCategoriesFragment.java
@@ -62,9 +62,9 @@ public class FeedCategoriesFragment extends BaseFeedlistFragment implements OnIt
params.put("op", "getCategories");
params.put("sid", sessionId);
params.put("enable_nested", "true");
- if (unreadOnly) {
- params.put("unread_only", String.valueOf(unreadOnly));
- }
+
+ if (unreadOnly)
+ params.put("unread_only", "true");
return new ApiLoader(getContext(), params);
}
@@ -288,7 +288,7 @@ public class FeedCategoriesFragment extends BaseFeedlistFragment implements OnIt
m_list = view.findViewById(R.id.feeds);
m_adapter = new FeedCategoryListAdapter(getActivity(), R.layout.feeds_row, m_cats);
- initDrawerHeader(inflater, view, m_list, m_activity, m_prefs, true);
+ initDrawerHeader(inflater, view, m_list, m_activity, m_prefs);
m_list.setAdapter(m_adapter);
m_list.setOnItemClickListener(this);
@@ -312,7 +312,7 @@ public class FeedCategoriesFragment extends BaseFeedlistFragment implements OnIt
public void onResume() {
super.onResume();
- LoaderManager.getInstance(this).initLoader(0, null, this).forceLoad();
+ LoaderManager.getInstance(this).initLoader(Application.LOADER_CATS, null, this).forceLoad();
m_activity.invalidateOptionsMenu();
}
@@ -324,7 +324,7 @@ public class FeedCategoriesFragment extends BaseFeedlistFragment implements OnIt
if (m_swipeLayout != null)
m_swipeLayout.setRefreshing(true);
- LoaderManager.getInstance(this).restartLoader(0, null, this).forceLoad();
+ LoaderManager.getInstance(this).restartLoader(Application.LOADER_CATS, null, this).forceLoad();
}
private class FeedCategoryListAdapter extends ArrayAdapter<FeedCategory> {
@@ -376,10 +376,7 @@ public class FeedCategoriesFragment extends BaseFeedlistFragment implements OnIt
ImageView icon = v.findViewById(R.id.icon);
if (icon != null) {
- TypedValue tv = new TypedValue();
-
- m_activity.getTheme().resolveAttribute(R.attr.ic_folder_outline, tv, true);
- icon.setImageResource(tv.resourceId);
+ icon.setImageResource(R.drawable.baseline_folder_open_24);
}
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 495180bb..c198343d 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
@@ -327,7 +327,7 @@ public class FeedsFragment extends BaseFeedlistFragment implements OnItemClickLi
m_list = view.findViewById(R.id.feeds);
- initDrawerHeader(inflater, view, m_list, m_activity, m_prefs, !m_enableParentBtn);
+ initDrawerHeader(inflater, view, m_list, m_activity, m_prefs);
if (m_enableParentBtn) {
View layout = inflater.inflate(R.layout.feeds_goback, m_list, false);
@@ -366,7 +366,7 @@ public class FeedsFragment extends BaseFeedlistFragment implements OnItemClickLi
public void onResume() {
super.onResume();
- LoaderManager.getInstance(this).initLoader(0, null, this).forceLoad();
+ LoaderManager.getInstance(this).initLoader(Application.LOADER_FEEDS, null, this).forceLoad();
m_activity.invalidateOptionsMenu();
}
@@ -404,7 +404,7 @@ public class FeedsFragment extends BaseFeedlistFragment implements OnItemClickLi
m_swipeLayout.setRefreshing(true);
}
- LoaderManager.getInstance(this).restartLoader(0, null, this).forceLoad();
+ LoaderManager.getInstance(this).restartLoader(Application.LOADER_FEEDS, null, this).forceLoad();
}
private class FeedListAdapter extends ArrayAdapter<Feed> {
@@ -462,34 +462,23 @@ public class FeedsFragment extends BaseFeedlistFragment implements OnItemClickLi
ImageView icon = v.findViewById(R.id.icon);
if (icon != null) {
- TypedValue tv = new TypedValue();
-
if (feed.id == 0 && !feed.is_cat) {
- m_activity.getTheme().resolveAttribute(R.attr.ic_archive, tv, true);
- icon.setImageResource(tv.resourceId);
+ icon.setImageResource(R.drawable.baseline_archive_24);
} else if (feed.id == -1 && !feed.is_cat) {
- m_activity.getTheme().resolveAttribute(R.attr.ic_star, tv, true);
- icon.setImageResource(tv.resourceId);
+ icon.setImageResource(R.drawable.baseline_star_24);
} else if (feed.id == -2 && !feed.is_cat) {
- m_activity.getTheme().resolveAttribute(R.attr.ic_rss_box, tv, true);
- icon.setImageResource(tv.resourceId);
+ icon.setImageResource(R.drawable.rss);
} else if (feed.id == -3 && !feed.is_cat) {
- m_activity.getTheme().resolveAttribute(R.attr.ic_fresh, tv, true);
- icon.setImageResource(tv.resourceId);
+ icon.setImageResource(R.drawable.baseline_local_fire_department_24);
} else if (feed.id == -4 && !feed.is_cat) {
- m_activity.getTheme().resolveAttribute(R.attr.ic_inbox, tv, true);
- icon.setImageResource(tv.resourceId);
+ icon.setImageResource(R.drawable.baseline_inbox_24);
} else if (feed.id == -6 && !feed.is_cat) {
- m_activity.getTheme().resolveAttribute(R.attr.ic_restore, tv, true);
- icon.setImageResource(tv.resourceId);
+ icon.setImageResource(R.drawable.baseline_restore_24);
} else if (feed.is_cat) {
- m_activity.getTheme().resolveAttribute(R.attr.ic_folder_outline, tv, true);
- icon.setImageResource(tv.resourceId);
+ icon.setImageResource(R.drawable.baseline_folder_open_24);
} else {
- m_activity.getTheme().resolveAttribute(R.attr.ic_rss_box, tv, true);
- icon.setImageResource(tv.resourceId);
+ icon.setImageResource(R.drawable.rss);
}
-
}
TextView tt = v.findViewById(R.id.title);
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesEventListener.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesEventListener.java
index 5494bb2b..27e00bbf 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesEventListener.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesEventListener.java
@@ -4,7 +4,7 @@ import org.fox.ttrss.types.Article;
import org.fox.ttrss.types.ArticleList;
public interface HeadlinesEventListener {
- void onArticleListSelectionChange(ArticleList m_selectedArticles);
+ void onArticleListSelectionChange();
void onArticleSelected(Article article);
void onArticleSelected(Article article, boolean open);
void onHeadlinesLoaded(boolean appended);
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java
index ad023a7e..fbcf0b4c 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java
@@ -1,6 +1,5 @@
package org.fox.ttrss;
-import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
@@ -15,6 +14,7 @@ import android.media.MediaPlayer;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
@@ -46,11 +46,13 @@ import android.widget.TextView;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
+import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -65,14 +67,13 @@ import com.bumptech.glide.request.target.Target;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
-import com.google.gson.JsonElement;
import org.fox.ttrss.glide.ProgressTarget;
import org.fox.ttrss.types.Article;
import org.fox.ttrss.types.ArticleList;
import org.fox.ttrss.types.Attachment;
import org.fox.ttrss.types.Feed;
-import org.fox.ttrss.util.HeadlinesRequest;
+import org.fox.ttrss.util.ArticleDiffItemCallback;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
@@ -81,11 +82,19 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.TimeZone;
+import java.util.stream.Collectors;
import jp.wasabeef.glide.transformations.CropCircleTransformation;
public class HeadlinesFragment extends androidx.fragment.app.Fragment {
+ private boolean m_isLazyLoading;
+
+ public void notifyItemChanged(int position) {
+ if (m_adapter != null)
+ m_adapter.notifyItemChanged(position);
+ }
+
public enum ArticlesSelection { ALL, NONE, UNREAD }
public static final int FLAVOR_IMG_MIN_SIZE = 128;
@@ -96,9 +105,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
private Feed m_feed;
private int m_activeArticleId;
private String m_searchQuery = "";
- private boolean m_refreshInProgress = false;
- private int m_firstId = 0;
- private boolean m_lazyLoadDisabled = false;
private SharedPreferences m_prefs;
@@ -114,14 +120,12 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
private MediaPlayer m_mediaPlayer;
private TextureView m_activeTexture;
- public ArticleList getSelectedArticles() {
- ArticleList tmp = new ArticleList();
-
- for (Article a : Application.getArticles()) {
- if (a.selected) tmp.add(a);
- }
+ protected static HashMap<Integer, Integer> m_flavorHeightsCache = new HashMap<>();
- return tmp;
+ public ArticleList getSelectedArticles() {
+ return Application.getArticles()
+ .stream()
+ .filter(a -> a.selected).collect(Collectors.toCollection(ArticleList::new));
}
public void initialize(Feed feed) {
@@ -186,19 +190,24 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
private void catchupAbove(Article article) {
ArticleList tmp = new ArticleList();
- for (Article a : Application.getArticles()) {
+ ArticleList articles = Application.getArticles();
+ for (Article a : articles) {
if (article.equalsById(a))
break;
if (a.unread) {
a.unread = false;
tmp.add(a);
+
+ int position = articles.getPositionById(a.id);
+
+ if (position != -1)
+ m_adapter.notifyItemChanged(position);
}
}
if (!tmp.isEmpty()) {
m_activity.setArticlesUnread(tmp, Article.UPDATE_SET_FALSE);
- m_adapter.notifyDataSetChanged();
}
}
@@ -250,8 +259,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
m_feed = savedInstanceState.getParcelable("m_feed");
m_activeArticleId = savedInstanceState.getInt("m_activeArticleId");
m_searchQuery = savedInstanceState.getString("m_searchQuery");
- m_firstId = savedInstanceState.getInt("m_firstId");
- m_lazyLoadDisabled = savedInstanceState.getBoolean("m_lazyLoadDisabled");
m_compactLayoutMode = savedInstanceState.getBoolean("m_compactLayoutMode");
}
@@ -267,13 +274,12 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
out.putParcelable("m_feed", m_feed);
out.putInt("m_activeArticleId", m_activeArticleId);
out.putString("m_searchQuery", m_searchQuery);
- out.putInt("m_firstId", m_firstId);
- out.putBoolean("m_lazyLoadDisabled", m_lazyLoadDisabled);
out.putBoolean("m_compactLayoutMode", m_compactLayoutMode);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ Log.d(TAG, "onCreateView");
String headlineMode = m_prefs.getString("headline_mode", "HL_DEFAULT");
@@ -287,7 +293,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
m_swipeLayout = view.findViewById(R.id.headlines_swipe_container);
- m_swipeLayout.setOnRefreshListener(() -> refresh(false, true));
+ m_swipeLayout.setOnRefreshListener(() -> refresh(false));
m_list = view.findViewById(R.id.headlines_list);
registerForContextMenu(m_list);
@@ -296,11 +302,14 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
m_list.setLayoutManager(m_layoutManager);
m_list.setItemAnimator(new DefaultItemAnimator());
- m_adapter = new ArticleListAdapter(Application.getArticles());
-
+ m_adapter = new ArticleListAdapter();
m_list.setAdapter(m_adapter);
- if (m_prefs.getBoolean("headlines_swipe_to_dismiss", true) && !m_prefs.getBoolean("headlines_mark_read_scroll", false) ) {
+ if (savedInstanceState == null && Application.getArticles().isEmpty()) {
+ refresh(false);
+ }
+
+ if (m_prefs.getBoolean("headlines_swipe_to_dismiss", true) /*&& !m_prefs.getBoolean("headlines_mark_read_scroll", false) */) {
ItemTouchHelper swipeHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
@@ -345,8 +354,10 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
wasUnread = false;
}
- Application.getArticles().remove(adapterPosition);
- m_adapter.notifyItemRemoved(adapterPosition);
+ ArticleList tmpRemove = new ArticleList(Application.getArticles());
+ tmpRemove.remove(adapterPosition);
+
+ Application.getArticlesModel().update(tmpRemove);
Snackbar.make(m_list, R.string.headline_undo_row_prompt, Snackbar.LENGTH_LONG)
.setAction(getString(R.string.headline_undo_row_button), v -> {
@@ -356,9 +367,10 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
m_activity.saveArticleUnread(article);
}
- Application.getArticles().add(adapterPosition, article);
- m_adapter.notifyItemInserted(adapterPosition);
- m_adapter.notifyItemRangeChanged(adapterPosition, 1);
+ ArticleList tmpInsert = new ArticleList(Application.getArticles());
+ tmpInsert.add(adapterPosition, article);
+
+ Application.getArticlesModel().update(tmpInsert);
}).show();
}
@@ -378,17 +390,22 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
- if (newState == RecyclerView.SCROLL_STATE_IDLE && m_prefs.getBoolean("headlines_mark_read_scroll", false)) {
- if (!m_readArticles.isEmpty()) {
- m_activity.toggleArticlesUnread(m_readArticles);
+ ArticleModel model = Application.getArticlesModel();
+
+ if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+ if (!m_readArticles.isEmpty() && !m_isLazyLoading && !model.isLoading() && m_prefs.getBoolean("headlines_mark_read_scroll", false)) {
+ Log.d(TAG, "marking articles as read, count=" + m_readArticles.size());
- for (Article a : m_readArticles)
+ m_activity.setArticlesUnread(m_readArticles, Article.UPDATE_SET_FALSE);
+
+ for (Article a : m_readArticles) {
a.unread = false;
- if (m_feed != null)
- m_feed.unread -= m_readArticles.size();
+ int position = Application.getArticles().getPositionById(a.id);
- m_adapter.notifyDataSetChanged();
+ if (position != -1)
+ m_adapter.notifyItemChanged(position);
+ }
m_readArticles.clear();
@@ -407,27 +424,33 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
// Log.d(TAG, "onScrolled: FVI=" + firstVisibleItem + " LVI=" + lastVisibleItem);
if (m_prefs.getBoolean("headlines_mark_read_scroll", false)) {
-
for (int i = 0; i < firstVisibleItem; i++) {
try {
Article article = Application.getArticles().get(i);
- if (article.unread && !m_readArticles.contains(article)) {
- Log.d(TAG, "adding to mark read=" + article.title);
-
+ if (article.unread && !m_readArticles.contains(article))
m_readArticles.add(article);
- }
+
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
}
}
- }
- if (!m_refreshInProgress && !m_lazyLoadDisabled && lastVisibleItem >= Application.getArticles().size() - 5) {
- m_refreshInProgress = true;
- new Handler().postDelayed(() -> refresh(true), 100);
+ // Log.d(TAG, "pending to auto mark as read count=" + m_readArticles.size());
}
+ ArticleModel model = Application.getArticlesModel();
+
+ if (dy > 0 && !m_isLazyLoading && !model.isLoading() && model.lazyLoadEnabled() &&
+ lastVisibleItem >= Application.getArticles().size() - 5) {
+
+ Log.d(TAG, "attempting to lazy load more articles...");
+
+ m_isLazyLoading = true;
+
+ // this has to be dispatched delayed, consequent adapter updates are forbidden in scroll handler
+ new Handler().postDelayed(() -> refresh(true), 250);
+ }
}
});
@@ -435,7 +458,60 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
m_activity.setTitle(m_feed.title);
}
- Log.d(TAG, "onCreateView, feed=" + m_feed);
+ ArticleModel model = Application.getArticlesModel();
+
+ // this gets notified on network update
+ model.getUpdatesData().observe(getActivity(), lastUpdate -> {
+ if (lastUpdate > 0) {
+ ArticleList tmp = new ArticleList(model.getArticles().getValue());
+
+ Log.d(TAG, "observed last update=" + lastUpdate + " article count=" + tmp.size());
+
+ if (m_prefs.getBoolean("headlines_mark_read_scroll", false))
+ tmp.add(new Article(Article.TYPE_AMR_FOOTER));
+
+ final boolean appended = model.getAppend();
+
+ m_adapter.submitList(tmp, () -> {
+ if (!appended)
+ m_list.scrollToPosition(0);
+
+ if (m_swipeLayout != null)
+ m_swipeLayout.setRefreshing(false);
+
+ m_isLazyLoading = false;
+
+ m_listener.onHeadlinesLoaded(appended);
+ m_listener.onArticleListSelectionChange();
+ });
+
+ if (model.getFirstIdChanged())
+ Snackbar.make(getView(), R.string.headlines_row_top_changed, Snackbar.LENGTH_LONG)
+ .setAction(R.string.reload, v -> refresh(false)).show();
+
+ if (model.getLastError() == ApiCommon.ApiError.LOGIN_FAILED) {
+ m_activity.login();
+ } else if (model.getLastError() != null && model.getLastError() != ApiCommon.ApiError.SUCCESS) {
+ if (model.getLastErrorMessage() != null) {
+ m_activity.toast(m_activity.getString(model.getErrorMessage()) + "\n" + model.getLastErrorMessage());
+ } else {
+ m_activity.toast(model.getErrorMessage());
+ }
+ }
+ }
+ });
+
+ // loaded articles might get modified for all sorts of reasons
+ model.getArticles().observe(getActivity(), articles -> {
+ Log.d(TAG, "observed article list size=" + articles.size());
+
+ ArticleList tmp = new ArticleList(articles);
+
+ if (m_prefs.getBoolean("headlines_mark_read_scroll", false))
+ tmp.add(new Article(Article.TYPE_AMR_FOOTER));
+
+ m_adapter.submitList(tmp);
+ });
return view;
}
@@ -444,9 +520,12 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
public void onResume() {
super.onResume();
- if (Application.getArticles().isEmpty()) {
- refresh(false);
- } else {
+ Log.d(TAG, "onResume");
+
+ syncToSharedArticles();
+
+ // we only set this in detail activity
+ if (m_activeArticleId > 0) {
Article activeArticle = Application.getArticles().getById(m_activeArticleId);
if (activeArticle != null)
@@ -464,183 +543,21 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
m_listener = (HeadlinesEventListener) activity;
}
- public void refresh(boolean append) {
- refresh(append, false);
- }
-
- public void refresh(final boolean append, boolean userInitiated) {
- Application.getArticles().stripFooters();
- m_adapter.notifyDataSetChanged();
-
- if (!append) m_lazyLoadDisabled = false;
-
- if (m_activity != null && isAdded() && m_feed != null) {
- m_refreshInProgress = true;
-
- if (m_swipeLayout != null) m_swipeLayout.setRefreshing(true);
-
- if (!append) {
- m_activity.getSupportActionBar().show();
- Application.getArticles().clear();
- m_adapter.notifyDataSetChanged();
- } else if (!(m_activity instanceof DetailActivity)) {
- // detail activity does not use footers because it would break 1-to-1 mapping with pager view
- // pager will need to work on a footerless subset of shared article view before this is possible
- Application.getArticles().add(new Article(Article.TYPE_LOADMORE));
- m_adapter.notifyDataSetChanged();
- }
-
- final String sessionId = m_activity.getSessionId();
- final boolean isCat = m_feed.is_cat;
-
- @SuppressLint("StaticFieldLeak") HeadlinesRequest req = new HeadlinesRequest(getActivity().getApplicationContext(), m_activity, Application.getArticles()) {
- @Override
- protected void onPostExecute(JsonElement result) {
- if (isDetached() || !isAdded()) return;
-
- super.onPostExecute(result);
-
- if (m_swipeLayout != null) m_swipeLayout.setRefreshing(false);
-
- m_refreshInProgress = false;
-
- if (result != null) {
-
- // is this needed?
- if (!Application.getArticles().containsId(m_activeArticleId))
- m_activeArticleId = 0;
-
- if (m_firstIdChanged) {
- m_lazyLoadDisabled = true;
-
- Log.d(TAG, "first id changed, disabling lazy load");
-
- // article pager deals with this in tablet landscape view
- if (m_activity.isSmallScreen() || !m_activity.isPortrait()) {
- Snackbar.make(getView(), R.string.headlines_row_top_changed, Snackbar.LENGTH_LONG)
- .setAction(R.string.reload, v -> refresh(false)).show();
- }
- }
-
- if (m_amountLoaded < Integer.parseInt(m_prefs.getString("headlines_request_size", "15"))) {
- // Log.d(TAG, "amount loaded "+m_amountLoaded+" < request size, disabling lazy load");
- m_lazyLoadDisabled = true;
- }
-
- HeadlinesFragment.this.m_firstId = m_firstId;
-
- m_adapter.notifyDataSetChanged();
- m_listener.onHeadlinesLoaded(append);
-
- } else {
- m_lazyLoadDisabled = true;
-
- if (m_lastError == ApiCommon.ApiError.LOGIN_FAILED) {
- m_activity.login(true);
- } else {
- if (m_lastErrorMessage != null) {
- m_activity.toast(getString(getErrorMessage()) + "\n" + m_lastErrorMessage);
- } else {
- m_activity.toast(getErrorMessage());
- }
- }
- }
-
- // detail activity does not use footers (see above)
- if (!(m_activity instanceof DetailActivity)) {
- Application.getArticles().add(new Article(Article.TYPE_AMR_FOOTER));
- m_adapter.notifyDataSetChanged();
- }
- }
- };
-
- final int skip = getSkip(append);
-
- final boolean allowForceUpdate = m_activity.getApiLevel() >= 9 &&
- !m_feed.is_cat && m_feed.id > 0 && !append && userInitiated &&
- skip == 0;
-
- Log.d(TAG, "allowForceUpdate=" + allowForceUpdate + " userInitiated=" + userInitiated + " skip=" + skip);
-
- req.setOffset(skip);
-
- HashMap<String,String> map = new HashMap<>();
- map.put("op", "getHeadlines");
- map.put("sid", sessionId);
- map.put("feed_id", String.valueOf(m_feed.id));
- map.put("show_excerpt", "true");
- map.put("excerpt_length", String.valueOf(CommonActivity.EXCERPT_MAX_LENGTH));
- map.put("show_content", "true");
- map.put("include_attachments", "true");
- map.put("view_mode", m_activity.getViewMode());
- map.put("limit", m_prefs.getString("headlines_request_size", "15"));
- map.put("offset", String.valueOf(0));
- map.put("skip", String.valueOf(skip));
- map.put("include_nested", "true");
- map.put("has_sandbox", "true");
- map.put("order_by", m_activity.getSortMode());
-
- if (m_prefs.getBoolean("enable_image_downsampling", false)) {
- if (m_prefs.getBoolean("always_downsample_images", false) || !m_activity.isWifiConnected()) {
- map.put("resize_width", String.valueOf(m_activity.getResizeWidth()));
- }
- }
-
- if (isCat) map.put("is_cat", "true");
+ public void refresh(final boolean append) {
+ ArticleModel model = Application.getArticlesModel();
- if (allowForceUpdate) {
- map.put("force_update", "true");
- }
-
- if (m_searchQuery != null && !m_searchQuery.isEmpty()) {
- map.put("search", m_searchQuery);
- map.put("search_mode", "");
- map.put("match_on", "both");
- }
-
- if (m_firstId > 0) map.put("check_first_id", String.valueOf(m_firstId));
-
- if (m_activity.getApiLevel() >= 12) {
- map.put("include_header", "true");
- }
-
- Log.d(TAG, "[HP] request more headlines, firstId=" + m_firstId);
-
- req.execute(map);
- }
- }
+ if (!append)
+ m_activeArticleId = -1;
- private int getSkip(boolean append) {
- int skip = 0;
-
- if (append) {
- // adaptive, all_articles, marked, published, unread
- String viewMode = m_activity.getViewMode();
-
- int numUnread = Math.toIntExact(Application.getArticles().getUnreadCount());
- int numAll = Math.toIntExact(Application.getArticles().getSizeWithoutFooters());
-
- if ("marked".equals(viewMode)) {
- skip = numAll;
- } else if ("published".equals(viewMode)) {
- skip = numAll;
- } else if ("unread".equals(viewMode)) {
- skip = numUnread;
- } else if (m_searchQuery != null && !m_searchQuery.isEmpty()) {
- skip = numAll;
- } else if ("adaptive".equals(viewMode)) {
- skip = numUnread > 0 ? numUnread : numAll;
- } else {
- skip = numAll;
- }
- }
+ if (m_swipeLayout != null)
+ m_swipeLayout.setRefreshing(true);
- return skip;
+ model.setSearchQuery(getSearchQuery());
+ model.startLoading(append, m_feed, m_activity.getResizeWidth());
}
static class ArticleViewHolder extends RecyclerView.ViewHolder {
public View view;
- public Article article;
public TextView titleView;
public TextView feedTitleView;
@@ -664,6 +581,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
public TextureView flavorVideoView;
public MaterialButton attachmentsView;
public ProgressTarget<String, GlideDrawable> flavorProgressTarget;
+ int articleId;
public ArticleViewHolder(View v) {
super(v);
@@ -674,7 +592,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
View flavorImage = view.findViewById(R.id.flavor_image);
if (flavorImage != null) {
- article.flavorViewHeight = flavorImage.getMeasuredHeight();
+ HeadlinesFragment.m_flavorHeightsCache.put(articleId, flavorImage.getMeasuredHeight());
}
return true;
@@ -705,6 +623,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
if (flavorImageView != null && flavorImageLoadingBar != null) {
flavorProgressTarget = new FlavorProgressTarget<>(new GlideDrawableImageViewTarget(flavorImageView), flavorImageLoadingBar);
}
+
}
public void clearAnimation() {
@@ -739,15 +658,12 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
}
}
- private class ArticleListAdapter extends RecyclerView.Adapter<ArticleViewHolder> {
- private final ArticleList items;
-
+ private class ArticleListAdapter extends ListAdapter<Article, ArticleViewHolder> {
public static final int VIEW_NORMAL = 0;
public static final int VIEW_UNREAD = 1;
public static final int VIEW_ACTIVE = 2;
public static final int VIEW_ACTIVE_UNREAD = 3;
- public static final int VIEW_LOADMORE = 4;
- public static final int VIEW_AMR_FOOTER = 5;
+ public static final int VIEW_AMR_FOOTER = 4;
public static final int VIEW_COUNT = VIEW_AMR_FOOTER + 1;
@@ -779,9 +695,8 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
return false;
}
- public ArticleListAdapter(ArticleList items) {
- super();
- this.items = items;
+ public ArticleListAdapter() {
+ super(new ArticleDiffItemCallback());
Display display = m_activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
@@ -803,9 +718,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
case VIEW_AMR_FOOTER:
layoutId = R.layout.headlines_footer;
break;
- case VIEW_LOADMORE:
- layoutId = R.layout.headlines_row_loadmore;
- break;
case VIEW_UNREAD:
layoutId = m_compactLayoutMode ? R.layout.headlines_row_compact_unread : R.layout.headlines_row_unread;
break;
@@ -826,12 +738,12 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
@Override
public void onBindViewHolder(final ArticleViewHolder holder, int position) {
- holder.article = items.get(position);
-
int headlineFontSize = m_prefs.getInt("headlines_font_size_sp_int", 13);
int headlineSmallFontSize = Math.max(10, Math.min(18, headlineFontSize - 2));
- final Article article = holder.article;
+ Article article = getItem(position);
+
+ holder.articleId = article.id;
if (article.id == Article.TYPE_AMR_FOOTER && m_prefs.getBoolean("headlines_mark_read_scroll", false)) {
WindowManager wm = (WindowManager) m_activity.getSystemService(Context.WINDOW_SERVICE);
@@ -854,9 +766,10 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
// only set active article when it makes sense (in DetailActivity)
if (getActivity() instanceof DetailActivity) {
- m_activeArticleId = article.id;
- m_adapter.notifyDataSetChanged();
- }
+ m_activeArticleId = article.id;
+
+ m_adapter.notifyItemChanged(position);
+ }
});
// block footer clicks to make button/selection clicking easier
@@ -867,18 +780,18 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
}
if (holder.textImage != null) {
- updateTextCheckedState(holder, article);
+ updateTextCheckedState(holder, position);
holder.textImage.setOnClickListener(view -> {
- Log.d(TAG, "textImage : onclicked");
+ Article selectedArticle = getItem(position);
- article.selected = !article.selected;
+ Log.d(TAG, "textImage onClick pos=" + position + " article=" + article);
- updateTextCheckedState(holder, article);
+ selectedArticle.selected = !selectedArticle.selected;
- m_listener.onArticleListSelectionChange(getSelectedArticles());
+ updateTextCheckedState(holder, position);
- Log.d(TAG, "num selected: " + getSelectedArticles().size());
+ m_listener.onArticleListSelectionChange();
});
ViewCompat.setTransitionName(holder.textImage, "gallery:" + article.flavorImageUri);
@@ -915,47 +828,40 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
TypedValue tvTertiary = new TypedValue();
m_activity.getTheme().resolveAttribute(R.attr.colorTertiary, tvTertiary, true);
+ ColorStateList colorTertiary = ColorStateList.valueOf(ContextCompat.getColor(m_activity, tvTertiary.resourceId));
+
TypedValue tvPrimary = new TypedValue();
m_activity.getTheme().resolveAttribute(R.attr.colorPrimary, tvPrimary, true);
- if (holder.markedView != null) {
- TypedValue tv = new TypedValue();
- m_activity.getTheme().resolveAttribute(article.marked ? R.attr.ic_star : R.attr.ic_star_outline, tv, true);
-
- holder.markedView.setIconResource(tv.resourceId);
+ ColorStateList colorPrimary = ColorStateList.valueOf(ContextCompat.getColor(m_activity, tvPrimary.resourceId));
-
- if (article.marked)
- holder.markedView.setIconTint(ColorStateList.valueOf(tvTertiary.data));
- else
- holder.markedView.setIconTint(ColorStateList.valueOf(tvPrimary.data));
+ if (holder.markedView != null) {
+ holder.markedView.setIconResource(article.marked ? R.drawable.baseline_star_24 : R.drawable.baseline_star_outline_24);
+ holder.markedView.setIconTint(article.marked ? colorTertiary : colorPrimary);
holder.markedView.setOnClickListener(v -> {
- article.marked = !article.marked;
-
- m_adapter.notifyItemChanged(m_list.getChildAdapterPosition(holder.view));
+ Article selectedArticle = new Article(getItem(position));
+ selectedArticle.marked = !selectedArticle.marked;
- m_activity.saveArticleMarked(article);
+ m_activity.saveArticleMarked(selectedArticle);
+ Application.getArticlesModel().update(position, selectedArticle);
});
}
if (holder.scoreView != null) {
- TypedValue tv = new TypedValue();
- int scoreAttr = R.attr.ic_action_trending_flat;
+ int scoreDrawable = R.drawable.baseline_trending_flat_24;
if (article.score > 0)
- scoreAttr = R.attr.ic_action_trending_up;
+ scoreDrawable = R.drawable.baseline_trending_up_24;
else if (article.score < 0)
- scoreAttr = R.attr.ic_action_trending_down;
+ scoreDrawable = R.drawable.baseline_trending_down_24;
- m_activity.getTheme().resolveAttribute(scoreAttr, tv, true);
-
- holder.scoreView.setIconResource(tv.resourceId);
+ holder.scoreView.setIconResource(scoreDrawable);
if (article.score > Article.SCORE_HIGH)
- holder.scoreView.setIconTint(ColorStateList.valueOf(tvTertiary.data));
+ holder.scoreView.setIconTint(colorTertiary);
else
- holder.scoreView.setIconTint(ColorStateList.valueOf(tvPrimary.data));
+ holder.scoreView.setIconTint(colorPrimary);
if (m_activity.getApiLevel() >= 16) {
holder.scoreView.setOnClickListener(v -> {
@@ -985,21 +891,21 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
}
if (holder.publishedView != null) {
- TypedValue tv = new TypedValue();
- m_activity.getTheme().resolveAttribute(R.attr.ic_rss_box, tv, true);
- holder.publishedView.setIconResource(tv.resourceId);
+ // otherwise we just use tinting in actionbar
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+ holder.publishedView.setIconResource(article.published ? R.drawable.rss_box : R.drawable.rss);
+ }
- if (article.published)
- holder.publishedView.setIconTint(ColorStateList.valueOf(tvTertiary.data));
- else
- holder.publishedView.setIconTint(ColorStateList.valueOf(tvPrimary.data));
+ holder.publishedView.setIconTint(article.published ? colorTertiary : colorPrimary);
holder.publishedView.setOnClickListener(v -> {
- article.published = !article.published;
- m_adapter.notifyItemChanged(m_list.getChildAdapterPosition(holder.view));
+ Article selectedArticle = new Article(getItem(position));
+ selectedArticle.published = !selectedArticle.published;
- m_activity.saveArticlePublished(article);
+ m_activity.saveArticlePublished(selectedArticle);
+
+ Application.getArticlesModel().update(position, selectedArticle);
});
}
@@ -1061,6 +967,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
holder.flavorVideoKindView.setVisibility(View.GONE);
holder.flavorImageOverflow.setVisibility(View.GONE);
holder.flavorVideoView.setVisibility(View.GONE);
+ holder.flavorImageHolder.setVisibility(View.GONE);
Glide.clear(holder.flavorImageView);
@@ -1124,10 +1031,17 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
holder.flavorImageView.setVisibility(View.VISIBLE);
holder.flavorImageView.setMaxHeight((int)(m_screenHeight * 0.6f));
+ // only show holder if we're about to display a picture
+ holder.flavorImageHolder.setVisibility(View.VISIBLE);
+
// prevent lower listiew entries from jumping around if this row is modified
- if (article.flavorViewHeight > 0) {
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) holder.flavorImageView.getLayoutParams();
- lp.height = article.flavorViewHeight;
+ if (m_flavorHeightsCache.containsKey(article.id)) {
+ int cachedHeight = m_flavorHeightsCache.get(article.id);
+
+ if (cachedHeight > 0) {
+ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) holder.flavorImageView.getLayoutParams();
+ lp.height = cachedHeight;
+ }
}
holder.flavorProgressTarget.setModel(article.flavorImageUri);
@@ -1320,18 +1234,19 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
if (holder.selectionBoxView != null) {
holder.selectionBoxView.setChecked(article.selected);
holder.selectionBoxView.setOnClickListener(view -> {
- CheckBox cb = (CheckBox)view;
+ Article currentArticle = getItem(position);
- article.selected = cb.isChecked();
+ Log.d(TAG, "selectionCb onClick pos=" + position + " article=" + article);
+
+ CheckBox cb = (CheckBox)view;
- m_listener.onArticleListSelectionChange(getSelectedArticles());
+ currentArticle.selected = cb.isChecked();
- Log.d(TAG, "num selected: " + getSelectedArticles().size());
+ m_listener.onArticleListSelectionChange();
});
}
if (holder.menuButtonView != null) {
-
holder.menuButtonView.setOnClickListener(v -> {
PopupMenu popup = new PopupMenu(getActivity(), v);
@@ -1341,7 +1256,8 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
popup.getMenu().findItem(R.id.article_set_labels).setEnabled(m_activity.getApiLevel() >= 1);
popup.getMenu().findItem(R.id.article_edit_note).setEnabled(m_activity.getApiLevel() >= 1);
- popup.setOnMenuItemClickListener(item -> onArticleMenuItemSelected(item, article,
+ popup.setOnMenuItemClickListener(item -> onArticleMenuItemSelected(item,
+ getItem(position),
m_list.getChildAdapterPosition(holder.view)));
popup.show();
@@ -1351,12 +1267,10 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
@Override
public int getItemViewType(int position) {
- Article a = items.get(position);
+ Article a = getItem(position);
if (a.id == Article.TYPE_AMR_FOOTER) {
return VIEW_AMR_FOOTER;
- } else if (a.id == Article.TYPE_LOADMORE) {
- return VIEW_LOADMORE;
} else if (a.id == m_activeArticleId && a.unread) {
return VIEW_ACTIVE_UNREAD;
} else if (a.id == m_activeArticleId) {
@@ -1368,12 +1282,9 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
}
}
- @Override
- public int getItemCount() {
- return items.size();
- }
+ private void updateTextCheckedState(final ArticleViewHolder holder, int position) {
+ Article article = getItem(position);
- private void updateTextCheckedState(final ArticleViewHolder holder, final Article article) {
String tmp = !article.title.isEmpty() ? article.title.substring(0, 1).toUpperCase() : "?";
if (article.selected) {
@@ -1508,47 +1419,60 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
}
}
- public void notifyUpdated() {
- m_adapter.notifyDataSetChanged();
- }
-
public void scrollToArticle(Article article) {
scrollToArticleId(article.id);
}
public void scrollToArticleId(int id) {
- m_list.scrollToPosition(Application.getArticles().getPositionById(id));
+ int position = Application.getArticles().getPositionById(id);
+
+ if (position != -1)
+ m_list.scrollToPosition(position);
}
public void setActiveArticleId(int articleId) {
if (m_list != null && articleId != m_activeArticleId) {
+ ArticleList articles = Application.getArticles();
+
+ int oldPosition = articles.getPositionById(m_activeArticleId);
+ int newPosition = articles.getPositionById(articleId);
+
m_activeArticleId = articleId;
- m_adapter.notifyDataSetChanged();
+
+ if (oldPosition != -1)
+ m_adapter.notifyItemChanged(oldPosition);
+
+ m_adapter.notifyItemChanged(newPosition);
scrollToArticleId(articleId);
+
+ if (newPosition >= articles.size() - 5)
+ new Handler().postDelayed(() -> refresh(true), 0);
}
}
public void setSelection(ArticlesSelection select) {
- for (Article a : Application.getArticles())
- a.selected = false;
+ ArticleList articlesWithoutFooters = Application.getArticles().getWithoutFooters();
- if (select != ArticlesSelection.NONE) {
- for (Article a : Application.getArticles()) {
- if (select == ArticlesSelection.ALL || select == ArticlesSelection.UNREAD && a.unread) {
- a.selected = true;
- }
- }
- }
+ for (Article a : articlesWithoutFooters) {
+ if (select == ArticlesSelection.ALL || select == ArticlesSelection.UNREAD && a.unread) {
+ a.selected = true;
- if (m_adapter != null) {
- m_adapter.notifyDataSetChanged();
- }
- }
+ int position = Application.getArticles().getPositionById(a.id);
+
+ if (position != -1)
+ m_adapter.notifyItemChanged(position);
+
+ } else if (a.selected) {
+ a.selected = false;
+
+ int position = Application.getArticles().getPositionById(a.id);
- public int getActiveArticleId() {
- return m_activeArticleId;
+ if (position != -1)
+ m_adapter.notifyItemChanged(position);
+ }
+ }
}
public String getSearchQuery() {
@@ -1559,10 +1483,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
if (!m_searchQuery.equals(query)) {
m_searchQuery = query;
- // could be called before fragment view has been initialized
- if (m_list != null) {
- refresh(false);
- }
+ refresh(false);
}
}
@@ -1577,4 +1498,15 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
releaseSurface();
}
+ private void syncToSharedArticles() {
+ ArticleList tmp = new ArticleList();
+
+ tmp.addAll(Application.getArticles());
+
+ if (m_prefs.getBoolean("headlines_mark_read_scroll", false))
+ tmp.add(new Article(Article.TYPE_AMR_FOOTER));
+
+ m_adapter.submitList(tmp);
+ }
+
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java
index 9430ddc2..458f1f76 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java
@@ -164,7 +164,7 @@ public class MasterActivity extends OnlineActivity implements HeadlinesEventList
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- if (m_prefs.getBoolean("enable_cats", false)) {
+ if (m_prefs.getBoolean("enable_cats", true)) {
ft.replace(R.id.feeds_fragment, new FeedCategoriesFragment(), FRAG_CATS);
} else {
ft.replace(R.id.feeds_fragment, new FeedsFragment(), FRAG_FEEDS);
@@ -445,7 +445,7 @@ public class MasterActivity extends OnlineActivity implements HeadlinesEventList
}
@Override
- public void onArticleListSelectionChange(ArticleList m_selectedArticles) {
+ public void onArticleListSelectionChange() {
invalidateOptionsMenu();
}
@@ -476,7 +476,7 @@ public class MasterActivity extends OnlineActivity implements HeadlinesEventList
// we use shared article list, but detail activity does not use special footers
// we will append those back (if needed) in onActivityResult()
- Application.getArticles().stripFooters();
+ // Application.getArticles().stripFooters();
startActivityForResult(intent, HEADLINES_REQUEST);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
@@ -520,19 +520,19 @@ public class MasterActivity extends OnlineActivity implements HeadlinesEventList
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == HEADLINES_REQUEST) {
-
- // we add back footers stripped when this was passed to DetailActivity
- Application.getArticles().add(new Article(Article.TYPE_AMR_FOOTER));
+ Log.d(TAG, "onActivityResult:" + requestCode + " "+ resultCode + " " + data);
+ if (requestCode == HEADLINES_REQUEST) {
HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
if (hf != null) {
- hf.notifyUpdated();
+ // data might be null if detailactivity crashed
+ if (data != null) {
+ int activeArticleId = data.getIntExtra("activeArticleId", 0);
- // this makes position in headlines in master activity (not quite) randomly jump around when returning
- // even if active article hasn't been changed, i guess keeping it as-is is a lesser evil?
- hf.scrollToArticleId(data.getIntExtra("activeArticleId", 0));
+ Log.d(TAG, "got back from detail activity, scrolling to id=" + activeArticleId);
+ hf.scrollToArticleId(activeArticleId);
+ }
}
}
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java
index 92a3f219..ffca776b 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java
@@ -5,12 +5,15 @@ import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.res.ColorStateList;
import android.graphics.Point;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.util.Log;
+import android.util.TypedValue;
import android.view.Display;
import android.view.KeyEvent;
import android.view.Menu;
@@ -23,6 +26,7 @@ import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.view.ActionMode;
import androidx.appcompat.widget.Toolbar;
+import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@@ -391,6 +395,7 @@ public class OnlineActivity extends CommonActivity {
} else if (itemId == R.id.search) {
if (hf != null) {
final EditText edit = new EditText(this);
+ edit.setText(hf.getSearchQuery());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this)
.setTitle(R.string.search)
@@ -561,28 +566,37 @@ public class OnlineActivity extends CommonActivity {
if (ap != null) {
Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId());
- if (selectedArticle != null)
- setArticleScore(selectedArticle);
+ if (selectedArticle != null) {
+ setArticleScore(selectedArticle);
+
+ hf.notifyItemChanged(Application.getArticles().indexOf(selectedArticle));
+ }
}
return true;
} else if (itemId == R.id.toggle_marked) {
if (ap != null) {
Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId());
- selectedArticle.marked = !selectedArticle.marked;
- saveArticleMarked(selectedArticle);
+ if (selectedArticle != null) {
+ selectedArticle.marked = !selectedArticle.marked;
+
+ saveArticleMarked(selectedArticle);
- if (hf != null) hf.notifyUpdated();
+ hf.notifyItemChanged(Application.getArticles().indexOf(selectedArticle));
+ }
}
return true;
} else if (itemId == R.id.toggle_unread) {
if (ap != null) {
Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId());
- selectedArticle.unread = !selectedArticle.unread;
- saveArticleUnread(selectedArticle);
+ if (selectedArticle != null) {
+ selectedArticle.unread = !selectedArticle.unread;
+
+ saveArticleUnread(selectedArticle);
- if (hf != null) hf.notifyUpdated();
+ hf.notifyItemChanged(Application.getArticles().indexOf(selectedArticle));
+ }
}
return true;
} else if (itemId == R.id.selection_toggle_unread) {
@@ -590,11 +604,13 @@ public class OnlineActivity extends CommonActivity {
ArticleList selected = hf.getSelectedArticles();
if (!selected.isEmpty()) {
- for (Article a : selected)
+ for (Article a : selected) {
a.unread = !a.unread;
+ hf.notifyItemChanged(Application.getArticles().indexOf(a));
+ }
+
toggleArticlesUnread(selected);
- hf.notifyUpdated();
invalidateOptionsMenu();
}
}
@@ -604,11 +620,13 @@ public class OnlineActivity extends CommonActivity {
ArticleList selected = hf.getSelectedArticles();
if (!selected.isEmpty()) {
- for (Article a : selected)
+ for (Article a : selected) {
a.marked = !a.marked;
+ hf.notifyItemChanged(Application.getArticles().indexOf(a));
+ }
+
toggleArticlesMarked(selected);
- hf.notifyUpdated();
invalidateOptionsMenu();
}
}
@@ -618,24 +636,26 @@ public class OnlineActivity extends CommonActivity {
ArticleList selected = hf.getSelectedArticles();
if (!selected.isEmpty()) {
- for (Article a : selected)
+ for (Article a : selected) {
a.published = !a.published;
+ hf.notifyItemChanged(Application.getArticles().indexOf(a));
+ }
+
toggleArticlesPublished(selected);
- hf.notifyUpdated();
invalidateOptionsMenu();
}
}
return true;
} else if (itemId == R.id.toggle_published) {
- if (ap != null) {
+ if (ap != null && hf != null) {
Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId());
if (selectedArticle != null) {
selectedArticle.published = !selectedArticle.published;
saveArticlePublished(selectedArticle);
- if (hf != null) hf.notifyUpdated();
+ hf.notifyItemChanged(Application.getArticles().indexOf(selectedArticle));
}
}
return true;
@@ -688,12 +708,17 @@ public class OnlineActivity extends CommonActivity {
if (a.unread) {
a.unread = false;
tmp.add(a);
+
+ if (hf != null) {
+ int position = Application.getArticles().indexOf(a);
+
+ hf.notifyItemChanged(position);
+ }
}
}
if (!tmp.isEmpty()) {
setArticlesUnread(tmp, Article.UPDATE_SET_FALSE);
- hf.notifyUpdated();
invalidateOptionsMenu();
}
}
@@ -713,11 +738,15 @@ public class OnlineActivity extends CommonActivity {
saveArticleNote(article, note);
- HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
- if (hf != null) hf.notifyUpdated();
+ int position = Application.getArticles().getPositionById(article.id);
+
+ if (position != -1) {
+ HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+ if (hf != null) hf.notifyItemChanged(position);
- ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
- if (ap != null) ap.notifyUpdated();
+ ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
+ if (ap != null) ap.notifyItemChanged(position);
+ }
});
builder.setNegativeButton(R.string.dialog_cancel, (dialog, which) -> {
@@ -839,7 +868,8 @@ public class OnlineActivity extends CommonActivity {
protected void setApiLevel(int apiLevel) {
Application.getInstance().setApiLevel(apiLevel);
}
-
+
+ // TODO switch to setArticleField()
public void saveArticleUnread(final Article article) {
ApiRequest req = new ApiRequest(getApplicationContext()) {
protected void onPostExecute(JsonElement result) {
@@ -853,11 +883,12 @@ public class OnlineActivity extends CommonActivity {
map.put("op", "updateArticle");
map.put("article_ids", String.valueOf(article.id));
map.put("mode", article.unread ? "1" : "0");
- map.put("field", "2");
+ map.put("field", String.valueOf(Article.UPDATE_FIELD_UNREAD));
req.execute(map);
}
+ // TODO switch to setArticleField()
public void saveArticleScore(final Article article) {
ApiRequest req = new ApiRequest(getApplicationContext()) {
protected void onPostExecute(JsonElement result) {
@@ -871,11 +902,12 @@ public class OnlineActivity extends CommonActivity {
map.put("op", "updateArticle");
map.put("article_ids", String.valueOf(article.id));
map.put("data", String.valueOf(article.score));
- map.put("field", "4");
+ map.put("field", String.valueOf(Article.UPDATE_FIELD_SCORE));
req.execute(map);
}
+ // TODO switch to setArticleField()
public void saveArticleMarked(final Article article) {
ApiRequest req = new ApiRequest(getApplicationContext()) {
protected void onPostExecute(JsonElement result) {
@@ -889,11 +921,12 @@ public class OnlineActivity extends CommonActivity {
map.put("op", "updateArticle");
map.put("article_ids", String.valueOf(article.id));
map.put("mode", article.marked ? "1" : "0");
- map.put("field", "0");
+ map.put("field", String.valueOf(Article.UPDATE_FIELD_MARKED));
req.execute(map);
}
+ // TODO switch to setArticleField()
public void saveArticlePublished(final Article article) {
ApiRequest req = new ApiRequest(getApplicationContext()) {
@@ -908,11 +941,12 @@ public class OnlineActivity extends CommonActivity {
map.put("op", "updateArticle");
map.put("article_ids", String.valueOf(article.id));
map.put("mode", article.published ? "1" : "0");
- map.put("field", "1");
+ map.put("field", String.valueOf(Article.UPDATE_FIELD_PUBLISHED));
req.execute(map);
}
+ // TODO switch to setArticleField()
public void saveArticleNote(final Article article, final String note) {
ApiRequest req = new ApiRequest(getApplicationContext()) {
protected void onPostExecute(JsonElement result) {
@@ -926,7 +960,7 @@ public class OnlineActivity extends CommonActivity {
map.put("article_ids", String.valueOf(article.id));
map.put("mode", "1");
map.put("data", note);
- map.put("field", "3");
+ map.put("field", String.valueOf(Article.UPDATE_FIELD_NOTE));
req.execute(map);
}
@@ -1005,7 +1039,8 @@ article.score = Integer.parseInt(edit.getText().toString());
if (selectedArticle != null) {
selectedArticle.unread = !selectedArticle.unread;
saveArticleUnread(selectedArticle);
- if (hf != null) hf.notifyUpdated();
+
+ hf.notifyItemChanged(Application.getArticles().indexOf(selectedArticle));
}
}
return true;
@@ -1081,8 +1116,6 @@ article.score = Integer.parseInt(edit.getText().toString());
}
public void setArticlesUnread(final ArticleList articles, int mode) {
- ApiRequest req = new ApiRequest(getApplicationContext());
-
setArticleField(articles, Article.UPDATE_FIELD_UNREAD, mode);
}
@@ -1099,11 +1132,19 @@ article.score = Integer.parseInt(edit.getText().toString());
protected void onPostExecute(JsonElement result) {
Log.d(TAG, "setArticleField operation complete");
- HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
- if (hf != null) hf.notifyUpdated();
+ // currently this is generally handled before operation completes (but after POJO is modified)
+ /* HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
- if (ap != null) ap.notifyUpdated();
+
+ for (Article a : articles) {
+ int position = Application.getArticles().getPositionById(a.id);
+
+ if (position != -1) {
+ if (hf != null) hf.notifyItemChanged(position);
+ if (ap != null) ap.notifyItemChanged(position);
+ }
+ } */
}
};
@@ -1144,11 +1185,30 @@ article.score = Integer.parseInt(edit.getText().toString());
Article article = Application.getArticles().getById(ap.getSelectedArticleId());
if (article != null) {
+
m_menu.findItem(R.id.toggle_marked).setIcon(article.marked ? R.drawable.baseline_star_24 :
R.drawable.baseline_star_outline_24);
- m_menu.findItem(R.id.toggle_published).setIcon(article.published ? R.drawable.baseline_check_box_24 :
- R.drawable.baseline_rss_feed_24);
+ // TODO we probably shouldn't do this all the time
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ TypedValue tvTertiary = new TypedValue();
+ getTheme().resolveAttribute(R.attr.colorTertiary, tvTertiary, true);
+
+ ColorStateList colorStateTertiary = ColorStateList.valueOf(ContextCompat.getColor(this, tvTertiary.resourceId));
+
+ TypedValue tvNormal = new TypedValue();
+ getTheme().resolveAttribute(R.attr.colorControlNormal, tvNormal, true);
+
+ ColorStateList colorStateNormal = ColorStateList.valueOf(ContextCompat.getColor(this, tvNormal.resourceId));
+
+ m_menu.findItem(R.id.toggle_published).setIconTintList(article.published ? colorStateTertiary : colorStateNormal);
+ m_menu.findItem(R.id.toggle_marked).setIconTintList(article.marked ? colorStateTertiary : colorStateNormal);
+
+ } else {
+ m_menu.findItem(R.id.toggle_published).setIcon(article.published ? R.drawable.rss_box :
+ R.drawable.baseline_rss_feed_24);
+ }
+
}
}
@@ -1189,12 +1249,6 @@ article.score = Integer.parseInt(edit.getText().toString());
if (hf != null) {
hf.refresh(false);
}
-
- ArticlePager af = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
-
- if (af != null) {
- af.refresh(false);
- }
}
}
@@ -1363,15 +1417,6 @@ article.score = Integer.parseInt(edit.getText().toString());
return m_lastImageHitTestUrl;
}
- public boolean isWifiConnected() {
- NetworkInfo wifi = m_cmgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-
- if (wifi != null)
- return wifi.isConnected();
-
- return false;
- }
-
public int getResizeWidth() {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/share/CommonActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/share/CommonActivity.java
index 63458532..9c9187d9 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/share/CommonActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/share/CommonActivity.java
@@ -10,7 +10,6 @@ public class CommonActivity extends Activity {
private final String TAG = this.getClass().getSimpleName();
private boolean m_smallScreenMode = true;
- private boolean m_compatMode = false;
protected void setSmallScreen(boolean smallScreen) {
Log.d(TAG, "m_smallScreenMode=" + smallScreen);
@@ -27,23 +26,10 @@ public class CommonActivity extends Activity {
toast.show();
}
- @Override
- public void onCreate(Bundle savedInstanceState) {
- m_compatMode = android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB;
-
- Log.d(TAG, "m_compatMode=" + m_compatMode);
-
- super.onCreate(savedInstanceState);
- }
-
public boolean isSmallScreen() {
return m_smallScreenMode;
}
- public boolean isCompatMode() {
- return m_compatMode;
- }
-
public boolean isPortrait() {
Display display = getWindowManager().getDefaultDisplay();
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/share/ShareActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/share/ShareActivity.java
index 3a1553b6..66a77aef 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/share/ShareActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/share/ShareActivity.java
@@ -86,7 +86,7 @@ public class ShareActivity extends CommonShareActivity {
protected void onPostExecute(JsonElement result) {
setProgressBarIndeterminateVisibility(false);
- if (m_lastError != ApiCommon.ApiError.NO_ERROR) {
+ if (m_lastError != ApiCommon.ApiError.UNKNOWN_ERROR) {
toast(getErrorMessage());
} else {
toast(R.string.share_article_posted);
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/share/SubscribeActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/share/SubscribeActivity.java
index e71583d3..82e2d52d 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/share/SubscribeActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/share/SubscribeActivity.java
@@ -157,7 +157,7 @@ public class SubscribeActivity extends CommonShareActivity {
protected void onPostExecute(JsonElement result) {
m_progressBar.setVisibility(View.INVISIBLE);
- if (m_lastError != ApiCommon.ApiError.NO_ERROR) {
+ if (m_lastError != ApiCommon.ApiError.UNKNOWN_ERROR) {
toast(getErrorMessage());
} else {
try {
@@ -259,7 +259,7 @@ public class SubscribeActivity extends CommonShareActivity {
protected void onPostExecute(JsonElement result) {
m_progressBar.setVisibility(View.INVISIBLE);
- if (m_lastError != ApiCommon.ApiError.NO_ERROR) {
+ if (m_lastError != ApiCommon.ApiError.UNKNOWN_ERROR) {
toast(getErrorMessage());
} else {
JsonArray content = result.getAsJsonArray();
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java
index 7d476ad6..f0795dd8 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java
@@ -14,7 +14,6 @@ import java.util.regex.Pattern;
// TODO: serialize Labels
public class Article implements Parcelable {
- public static final int TYPE_LOADMORE = -1;
public static final int TYPE_AMR_FOOTER = -2;
public static final int FLAVOR_KIND_ALBUM = 1;
@@ -69,9 +68,8 @@ public class Article implements Parcelable {
transient public String flavorStreamUri;
transient public String youtubeVid;
transient public List<Element> mediaList = new ArrayList<>();
- transient public int flavorViewHeight;
- public Article(Parcel in) {
+ public Article(Parcel in) {
readFromParcel(in);
}
@@ -194,8 +192,44 @@ public class Article implements Parcelable {
public Article(int id) {
this.id = id;
this.title = "ID:" + id;
- this.link = "";
- this.tags = new ArrayList<>();
+ fixNullFields();
+ }
+
+ public Article(Article clone) {
+ id = clone.id;
+ unread = clone.unread;
+ marked = clone.marked;
+ published = clone.published;
+ score = clone.score;
+ updated = clone.updated;
+ is_updated = clone.is_updated;
+ title = clone.title;
+ link = clone.link;
+ feed_id = clone.feed_id;
+ tags = clone.tags;
+ attachments = clone.attachments;
+ content = clone.content;
+ excerpt = clone.excerpt;
+ labels = clone.labels;
+ feed_title = clone.feed_title;
+ comments_count = clone.comments_count;
+ comments_link = clone.comments_link;
+ always_display_attachments = clone.always_display_attachments;
+ author = clone.author;
+ note = clone.note;
+ selected = clone.selected;
+ flavor_image = clone.flavor_image;
+ flavor_stream = clone.flavor_stream;
+ flavor_kind = clone.flavor_kind;
+ site_url = clone.site_url;
+
+ articleDoc = clone.articleDoc;
+ flavorImage = clone.flavorImage;
+
+ flavorImageUri = clone.flavorImageUri;
+ flavorStreamUri = clone.flavorStreamUri;
+ youtubeVid = clone.youtubeVid;
+ mediaList = new ArrayList<>(clone.mediaList);
}
@Override
@@ -262,13 +296,9 @@ public class Article implements Parcelable {
}
public boolean equalsById(Article article) {
- if (article != null && id == article.id) {
- return true;
- } else {
- return false;
- }
+ return article != null && id == article.id;
}
-
+
@SuppressWarnings("rawtypes")
public static final Parcelable.Creator CREATOR =
new Parcelable.Creator() {
@@ -280,4 +310,14 @@ public class Article implements Parcelable {
return new Article[size];
}
};
+
+ /** set fields which might be missing during JSON deserialization to sane values */
+ public void fixNullFields() {
+ if (note == null) note = "";
+ if (link == null) link = "";
+ if (tags == null) tags = new ArrayList<>();
+ if (note == null) note = "";
+ if (excerpt == null) excerpt = "";
+ if (content == null) content = "";
+ }
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java
index 873b311b..6724acb0 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java
@@ -1,8 +1,5 @@
package org.fox.ttrss.types;
-import android.os.Parcel;
-import android.os.Parcelable;
-
import java.util.ListIterator;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
@@ -26,6 +23,10 @@ public class ArticleList extends CopyOnWriteArrayList<Article> {
public ArticleList() { }
+ public ArticleList(ArticleList clone) {
+ this.addAll(clone);
+ }
+
public ArticleList getWithoutFooters() {
return this.stream().filter(a -> { return a.id > 0; }).collect(Collectors.toCollection(ArticleList::new));
}
@@ -34,22 +35,6 @@ public class ArticleList extends CopyOnWriteArrayList<Article> {
return this.stream().filter(a -> { return a.unread; }).count();
}
- public long getSizeWithoutFooters() {
- return this.stream().filter(a -> { return a.id > 0; }).count();
- }
-
- /** strips all trailing items with negative IDs (Article.TYPE_LOADMORE, Article.TYPE_AMR_FOOTER) */
- public void stripFooters() {
- for (ListIterator<Article> iterator = this.listIterator(size()); iterator.hasPrevious();) {
- final Article article = iterator.previous();
-
- if (article.id < 0)
- this.remove(article);
- else
- break;
- }
- }
-
public int getPositionById(int id) {
for (int i = 0; i < size(); i++) {
if (get(i).id == id) {
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ArticleDiffItemCallback.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ArticleDiffItemCallback.java
new file mode 100644
index 00000000..b037eea0
--- /dev/null
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ArticleDiffItemCallback.java
@@ -0,0 +1,21 @@
+package org.fox.ttrss.util;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.DiffUtil;
+
+import org.fox.ttrss.types.Article;
+
+public class ArticleDiffItemCallback extends DiffUtil.ItemCallback<Article> {
+ private final String TAG = this.getClass().getSimpleName();
+ @Override
+ public boolean areItemsTheSame(@NonNull Article a1, @NonNull Article a2) {
+ return a1.id == a2.id;
+ }
+
+ @Override
+ public boolean areContentsTheSame(@NonNull Article a1, @NonNull Article a2) {
+ return a1.id == a2.id && a1.unread == a2.unread && a1.marked == a2.marked
+ && a1.selected == a2.selected && a1.published == a2.published
+ && a1.note.equals(a2.note);
+ }
+}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/DiffFragmentStateAdapter.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/DiffFragmentStateAdapter.java
new file mode 100644
index 00000000..c423b02d
--- /dev/null
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/DiffFragmentStateAdapter.java
@@ -0,0 +1,54 @@
+package org.fox.ttrss.util;
+
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+import androidx.lifecycle.Lifecycle;
+import androidx.recyclerview.widget.AsyncListDiffer;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.viewpager2.adapter.FragmentStateAdapter;
+
+import java.util.List;
+
+// https://gist.github.com/Gnzlt/7e8a23ba0c3b046ed33c824b284d7270
+public abstract class DiffFragmentStateAdapter<T> extends FragmentStateAdapter {
+
+ private final AsyncListDiffer<T> differ;
+
+ protected DiffFragmentStateAdapter(FragmentActivity fragmentActivity, DiffUtil.ItemCallback<T> diffCallback) {
+ super(fragmentActivity);
+ differ = new AsyncListDiffer<>(this, diffCallback);
+ }
+
+ protected DiffFragmentStateAdapter(Fragment fragment, DiffUtil.ItemCallback<T> diffCallback) {
+ super(fragment);
+ differ = new AsyncListDiffer<>(this, diffCallback);
+ }
+
+ protected DiffFragmentStateAdapter(FragmentManager fragmentManager, Lifecycle lifecycle, DiffUtil.ItemCallback<T> diffCallback) {
+ super(fragmentManager, lifecycle);
+ differ = new AsyncListDiffer<>(this, diffCallback);
+ }
+
+ public void submitList(List<T> list, Runnable commitCallback) {
+ differ.submitList(list, commitCallback);
+ }
+
+ public void submitList(List<T> list) {
+ differ.submitList(list, null);
+ }
+
+ public List<T> getCurrentList() {
+ return differ.getCurrentList();
+ }
+
+ protected T getItem(int position) {
+ return differ.getCurrentList().get(position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return differ.getCurrentList().size();
+ }
+}
+
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesRequest.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesRequest.java
deleted file mode 100755
index 82698ffb..00000000
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesRequest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.fox.ttrss.util;
-
-import android.content.Context;
-import android.util.Log;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.reflect.TypeToken;
-
-import org.fox.ttrss.ApiCommon;
-import org.fox.ttrss.ApiRequest;
-import org.fox.ttrss.Application;
-import org.fox.ttrss.OnlineActivity;
-import org.fox.ttrss.types.Article;
-import org.fox.ttrss.types.ArticleList;
-
-import java.lang.reflect.Type;
-import java.util.List;
-
-public class HeadlinesRequest extends ApiRequest {
- private final String TAG = this.getClass().getSimpleName();
-
- private int m_offset = 0;
- private final OnlineActivity m_activity;
- protected boolean m_firstIdChanged = false;
- protected int m_firstId = 0;
- protected int m_amountLoaded = 0;
-
- public HeadlinesRequest(Context context, OnlineActivity activity, ArticleList articles) {
- super(context);
-
- m_activity = activity;
- }
-
- protected void onPostExecute(JsonElement result) {
- if (result != null) {
- try {
- JsonArray content = result.getAsJsonArray();
- if (content != null) {
- final List<Article> articlesJson;
- final JsonObject header;
-
- if (m_activity.getApiLevel() >= 12) {
- header = content.get(0).getAsJsonObject();
-
- //Log.d(TAG, "headerID:" + header.get("top_id_changed"));
-
- m_firstIdChanged = header.get("first_id_changed") != null;
- try {
- m_firstId = header.get("first_id").getAsInt();
- } catch (NumberFormatException e) {
- m_firstId = 0;
- }
-
- Log.d(TAG, "firstID=" + m_firstId + " firstIdChanged=" + m_firstIdChanged);
-
- Type listType = new TypeToken<List<Article>>() {}.getType();
- articlesJson = new Gson().fromJson(content.get(1), listType);
- } else {
- Type listType = new TypeToken<List<Article>>() {}.getType();
- articlesJson = new Gson().fromJson(content, listType);
- }
-
- ArticleList articles = Application.getArticles();
-
- if (m_offset == 0)
- articles.clear();
- else
- articles.stripFooters();
-
- m_amountLoaded = articlesJson.size();
-
- for (Article f : articlesJson)
- if (!articles.containsId(f.id)) {
- f.collectMediaInfo();
- f.cleanupExcerpt();
- articles.add(f);
- }
-
- return;
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- if (m_lastError == ApiCommon.ApiError.LOGIN_FAILED) {
- m_activity.login();
- } else {
-
- if (m_lastErrorMessage != null) {
- m_activity.toast(m_activity.getString(getErrorMessage()) + "\n" + m_lastErrorMessage);
- } else {
- m_activity.toast(getErrorMessage());
- }
- //m_activity.setLoadingStatus(getErrorMessage(), false);
- }
- }
-
- public void setOffset(int skip) {
- m_offset = skip;
- }
-}
diff --git a/org.fox.ttrss/src/main/res/drawable/ic_launcher_background_variant.xml b/org.fox.ttrss/src/main/res/drawable/ic_launcher_background_variant.xml
new file mode 100644
index 00000000..749ffa26
--- /dev/null
+++ b/org.fox.ttrss/src/main/res/drawable/ic_launcher_background_variant.xml
@@ -0,0 +1,42 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="51.06383"
+ android:viewportHeight="51.06383">
+ <group android:translateX="-10.468085"
+ android:translateY="-10.468085">
+ <path
+ android:pathData="M-9.8995,-7.7102h94.3666v92.4381h-94.3666z"
+ android:fillColor="#5c5c5c"
+ android:strokeColor="#00000000"
+ android:fillAlpha="1"/>
+ <path
+ android:pathData="M5.668,58.0128a8.3196,8.3198 0,1 0,16.6393 0a8.3196,8.3198 0,1 0,-16.6393 0z"
+ android:strokeAlpha="1"
+ android:strokeWidth="0.69765961"
+ android:fillColor="#808080"
+ android:strokeColor="#00000000"
+ android:fillAlpha="1"/>
+ <path
+ android:pathData="m45.8796,66.3326 l-11.7862,0A28.4254,28.426 0,0 0,5.668 37.9066l0,-11.7864A40.2116,40.2124 0,0 1,45.8796 66.3326Z"
+ android:strokeAlpha="1"
+ android:strokeWidth="0.69765961"
+ android:fillColor="#808080"
+ android:strokeColor="#00000000"
+ android:fillAlpha="1"/>
+ <path
+ android:pathData="M54.1992,66.3326A48.5312,48.5322 0,0 0,5.668 17.8004l0,-12.1331a60.6653,60.6641 90,0 1,60.6641 60.6653z"
+ android:strokeAlpha="1"
+ android:strokeWidth="2.01254654"
+ android:fillColor="#808080"
+ android:strokeColor="#00000000"
+ android:fillAlpha="1"/>
+ <path
+ android:pathData="M54.1992,66.3326A48.5312,48.5322 0,0 0,5.668 17.8004l0,-12.1331a60.6653,60.6641 90,0 1,60.6641 60.6653z"
+ android:strokeAlpha="1"
+ android:strokeWidth="2.01254654"
+ android:fillColor="#808080"
+ android:strokeColor="#00000000"
+ android:fillAlpha="1"/>
+ </group>
+</vector>
diff --git a/org.fox.ttrss/src/main/res/drawable/rss.xml b/org.fox.ttrss/src/main/res/drawable/rss.xml
new file mode 100644
index 00000000..f97e14a2
--- /dev/null
+++ b/org.fox.ttrss/src/main/res/drawable/rss.xml
@@ -0,0 +1 @@
+<!-- drawable/rss.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M6.18,15.64A2.18,2.18 0 0,1 8.36,17.82C8.36,19 7.38,20 6.18,20C5,20 4,19 4,17.82A2.18,2.18 0 0,1 6.18,15.64M4,4.44A15.56,15.56 0 0,1 19.56,20H16.73A12.73,12.73 0 0,0 4,7.27V4.44M4,10.1A9.9,9.9 0 0,1 13.9,20H11.07A7.07,7.07 0 0,0 4,12.93V10.1Z" /></vector> \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/res/drawable/rss_box.xml b/org.fox.ttrss/src/main/res/drawable/rss_box.xml
new file mode 100644
index 00000000..45b40cea
--- /dev/null
+++ b/org.fox.ttrss/src/main/res/drawable/rss_box.xml
@@ -0,0 +1 @@
+<!-- drawable/rss_box.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M5,3H19A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21H5A2,2 0 0,1 3,19V5A2,2 0 0,1 5,3M7.5,15A1.5,1.5 0 0,0 6,16.5A1.5,1.5 0 0,0 7.5,18A1.5,1.5 0 0,0 9,16.5A1.5,1.5 0 0,0 7.5,15M6,10V12A6,6 0 0,1 12,18H14A8,8 0 0,0 6,10M6,6V8A10,10 0 0,1 16,18H18A12,12 0 0,0 6,6Z" /></vector> \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/res/layout-sw600dp-land/activity_detail.xml b/org.fox.ttrss/src/main/res/layout-sw600dp-land/activity_detail.xml
index 59c1b086..823afb9b 100644
--- a/org.fox.ttrss/src/main/res/layout-sw600dp-land/activity_detail.xml
+++ b/org.fox.ttrss/src/main/res/layout-sw600dp-land/activity_detail.xml
@@ -54,7 +54,7 @@
<FrameLayout
android:layout_width="match_parent"
android:id="@+id/article_fragment"
- app:layout_behavior=".util.DetailActivityScrollingViewBehavior"
+ app:layout_behavior="org.fox.ttrss.util.DetailActivityScrollingViewBehavior"
android:layout_height="match_parent"/>
<com.google.android.material.bottomappbar.BottomAppBar
diff --git a/org.fox.ttrss/src/main/res/layout-sw600dp-land/activity_master.xml b/org.fox.ttrss/src/main/res/layout-sw600dp-land/activity_master.xml
index b6a6f19d..63b8c3e2 100644
--- a/org.fox.ttrss/src/main/res/layout-sw600dp-land/activity_master.xml
+++ b/org.fox.ttrss/src/main/res/layout-sw600dp-land/activity_master.xml
@@ -61,7 +61,7 @@
android:id="@+id/headlines_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- app:layout_behavior=".util.FabAwareScrollingViewBehavior" />
+ app:layout_behavior="org.fox.ttrss.util.FabAwareScrollingViewBehavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/master_fab"
diff --git a/org.fox.ttrss/src/main/res/layout/activity_gallery.xml b/org.fox.ttrss/src/main/res/layout/activity_gallery.xml
index f44bb74b..b0f67761 100644
--- a/org.fox.ttrss/src/main/res/layout/activity_gallery.xml
+++ b/org.fox.ttrss/src/main/res/layout/activity_gallery.xml
@@ -17,7 +17,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
- app:icon="?ic_dots_vertical"
+ app:icon="@drawable/baseline_more_vert_24"
android:layout_alignParentRight="true"
android:layout_marginTop="48dp"
app:iconTint="?colorTertiary" />
diff --git a/org.fox.ttrss/src/main/res/layout/feeds_goback.xml b/org.fox.ttrss/src/main/res/layout/feeds_goback.xml
index f4c580a3..75ba8fe1 100755
--- a/org.fox.ttrss/src/main/res/layout/feeds_goback.xml
+++ b/org.fox.ttrss/src/main/res/layout/feeds_goback.xml
@@ -20,7 +20,7 @@
android:layout_height="21dp"
android:layout_weight="0"
android:scaleType="fitXY"
- android:src="?ic_go_back"
+ android:src="@drawable/baseline_arrow_back_24"
app:tint="?colorTertiary" />
<TextView
diff --git a/org.fox.ttrss/src/main/res/layout/feeds_row.xml b/org.fox.ttrss/src/main/res/layout/feeds_row.xml
index 32e20c26..0f9c4e54 100755
--- a/org.fox.ttrss/src/main/res/layout/feeds_row.xml
+++ b/org.fox.ttrss/src/main/res/layout/feeds_row.xml
@@ -23,7 +23,7 @@
android:layout_weight="0"
android:scaleType="fitXY"
app:tint="?colorOnPrimaryContainer"
- android:src="?ic_rss_box" />
+ android:src="@drawable/rss" />
<TextView
android:id="@+id/title"
diff --git a/org.fox.ttrss/src/main/res/layout/feeds_row_selected.xml b/org.fox.ttrss/src/main/res/layout/feeds_row_selected.xml
index c12c732d..031c2116 100755
--- a/org.fox.ttrss/src/main/res/layout/feeds_row_selected.xml
+++ b/org.fox.ttrss/src/main/res/layout/feeds_row_selected.xml
@@ -29,7 +29,7 @@
android:layout_weight="0"
android:scaleType="fitXY"
app:tint="?colorOnTertiaryContainer"
- android:src="?ic_rss_box" />
+ android:src="@drawable/rss" />
<TextView
android:id="@+id/title"
diff --git a/org.fox.ttrss/src/main/res/layout/feeds_row_toggle.xml b/org.fox.ttrss/src/main/res/layout/feeds_row_toggle.xml
index d4451bbe..ad76bca5 100755
--- a/org.fox.ttrss/src/main/res/layout/feeds_row_toggle.xml
+++ b/org.fox.ttrss/src/main/res/layout/feeds_row_toggle.xml
@@ -20,7 +20,7 @@
android:layout_weight="0"
android:scaleType="fitXY"
app:tint="?colorOnPrimaryContainer"
- android:src="?ic_rss_box" />
+ android:src="@drawable/rss_box" />
<TextView
android:id="@+id/title"
diff --git a/org.fox.ttrss/src/main/res/layout/fragment_headlines.xml b/org.fox.ttrss/src/main/res/layout/fragment_headlines.xml
index 2783a1e4..647c3ae9 100755
--- a/org.fox.ttrss/src/main/res/layout/fragment_headlines.xml
+++ b/org.fox.ttrss/src/main/res/layout/fragment_headlines.xml
@@ -12,7 +12,6 @@
<org.fox.ttrss.util.ContextMenuRecyclerView
android:id="@+id/headlines_list"
android:background="?colorSurfaceContainer"
- android:drawSelectorOnTop="true"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
diff --git a/org.fox.ttrss/src/main/res/layout/headlines_row.xml b/org.fox.ttrss/src/main/res/layout/headlines_row.xml
index 52bbae56..3659589d 100755
--- a/org.fox.ttrss/src/main/res/layout/headlines_row.xml
+++ b/org.fox.ttrss/src/main/res/layout/headlines_row.xml
@@ -212,7 +212,7 @@
android:layout_weight="0"
android:paddingLeft="4dp"
android:paddingRight="4dp"
- app:icon="?ic_action_trending_flat" />
+ app:icon="@drawable/baseline_trending_flat_24" />
<com.google.android.material.button.MaterialButton
style="?attr/materialIconButtonStyle"
@@ -222,7 +222,7 @@
android:layout_weight="0"
android:paddingLeft="4dp"
android:paddingRight="4dp"
- app:icon="?ic_attachment" />
+ app:icon="@drawable/baseline_attachment_24" />
<com.google.android.material.button.MaterialButton
style="?attr/materialIconButtonStyle"
@@ -232,7 +232,7 @@
android:layout_weight="0"
android:paddingLeft="4dp"
android:paddingRight="4dp"
- app:icon="?ic_star_outline" />
+ app:icon="@drawable/baseline_star_outline_24" />
<com.google.android.material.button.MaterialButton
style="?attr/materialIconButtonStyle"
@@ -242,7 +242,7 @@
android:layout_weight="0"
android:paddingLeft="4dp"
android:paddingRight="4dp"
- app:icon="?ic_rss_box" />
+ app:icon="@drawable/rss" />
<com.google.android.material.button.MaterialButton
style="?attr/materialIconButtonStyle"
@@ -252,7 +252,7 @@
android:layout_weight="0"
android:paddingLeft="4dp"
android:paddingRight="4dp"
- app:icon="?ic_dots_vertical" />
+ app:icon="@drawable/baseline_more_vert_24" />
</LinearLayout>
</TableRow>
</TableLayout>
diff --git a/org.fox.ttrss/src/main/res/layout/headlines_row_compact.xml b/org.fox.ttrss/src/main/res/layout/headlines_row_compact.xml
index 352aad91..7090668a 100755
--- a/org.fox.ttrss/src/main/res/layout/headlines_row_compact.xml
+++ b/org.fox.ttrss/src/main/res/layout/headlines_row_compact.xml
@@ -103,6 +103,6 @@
android:layout_gravity="end"
android:layout_height="24dp"
android:layout_weight="0.5"
- app:icon="?ic_star_outline" />
+ app:icon="@drawable/baseline_star_outline_24" />
</LinearLayout>
</LinearLayout> \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/res/layout/headlines_row_compact_active.xml b/org.fox.ttrss/src/main/res/layout/headlines_row_compact_active.xml
index 5721dcb8..72ae99b8 100755
--- a/org.fox.ttrss/src/main/res/layout/headlines_row_compact_active.xml
+++ b/org.fox.ttrss/src/main/res/layout/headlines_row_compact_active.xml
@@ -101,8 +101,9 @@
style="?attr/materialIconButtonStyle"
android:layout_width="wrap_content"
android:paddingEnd="0dp"
+ android:layout_gravity="end"
android:layout_height="24dp"
android:layout_weight="0.5"
- app:icon="?ic_star_outline" />
+ app:icon="@drawable/baseline_star_outline_24" />
</LinearLayout>
</LinearLayout> \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/res/layout/headlines_row_compact_active_unread.xml b/org.fox.ttrss/src/main/res/layout/headlines_row_compact_active_unread.xml
index 06813e04..b2b3a21e 100755
--- a/org.fox.ttrss/src/main/res/layout/headlines_row_compact_active_unread.xml
+++ b/org.fox.ttrss/src/main/res/layout/headlines_row_compact_active_unread.xml
@@ -105,6 +105,6 @@
android:layout_gravity="end"
android:layout_height="24dp"
android:layout_weight="0.5"
- app:icon="?ic_star_outline" />
+ app:icon="@drawable/baseline_star_outline_24" />
</LinearLayout>
</LinearLayout> \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/res/layout/headlines_row_compact_unread.xml b/org.fox.ttrss/src/main/res/layout/headlines_row_compact_unread.xml
index 6aa1bdcd..2fbbe062 100755
--- a/org.fox.ttrss/src/main/res/layout/headlines_row_compact_unread.xml
+++ b/org.fox.ttrss/src/main/res/layout/headlines_row_compact_unread.xml
@@ -105,6 +105,6 @@
android:layout_gravity="end"
android:layout_height="24dp"
android:layout_weight="0.5"
- app:icon="?ic_star_outline" />
+ app:icon="@drawable/baseline_star_outline_24" />
</LinearLayout>
</LinearLayout> \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/res/layout/headlines_row_unread.xml b/org.fox.ttrss/src/main/res/layout/headlines_row_unread.xml
index 4b20d9cb..3365f476 100755
--- a/org.fox.ttrss/src/main/res/layout/headlines_row_unread.xml
+++ b/org.fox.ttrss/src/main/res/layout/headlines_row_unread.xml
@@ -212,7 +212,7 @@
android:layout_weight="0"
android:paddingLeft="4dp"
android:paddingRight="4dp"
- app:icon="?ic_action_trending_flat" />
+ app:icon="@drawable/baseline_trending_flat_24" />
<com.google.android.material.button.MaterialButton
style="?attr/materialIconButtonStyle"
@@ -222,7 +222,7 @@
android:layout_weight="0"
android:paddingLeft="4dp"
android:paddingRight="4dp"
- app:icon="?ic_attachment" />
+ app:icon="@drawable/baseline_attachment_24" />
<com.google.android.material.button.MaterialButton
style="?attr/materialIconButtonStyle"
@@ -232,7 +232,7 @@
android:layout_weight="0"
android:paddingLeft="4dp"
android:paddingRight="4dp"
- app:icon="?ic_star_outline" />
+ app:icon="@drawable/baseline_star_outline_24" />
<com.google.android.material.button.MaterialButton
style="?attr/materialIconButtonStyle"
@@ -242,7 +242,7 @@
android:layout_weight="0"
android:paddingLeft="4dp"
android:paddingRight="4dp"
- app:icon="?ic_rss_box" />
+ app:icon="@drawable/rss" />
<com.google.android.material.button.MaterialButton
style="?attr/materialIconButtonStyle"
@@ -252,7 +252,7 @@
android:layout_weight="0"
android:paddingLeft="4dp"
android:paddingRight="4dp"
- app:icon="?ic_dots_vertical" />
+ app:icon="@drawable/baseline_more_vert_24" />
</LinearLayout>
</TableRow>
</TableLayout>
diff --git a/org.fox.ttrss/src/main/res/layout/layout_detail_phone.xml b/org.fox.ttrss/src/main/res/layout/layout_detail_phone.xml
index 55a6ba77..4e75d44b 100644
--- a/org.fox.ttrss/src/main/res/layout/layout_detail_phone.xml
+++ b/org.fox.ttrss/src/main/res/layout/layout_detail_phone.xml
@@ -14,7 +14,7 @@
<FrameLayout
android:id="@+id/article_fragment"
- app:layout_behavior=".util.DetailActivityScrollingViewBehavior"
+ app:layout_behavior="org.fox.ttrss.util.DetailActivityScrollingViewBehavior"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
diff --git a/org.fox.ttrss/src/main/res/layout/layout_master_phone.xml b/org.fox.ttrss/src/main/res/layout/layout_master_phone.xml
index b4cb6b59..e32d5fbe 100644
--- a/org.fox.ttrss/src/main/res/layout/layout_master_phone.xml
+++ b/org.fox.ttrss/src/main/res/layout/layout_master_phone.xml
@@ -29,7 +29,7 @@
<FrameLayout
android:id="@+id/headlines_fragment"
- app:layout_behavior=".util.FabAwareScrollingViewBehavior"
+ app:layout_behavior="org.fox.ttrss.util.FabAwareScrollingViewBehavior"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
diff --git a/org.fox.ttrss/src/main/res/mipmap-anydpi-v26/ic_launcher_variant.xml b/org.fox.ttrss/src/main/res/mipmap-anydpi-v26/ic_launcher_variant.xml
new file mode 100644
index 00000000..d49922f9
--- /dev/null
+++ b/org.fox.ttrss/src/main/res/mipmap-anydpi-v26/ic_launcher_variant.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+ <background android:drawable="@drawable/ic_launcher_background_variant"/>
+ <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+</adaptive-icon> \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/res/values-night/themes.xml b/org.fox.ttrss/src/main/res/values-night/themes.xml
index 7d54a029..e11ef016 100644
--- a/org.fox.ttrss/src/main/res/values-night/themes.xml
+++ b/org.fox.ttrss/src/main/res/values-night/themes.xml
@@ -3,29 +3,6 @@
<item name="windowActionModeOverlay">true</item>
<item name="preferenceTheme">@style/AppPreferenceThemeOverlay</item>
- <item name="ic_rss_box">@drawable/baseline_rss_feed_24</item>
- <item name="ic_checkbox_marked">@drawable/baseline_check_box_24</item>
- <item name="ic_star">@drawable/baseline_star_24</item>
- <item name="ic_star_outline">@drawable/baseline_star_outline_24</item>
- <item name="ic_share">@drawable/baseline_share_24</item>
- <item name="ic_inbox">@drawable/baseline_inbox_24</item>
- <item name="ic_go_back">@drawable/baseline_arrow_back_24</item>
- <item name="ic_settings">@drawable/baseline_settings_24</item>
- <item name="ic_filter_variant">@drawable/baseline_filter_alt_24</item>
- <item name="ic_cloud_download">@drawable/baseline_cloud_download_24</item>
- <item name="ic_cloud_upload">@drawable/baseline_cloud_upload_24</item>
- <item name="ic_archive">@drawable/baseline_archive_24</item>
- <item name="ic_fresh">@drawable/baseline_local_fire_department_24</item>
- <item name="ic_restore">@drawable/baseline_restore_24</item>
- <item name="ic_folder_outline">@drawable/baseline_folder_open_24</item>
- <item name="ic_dots_vertical">@drawable/baseline_more_vert_24</item>
- <item name="ic_dots_vertical_circle">@drawable/outline_more_24</item>
- <item name="ic_attachment">@drawable/baseline_attachment_24</item>
- <item name="ic_attachment_vert">@drawable/baseline_attach_file_24</item>
- <item name="ic_action_trending_up">@drawable/baseline_trending_up_24</item>
- <item name="ic_action_trending_flat">@drawable/baseline_trending_flat_24</item>
- <item name="ic_action_trending_down">@drawable/baseline_trending_down_24</item>
-
<item name="colorPrimary">@color/md_theme_primary</item>
<item name="colorOnPrimary">@color/md_theme_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_primaryContainer</item>
diff --git a/org.fox.ttrss/src/main/res/values/attrs.xml b/org.fox.ttrss/src/main/res/values/attrs.xml
index daf2323c..55344e51 100755
--- a/org.fox.ttrss/src/main/res/values/attrs.xml
+++ b/org.fox.ttrss/src/main/res/values/attrs.xml
@@ -1,29 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <attr name="ic_rss_box" format="reference"/>
- <attr name="ic_checkbox_marked" format="reference" />
- <attr name="ic_star" format="reference" />
- <attr name="ic_star_outline" format="reference" />
- <attr name="ic_share" format="reference" />
- <attr name="ic_go_back" format="reference" />
- <attr name="ic_settings" format="reference" />
- <attr name="ic_filter_variant" format="reference" />
- <attr name="ic_cloud_download" format="reference" />
- <attr name="ic_cloud_upload" format="reference" />
- <attr name="ic_archive" format="reference" />
- <attr name="ic_fresh" format="reference" />
- <attr name="ic_folder_outline" format="reference" />
- <attr name="ic_dots_vertical" format="reference" />
- <attr name="ic_dots_vertical_circle" format="reference" />
- <attr name="ic_attachment" format="reference" />
- <attr name="ic_attachment_vert" format="reference" />
- <declare-styleable name="ScrimInsetsView">
- <attr format="reference|color" name="insetForeground">
- </attr></declare-styleable>
- <attr name="drawer_header" format="reference" />
- <attr name="ic_restore" format="reference" />
- <attr name="ic_inbox" format="reference" />
- <attr name="ic_action_trending_up" format="reference" />
- <attr name="ic_action_trending_flat" format="reference" />
- <attr name="ic_action_trending_down" format="reference" />
</resources> \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/res/values/strings.xml b/org.fox.ttrss/src/main/res/values/strings.xml
index 6a67013a..fb7e6309 100755
--- a/org.fox.ttrss/src/main/res/values/strings.xml
+++ b/org.fox.ttrss/src/main/res/values/strings.xml
@@ -303,4 +303,5 @@
<string name="check_for_updates">Check for updates</string>
<string name="dont_open_anything">Nothing</string>
<string name="open_on_startup">Open on startup</string>
+ <string name="error_success">Operation completed successfully</string>
</resources>
diff --git a/org.fox.ttrss/src/main/res/values/themes.xml b/org.fox.ttrss/src/main/res/values/themes.xml
index 68a57811..15be8c17 100644
--- a/org.fox.ttrss/src/main/res/values/themes.xml
+++ b/org.fox.ttrss/src/main/res/values/themes.xml
@@ -4,29 +4,6 @@
<item name="windowActionModeOverlay">true</item>
<item name="preferenceTheme">@style/AppPreferenceThemeOverlay</item>
- <item name="ic_rss_box">@drawable/baseline_rss_feed_24</item>
- <item name="ic_checkbox_marked">@drawable/baseline_check_box_24</item>
- <item name="ic_star">@drawable/baseline_star_24</item>
- <item name="ic_star_outline">@drawable/baseline_star_outline_24</item>
- <item name="ic_share">@drawable/baseline_share_24</item>
- <item name="ic_inbox">@drawable/baseline_inbox_24</item>
- <item name="ic_go_back">@drawable/baseline_arrow_back_24</item>
- <item name="ic_settings">@drawable/baseline_settings_24</item>
- <item name="ic_filter_variant">@drawable/baseline_filter_alt_24</item>
- <item name="ic_cloud_download">@drawable/baseline_cloud_download_24</item>
- <item name="ic_cloud_upload">@drawable/baseline_cloud_upload_24</item>
- <item name="ic_archive">@drawable/baseline_archive_24</item>
- <item name="ic_fresh">@drawable/baseline_local_fire_department_24</item>
- <item name="ic_restore">@drawable/baseline_restore_24</item>
- <item name="ic_folder_outline">@drawable/baseline_folder_open_24</item>
- <item name="ic_dots_vertical">@drawable/baseline_more_vert_24</item>
- <item name="ic_dots_vertical_circle">@drawable/outline_more_24</item>
- <item name="ic_attachment">@drawable/baseline_attachment_24</item>
- <item name="ic_attachment_vert">@drawable/baseline_attach_file_24</item>
- <item name="ic_action_trending_up">@drawable/baseline_trending_up_24</item>
- <item name="ic_action_trending_flat">@drawable/baseline_trending_flat_24</item>
- <item name="ic_action_trending_down">@drawable/baseline_trending_down_24</item>
-
<item name="colorPrimary">@color/md_theme_primary</item>
<item name="colorOnPrimary">@color/md_theme_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_primaryContainer</item>
diff --git a/org.fox.ttrss/src/main/res/xml/preferences.xml b/org.fox.ttrss/src/main/res/xml/preferences.xml
index 81fbd5f1..8d064587 100755
--- a/org.fox.ttrss/src/main/res/xml/preferences.xml
+++ b/org.fox.ttrss/src/main/res/xml/preferences.xml
@@ -44,7 +44,7 @@
android:title="@string/sort_feeds_by_unread" />
<SwitchPreferenceCompat
- android:defaultValue="false"
+ android:defaultValue="true"
android:key="enable_cats"
android:title="@string/enable_cats" />
@@ -108,7 +108,6 @@
<SwitchPreferenceCompat
android:defaultValue="true"
- android:dependency="headlines_mark_read_scroll"
android:key="headlines_swipe_to_dismiss"
android:summary="@string/pref_headlines_swipe_to_dismiss_long"
android:title="@string/pref_headlines_swipe_to_dismiss" />
diff --git a/org.fox.ttrss/src_drawable/s_dashclock.svg b/org.fox.ttrss/src_drawable/s_dashclock.svg
deleted file mode 100644
index f4be84f9..00000000
--- a/org.fox.ttrss/src_drawable/s_dashclock.svg
+++ /dev/null
@@ -1,1071 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="72"
- height="72"
- id="svg2985"
- version="1.1"
- inkscape:version="0.48.4 r9939"
- inkscape:export-filename="C:\Users\fox\workspace\Tiny-Tiny-RSS-for-Honeycomb\res\drawable-xhdpi\dashclock.png"
- inkscape:export-xdpi="120"
- inkscape:export-ydpi="120"
- sodipodi:docname="s_dashclock.svg">
- <defs
- id="defs2987">
- <filter
- id="filter4035"
- inkscape:label="Glow"
- inkscape:menu="Shadows and Glows"
- inkscape:menu-tooltip="Glow of object's own color at the edges"
- color-interpolation-filters="sRGB">
- <feGaussianBlur
- id="feGaussianBlur4037"
- stdDeviation="5"
- result="result91" />
- <feComposite
- id="feComposite4039"
- in2="result91"
- in="SourceGraphic"
- operator="over" />
- </filter>
- <filter
- id="filter4044"
- inkscape:label="Drop shadow"
- width="1.5"
- height="1.5"
- x="-.25"
- y="-.25">
- <feGaussianBlur
- id="feGaussianBlur4046"
- in="SourceAlpha"
- stdDeviation="2"
- result="blur" />
- <feColorMatrix
- id="feColorMatrix4048"
- result="bluralpha"
- type="matrix"
- values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.5 0 " />
- <feOffset
- id="feOffset4050"
- in="bluralpha"
- dx="1"
- dy="1"
- result="offsetBlur" />
- <feMerge
- id="feMerge4052">
- <feMergeNode
- id="feMergeNode4054"
- in="offsetBlur" />
- <feMergeNode
- id="feMergeNode4056"
- in="SourceGraphic" />
- </feMerge>
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient3890"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- id="RSSg"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3838"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3840"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3842"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3844"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3846"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3848"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3850"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient5363"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- id="linearGradient3277"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3279"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3281"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3283"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3285"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3287"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3289"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3291"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient5668"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- id="linearGradient3294"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3296"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3298"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3300"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3302"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3304"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3306"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3308"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient5670"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- id="linearGradient3311"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3313"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3315"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3317"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3319"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3321"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3323"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3325"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient5652"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- id="linearGradient3328"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3330"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3332"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3334"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3336"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3338"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3340"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3342"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient5654"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- id="linearGradient3345"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3347"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3349"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3351"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3353"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3355"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3357"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3359"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient5656"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- id="linearGradient3362"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3364"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3366"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3368"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3370"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3372"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3374"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3376"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient5658"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- id="linearGradient3379"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3381"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3383"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3385"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3387"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3389"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3391"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3393"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient5664"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- id="linearGradient3396"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3398"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3400"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3402"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3404"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3406"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3408"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3410"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient5666"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- id="linearGradient3413"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3415"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3417"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3419"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3421"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3423"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3425"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3427"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient5660"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- id="linearGradient3430"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3432"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3434"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3436"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3438"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3440"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3442"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3444"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient5662"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- id="linearGradient3447"
- y2="225.94"
- x2="225.94"
- y1="30.059999"
- x1="30.059999"
- gradientUnits="userSpaceOnUse">
- <stop
- id="stop3449"
- stop-color="#E3702D"
- offset="0.0" />
- <stop
- id="stop3451"
- stop-color="#EA7D31"
- offset="0.1071" />
- <stop
- id="stop3453"
- stop-color="#F69537"
- offset="0.3503" />
- <stop
- id="stop3455"
- stop-color="#FB9E3A"
- offset="0.5" />
- <stop
- id="stop3457"
- stop-color="#EA7C31"
- offset="0.7016" />
- <stop
- id="stop3459"
- stop-color="#DE642B"
- offset="0.8866" />
- <stop
- id="stop3461"
- stop-color="#D95B29"
- offset="1.0" />
- </linearGradient>
- <linearGradient
- y2="211.27248"
- x2="217.63582"
- y1="39.288776"
- x1="46.536098"
- gradientUnits="userSpaceOnUse"
- id="linearGradient3469"
- xlink:href="#RSSg"
- inkscape:collect="always" />
- <linearGradient
- y2="125.5"
- x2="220.00627"
- y1="125.5"
- x1="42.993729"
- gradientUnits="userSpaceOnUse"
- id="linearGradient3471"
- xlink:href="#RSSg"
- inkscape:collect="always" />
- <filter
- color-interpolation-filters="sRGB"
- id="filter5699"
- inkscape:label="Drop shadow"
- width="1.5"
- height="1.5"
- x="-0.25"
- y="-0.25">
- <feGaussianBlur
- id="feGaussianBlur5701"
- in="SourceAlpha"
- stdDeviation="2"
- result="blur" />
- <feColorMatrix
- id="feColorMatrix5703"
- result="bluralpha"
- type="matrix"
- values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.5 0 " />
- <feOffset
- id="feOffset5705"
- in="bluralpha"
- dx="2"
- dy="2"
- result="offsetBlur" />
- <feMerge
- id="feMerge5707">
- <feMergeNode
- id="feMergeNode5709"
- in="offsetBlur" />
- <feMergeNode
- id="feMergeNode5711"
- in="SourceGraphic" />
- </feMerge>
- </filter>
- <filter
- id="filter3293"
- inkscape:label="Drop shadow"
- width="1.5"
- height="1.5"
- x="-.25"
- y="-.25">
- <feGaussianBlur
- id="feGaussianBlur3295"
- in="SourceAlpha"
- stdDeviation="3"
- result="blur" />
- <feColorMatrix
- id="feColorMatrix3297"
- result="bluralpha"
- type="matrix"
- values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.75 0 " />
- <feOffset
- id="feOffset3299"
- in="bluralpha"
- dx="1"
- dy="1"
- result="offsetBlur" />
- <feMerge
- id="feMerge3301">
- <feMergeNode
- id="feMergeNode3303"
- in="offsetBlur" />
- <feMergeNode
- id="feMergeNode3305"
- in="SourceGraphic" />
- </feMerge>
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4512"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4514"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4516"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4518"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4520"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4522"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4524"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4526"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4528"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4530"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4532"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4534"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4549"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4551"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4553"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4555"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4557"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4559"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4561"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4563"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4565"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4567"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4572"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248"
- gradientTransform="matrix(0.34665172,0,0,0.34665859,-9.5847012,-7.505653)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4574"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5"
- gradientTransform="matrix(0.34665172,0,0,0.34665859,-9.5847012,-7.505653)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4577"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248"
- gradientTransform="matrix(0.34665172,0,0,0.34665859,-9.5847012,-7.505653)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4579"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5"
- gradientTransform="matrix(0.34665172,0,0,0.34665859,-9.5847012,-7.505653)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4581"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4583"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4585"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4587"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4590"
- gradientUnits="userSpaceOnUse"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248"
- gradientTransform="matrix(0.34665172,0,0,0.34665859,-9.5847012,-15.505653)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4592"
- gradientUnits="userSpaceOnUse"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5"
- gradientTransform="matrix(0.34665172,0,0,0.34665859,-9.5847012,-15.505653)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4676"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.34665172,0,0,0.34665859,-9.5847012,-7.505653)"
- x1="46.536098"
- y1="39.288776"
- x2="217.63582"
- y2="211.27248" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#RSSg"
- id="linearGradient4678"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.34665172,0,0,0.34665859,-9.5847012,-7.505653)"
- x1="42.993729"
- y1="125.5"
- x2="220.00627"
- y2="125.5" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#000000"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:zoom="7.7781746"
- inkscape:cx="49.788136"
- inkscape:cy="31.375346"
- inkscape:current-layer="layer1"
- showgrid="true"
- inkscape:document-units="px"
- inkscape:grid-bbox="true"
- inkscape:snap-page="false"
- inkscape:window-width="1280"
- inkscape:window-height="961"
- inkscape:window-x="1592"
- inkscape:window-y="-8"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata2990">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- id="layer1"
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- transform="translate(0,8)">
- <path
- style="fill:#5693fd;fill-opacity:1;stroke:none"
- d="m 10.457912,43.891242 c -5.3345941,0 -9.68712703,4.316148 -9.68712703,9.650846 0,5.334697 4.35253293,9.687127 9.68712703,9.687127 3.621444,0 6.763753,-2.021498 8.417279,-4.970548 -1.332101,-1.326573 -2.33102,-2.941902 -2.90251,-4.716579 -0.552565,-1.715836 -0.798196,-3.532842 -0.79819,-5.442206 -1.2e-5,-0.630425 0.02748,-1.310797 0.108844,-2.031757 0.02951,-0.261496 0.07199,-0.533671 0.108844,-0.798191 -1.447954,-0.866201 -3.124315,-1.378692 -4.934267,-1.378692 z"
- id="circle26"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#5693fd;fill-opacity:1;stroke:none"
- d="m 0.77078497,16.535086 0,13.678078 A 33.002051,33.002704 0 0 1 17.750468,34.929743 l 2.35829,-9.505721 -4.861704,0 -3.845826,0 1.015878,-3.7007 0.979597,-3.410449 A 46.685828,46.686752 0 0 0 0.77078497,16.535086 z M 39.990951,37.904815 39.337886,40.517074 c -0.08277,0.45381 -0.244611,0.952443 -0.362813,1.451255 -0.09989,0.421337 -0.134677,0.849362 -0.217689,1.269848 -0.08663,0.438515 -0.2221,0.845213 -0.290251,1.233567 -0.05306,0.302702 0,0.488934 0,0.507939 -1.1e-5,0.297438 0.0012,0.391421 0,0.435377 -0.055,-0.05926 0.482688,0.217695 1.741506,0.217688 0.228753,0 0.649652,-0.02893 1.233567,-0.108844 0.588536,-0.08053 1.214979,-0.189057 1.85035,-0.326532 0.164221,-0.03553 0.310568,-0.07416 0.471658,-0.108844 a 46.685828,46.686752 0 0 0 -3.773263,-7.183713 z m 7.365119,21.913951 -0.07256,0.253969 -1.523818,0.50794 c -0.770442,0.252811 -1.647848,0.498277 -2.648541,0.725627 -1.006346,0.228619 -2.097133,0.425988 -3.265323,0.616784 -1.18131,0.192927 -2.400678,0.344324 -3.664419,0.471657 -0.825434,0.08317 -1.630649,0.144805 -2.430852,0.181407 a 33.002051,33.002704 0 0 1 0.03628,0.653065 l 13.678078,0 A 46.685828,46.686752 0 0 0 47.35607,59.818766 z"
- id="path28"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#5693fd;fill-opacity:1;stroke:none"
- d="m 0.77078497,-7.229215 0,14.1134548 A 56.344965,56.346082 0 0 1 15.9364,8.9522782 l 0.108844,-0.3990952 2.213164,0 5.913864,0 2.249445,-8.78009268 0.435377,-1.77778732 0.217688,-0.036281 A 70.431206,70.432601 0 0 0 0.77078497,-7.229215 z M 57.11576,21.070257 l -0.507939,1.814069 -0.616783,2.10432 -2.176883,0 -10.666724,0 -0.217688,0.907034 A 56.344965,56.346082 0 0 1 57.11576,63.229215 l 14.113455,0 A 70.431206,70.432601 0 0 0 57.11576,21.070257 z"
- id="path30"
- inkscape:connector-curvature="0" />
- <path
- inkscape:connector-curvature="0"
- id="path4547"
- style="font-size:87.69078827px;font-style:oblique;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#5693fd;fill-opacity:1;stroke:none;font-family:Segoe UI;-inkscape-font-specification:Segoe UI Bold Oblique"
- d="m 53.804356,22.086365 -12.933871,0 -4.437563,17.489747 c -0.07218,0.395786 -0.162374,0.821991 -0.270583,1.278625 -0.108252,0.45667 -0.207472,0.913316 -0.297641,1.36995 -0.09022,0.456669 -0.171393,0.89049 -0.243525,1.301462 -0.07218,0.410996 -0.108252,0.753492 -0.108229,1.027466 -2.5e-5,1.217754 0.360753,2.115825 1.082332,2.694237 0.721529,0.578436 1.912093,0.867653 3.571696,0.867642 0.432905,1.1e-5 0.98309,-0.04563 1.650558,-0.136999 0.667406,-0.09137 1.352883,-0.21309 2.05643,-0.365321 0.703484,-0.152196 1.379941,-0.312032 2.029374,-0.479483 0.649365,-0.167429 1.172492,-0.312032 1.569382,-0.433809 l -2.651715,10.685637 c -0.649432,0.213102 -1.443141,0.426216 -2.381131,0.639306 -0.938051,0.213114 -1.966266,0.410996 -3.084647,0.593657 -1.118437,0.182649 -2.281943,0.33488 -3.490522,0.456646 -1.208628,0.121777 -2.390173,0.18266 -3.544639,0.18266 -2.741927,0 -5.032861,-0.296822 -6.87281,-0.890478 -1.839977,-0.593645 -3.310144,-1.415612 -4.410505,-2.465914 -1.100379,-1.050291 -1.87605,-2.275638 -2.327014,-3.676041 -0.450979,-1.400391 -0.676465,-2.922561 -0.676458,-4.566507 -7e-6,-0.487088 0.03607,-1.050291 0.10824,-1.689609 0.07215,-0.639307 0.171363,-1.293835 0.297641,-1.963605 0.126262,-0.669737 0.270577,-1.347103 0.432933,-2.032095 0.162343,-0.684969 0.315673,-1.316672 0.459992,-1.895107 l 4.437563,-17.992067 -8.550427,0 3.030532,-10.639977 8.171609,0 2.814064,-10.95963491 18.020835,-3.74454209 -3.625814,14.704177 13.150339,0 z" />
- </g>
-</svg>
diff --git a/org.fox.ttrss/src_drawable/s_drawer_header.svg b/org.fox.ttrss/src_drawable/s_drawer_header.svg
deleted file mode 100644
index d613c406..00000000
--- a/org.fox.ttrss/src_drawable/s_drawer_header.svg
+++ /dev/null
@@ -1,257 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="300"
- height="120"
- viewBox="0 0 300.00001 120.00001"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="s_drawer_header.svg"
- inkscape:export-filename="C:\Users\fox\Projects\tt-rss-android\org.fox.ttrss\src\main\res\drawable-xxhdpi\drawer_header.png"
- inkscape:export-xdpi="307.5"
- inkscape:export-ydpi="307.5">
- <defs
- id="defs4">
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4210">
- <feFlood
- flood-opacity="0.321569"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4212" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4214" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="2"
- result="blur"
- id="feGaussianBlur4216" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4218" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4220" />
- </filter>
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4222">
- <feFlood
- flood-opacity="0.321569"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4224" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4226" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="2"
- result="blur"
- id="feGaussianBlur4228" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4230" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4232" />
- </filter>
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4234">
- <feFlood
- flood-opacity="0.321569"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4236" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4238" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="2"
- result="blur"
- id="feGaussianBlur4240" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4242" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4244" />
- </filter>
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4306">
- <feFlood
- flood-opacity="0.611765"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4308" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4310" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="6"
- result="blur"
- id="feGaussianBlur4312" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4314" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4316" />
- </filter>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#000000"
- borderopacity="1"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="2.8"
- inkscape:cx="107.011"
- inkscape:cy="70.376366"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- units="px"
- borderlayer="true"
- inkscape:window-width="1920"
- inkscape:window-height="1137"
- inkscape:window-x="-8"
- inkscape:window-y="-8"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-932.36214)">
- <path
- style="fill:#c6e3f3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 96.7857,905.93357 63.21428,60.35714 -55.35714,95.71429 -32.857141,-1.0714 z"
- id="path4208"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:#1d6185;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 198.57141,994.505 64.64286,68.9286 -126.78572,-2.5 z"
- id="path4162"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#2374a1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4234)"
- d="M 219.2857,1007.3621 71.071414,1113.0764 161.78572,948.79071 Z"
- id="path4154"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccc" />
- <path
- style="fill:#ab2f08;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 58.214271,1057.3621 -62.1428577,0.3572 -0.7142858,-157.14287 24.6428575,-0.71429 z"
- id="path4160"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#f4511e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4222)"
- d="M 100.71427,895.93357 71.071414,1111.6478 3.2142708,895.93357 Z"
- id="path4156"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccc" />
- <path
- style="fill:#257eae;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4306)"
- d="m 83.571414,898.07643 163.214276,159.99997 63.21429,-0.7143 -3.57143,-161.42853 z"
- id="path4142"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m -1.4285867,895.93357 -1.0714286,-5"
- id="path4158"
- inkscape:connector-curvature="0" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164"
- width="65.35714"
- height="202.85715"
- x="-66.428589"
- y="888.43359" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164-4"
- width="65.357147"
- height="202.85718"
- x="300.89288"
- y="875.93353" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164-41"
- width="364.28574"
- height="81.428589"
- x="-36.250019"
- y="1053.7908" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164-41-3"
- width="364.28577"
- height="81.428596"
- x="-23.571449"
- y="820.2193" />
- </g>
-</svg>
diff --git a/org.fox.ttrss/src_drawable/s_drawer_header_amber.svg b/org.fox.ttrss/src_drawable/s_drawer_header_amber.svg
deleted file mode 100644
index 9c83cf7f..00000000
--- a/org.fox.ttrss/src_drawable/s_drawer_header_amber.svg
+++ /dev/null
@@ -1,257 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="300"
- height="120"
- viewBox="0 0 300.00001 120.00001"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.3 (2405546, 2018-03-11)"
- sodipodi:docname="s_drawer_header_dark.svg"
- inkscape:export-filename="C:\Users\andrew\Projects\tt-rss-android\org.fox.ttrss\src\main\res\drawable-xxhdpi\drawer_header_dark.png"
- inkscape:export-xdpi="307.20001"
- inkscape:export-ydpi="307.20001">
- <defs
- id="defs4">
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4210">
- <feFlood
- flood-opacity="0.321569"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4212" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4214" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="2"
- result="blur"
- id="feGaussianBlur4216" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4218" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4220" />
- </filter>
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4222">
- <feFlood
- flood-opacity="0.321569"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4224" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4226" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="2"
- result="blur"
- id="feGaussianBlur4228" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4230" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4232" />
- </filter>
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4234">
- <feFlood
- flood-opacity="0.321569"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4236" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4238" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="2"
- result="blur"
- id="feGaussianBlur4240" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4242" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4244" />
- </filter>
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4306">
- <feFlood
- flood-opacity="0.611765"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4308" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4310" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="6"
- result="blur"
- id="feGaussianBlur4312" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4314" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4316" />
- </filter>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#000000"
- borderopacity="1"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="2.8"
- inkscape:cx="95.509823"
- inkscape:cy="76.447795"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- units="px"
- borderlayer="true"
- inkscape:window-width="1920"
- inkscape:window-height="1170"
- inkscape:window-x="0"
- inkscape:window-y="0"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-932.36214)">
- <path
- style="fill:#eed5b2;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 96.7857,905.93357 63.21428,60.35714 -55.35714,95.71429 -32.857141,-1.0714 z"
- id="path4208"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:#624318;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 198.57141,994.505 64.64286,68.9286 -126.78572,-2.5 z"
- id="path4162"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#a0712c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4234)"
- d="M 219.2857,1007.3621 71.071414,1113.0764 161.78572,948.79071 Z"
- id="path4154"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccc" />
- <path
- style="fill:#ab2f08;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 58.214271,1057.3621 -62.1428577,0.3572 -0.7142858,-157.14287 24.6428575,-0.71429 z"
- id="path4160"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#f4511e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4222)"
- d="M 100.71427,895.93357 71.071414,1111.6478 3.2142708,895.93357 Z"
- id="path4156"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccc" />
- <path
- style="fill:#b87d2c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4306)"
- d="m 83.571414,898.07643 163.214276,159.99997 63.21429,-0.7143 -3.57143,-161.42853 z"
- id="path4142"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m -1.4285867,895.93357 -1.0714286,-5"
- id="path4158"
- inkscape:connector-curvature="0" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164"
- width="65.35714"
- height="202.85715"
- x="-66.428589"
- y="888.43359" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164-4"
- width="65.357147"
- height="202.85718"
- x="300.89288"
- y="875.93353" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164-41"
- width="364.28574"
- height="81.428589"
- x="-36.250019"
- y="1053.7908" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164-41-3"
- width="364.28577"
- height="81.428596"
- x="-23.571449"
- y="820.2193" />
- </g>
-</svg>
diff --git a/org.fox.ttrss/src_drawable/s_drawer_header_dark.svg b/org.fox.ttrss/src_drawable/s_drawer_header_dark.svg
deleted file mode 100644
index 45c92e72..00000000
--- a/org.fox.ttrss/src_drawable/s_drawer_header_dark.svg
+++ /dev/null
@@ -1,257 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="300"
- height="120"
- viewBox="0 0 300.00001 120.00001"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.3 (2405546, 2018-03-11)"
- sodipodi:docname="s_drawer_header_dark.svg"
- inkscape:export-filename="/home/fox/Projects/tt-rss-android/org.fox.ttrss/src/main/res/drawable-hdpi/drawer_header_amber.png"
- inkscape:export-xdpi="192"
- inkscape:export-ydpi="192">
- <defs
- id="defs4">
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4210">
- <feFlood
- flood-opacity="0.321569"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4212" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4214" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="2"
- result="blur"
- id="feGaussianBlur4216" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4218" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4220" />
- </filter>
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4222">
- <feFlood
- flood-opacity="0.321569"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4224" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4226" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="2"
- result="blur"
- id="feGaussianBlur4228" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4230" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4232" />
- </filter>
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4234">
- <feFlood
- flood-opacity="0.321569"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4236" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4238" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="2"
- result="blur"
- id="feGaussianBlur4240" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4242" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4244" />
- </filter>
- <filter
- style="color-interpolation-filters:sRGB"
- inkscape:label="Drop Shadow"
- id="filter4306">
- <feFlood
- flood-opacity="0.611765"
- flood-color="rgb(0,0,0)"
- result="flood"
- id="feFlood4308" />
- <feComposite
- in="flood"
- in2="SourceGraphic"
- operator="in"
- result="composite1"
- id="feComposite4310" />
- <feGaussianBlur
- in="composite1"
- stdDeviation="6"
- result="blur"
- id="feGaussianBlur4312" />
- <feOffset
- dx="0"
- dy="0"
- result="offset"
- id="feOffset4314" />
- <feComposite
- in="SourceGraphic"
- in2="offset"
- operator="over"
- result="composite2"
- id="feComposite4316" />
- </filter>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#000000"
- borderopacity="1"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="2.8"
- inkscape:cx="95.15268"
- inkscape:cy="76.447795"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- units="px"
- borderlayer="true"
- inkscape:window-width="1920"
- inkscape:window-height="1170"
- inkscape:window-x="0"
- inkscape:window-y="0"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-932.36214)">
- <path
- style="fill:#eed5b2;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 96.7857,905.93357 63.21428,60.35714 -55.35714,95.71429 -32.857141,-1.0714 z"
- id="path4208"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:#624318;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 198.57141,994.505 64.64286,68.9286 -126.78572,-2.5 z"
- id="path4162"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#a0712c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4234)"
- d="M 219.2857,1007.3621 71.071414,1113.0764 161.78572,948.79071 Z"
- id="path4154"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccc" />
- <path
- style="fill:#ab2f08;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 58.214271,1057.3621 -62.1428577,0.3572 -0.7142858,-157.14287 24.6428575,-0.71429 z"
- id="path4160"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#f4511e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4222)"
- d="M 100.71427,895.93357 71.071414,1111.6478 3.2142708,895.93357 Z"
- id="path4156"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccc" />
- <path
- style="fill:#b87d2c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4306)"
- d="m 83.571414,898.07643 163.214276,159.99997 63.21429,-0.7143 -3.57143,-161.42853 z"
- id="path4142"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m -1.4285867,895.93357 -1.0714286,-5"
- id="path4158"
- inkscape:connector-curvature="0" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164"
- width="65.35714"
- height="202.85715"
- x="-66.428589"
- y="888.43359" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164-4"
- width="65.357147"
- height="202.85718"
- x="300.89288"
- y="875.93353" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164-41"
- width="364.28574"
- height="81.428589"
- x="-36.250019"
- y="1053.7908" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4164-41-3"
- width="364.28577"
- height="81.428596"
- x="-23.571449"
- y="820.2193" />
- </g>
-</svg>