summaryrefslogtreecommitdiff
path: root/org.fox.ttrss/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'org.fox.ttrss/src/main/java')
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/Application.java12
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java83
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java73
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java57
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java133
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java5
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java6
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineMasterActivity.java2
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java3
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/util/ImageCacheService.java2
10 files changed, 332 insertions, 44 deletions
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/Application.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/Application.java
index dd134e8c..94857855 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
@@ -10,6 +10,9 @@ import org.fox.ttrss.types.ArticleList;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+
+import java.util.LinkedHashMap;
+
import icepick.Icepick;
public class Application extends android.app.Application {
@@ -21,6 +24,8 @@ public class Application extends android.app.Application {
public int m_selectedArticleId;
public String m_sessionId;
public int m_apiLevel;
+ public LinkedHashMap<String, String> m_customSortModes = new LinkedHashMap<String, String>();
+
public static Application getInstance(){
return m_singleton;
}
@@ -50,6 +55,7 @@ public class Application extends android.app.Application {
out.putString("gs:sessionId", m_sessionId);
out.putInt("gs:apiLevel", m_apiLevel);
out.putInt("gs:selectedArticleId", m_selectedArticleId);
+ out.putSerializable("gs:customSortTypes", m_customSortModes);
}
public void load(Bundle in) {
@@ -57,6 +63,12 @@ public class Application extends android.app.Application {
m_sessionId = in.getString("gs:sessionId");
m_apiLevel = in.getInt("gs:apiLevel");
m_selectedArticleId = in.getInt("gs:selectedArticleId");
+
+ try {
+ m_customSortModes = (LinkedHashMap<String, String>) in.getSerializable("gs:customSortTypes");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
}
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 ed961e38..d75a4e5a 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
@@ -2,7 +2,11 @@ package org.fox.ttrss;
import android.annotation.SuppressLint;
import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
import android.content.SharedPreferences;
+import android.content.res.Resources;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
@@ -23,6 +27,7 @@ import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebView.HitTestResult;
import android.webkit.WebViewClient;
+import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@@ -210,6 +215,70 @@ public class ArticleFragment extends StateSavedFragment {
}
+ final ImageView scoreView = view.findViewById(R.id.score);
+
+ if (scoreView != null) {
+ setScoreImage(scoreView, m_article.score);
+
+ Resources.Theme theme = m_activity.getTheme();
+ TypedValue tv = new TypedValue();
+ theme.resolveAttribute(R.attr.headlineTitleHighScoreUnreadTextColor, tv, true);
+ int titleHighScoreUnreadColor = tv.data;
+
+ if (m_article.score > Article.SCORE_HIGH)
+ scoreView.setColorFilter(titleHighScoreUnreadColor);
+ else
+ scoreView.setColorFilter(null);
+
+ if (m_activity.getApiLevel() >= 16) {
+ scoreView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final EditText edit = new EditText(getActivity());
+ edit.setText(String.valueOf(m_article.score));
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.score_for_this_article)
+ .setPositiveButton(R.string.set_score,
+ new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog,
+ int which) {
+
+ try {
+ int newScore = Integer.parseInt(edit.getText().toString());
+
+ m_article.score = newScore;
+
+ m_activity.saveArticleScore(m_article);
+
+ setScoreImage(scoreView, newScore);
+ } catch (NumberFormatException e) {
+ m_activity.toast(R.string.score_invalid);
+ e.printStackTrace();
+ }
+ }
+ })
+ .setNegativeButton(getString(R.string.cancel),
+ new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog,
+ int which) {
+
+ //
+
+ }
+ }).setView(edit);
+
+ Dialog dialog = builder.create();
+ dialog.show();
+ }
+ });
+ }
+ }
+
ImageView attachments = view.findViewById(R.id.attachments);
if (attachments != null) {
@@ -360,6 +429,20 @@ public class ArticleFragment extends StateSavedFragment {
return view;
}
+ private void setScoreImage(ImageView scoreView, int score) {
+ TypedValue tv = new TypedValue();
+ int scoreAttr = R.attr.ic_action_trending_flat;
+
+ if (m_article.score > 0)
+ scoreAttr = R.attr.ic_action_trending_up;
+ else if (m_article.score < 0)
+ scoreAttr = R.attr.ic_action_trending_down;
+
+ m_activity.getTheme().resolveAttribute(scoreAttr, tv, true);
+
+ scoreView.setImageResource(tv.resourceId);
+ }
+
protected void renderContent(Bundle savedInstanceState) {
if (!isAdded() || m_web == null) return;
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 b92324da..672da44e 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
@@ -43,6 +43,7 @@ import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.CheckBox;
+import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupMenu;
@@ -704,6 +705,7 @@ public class HeadlinesFragment extends StateSavedFragment {
public TextView titleView;
public TextView feedTitleView;
public ImageView markedView;
+ public ImageView scoreView;
public ImageView publishedView;
public TextView excerptView;
public ImageView flavorImageView;
@@ -747,6 +749,7 @@ public class HeadlinesFragment extends StateSavedFragment {
feedTitleView = v.findViewById(R.id.feed_title);
markedView = v.findViewById(R.id.marked);
+ scoreView = v.findViewById(R.id.score);
publishedView = v.findViewById(R.id.published);
excerptView = v.findViewById(R.id.excerpt);
flavorImageView = v.findViewById(R.id.flavor_image);
@@ -1034,6 +1037,72 @@ public class HeadlinesFragment extends StateSavedFragment {
});
}
+ if (holder.scoreView != null) {
+ TypedValue tv = new TypedValue();
+ int scoreAttr = R.attr.ic_action_trending_flat;
+
+ if (article.score > 0)
+ scoreAttr = R.attr.ic_action_trending_up;
+ else if (article.score < 0)
+ scoreAttr = R.attr.ic_action_trending_down;
+
+ m_activity.getTheme().resolveAttribute(scoreAttr, tv, true);
+
+ holder.scoreView.setImageResource(tv.resourceId);
+
+ if (article.score > Article.SCORE_HIGH)
+ holder.scoreView.setColorFilter(titleHighScoreUnreadColor);
+ else
+ holder.scoreView.setColorFilter(null);
+
+ if (m_activity.getApiLevel() >= 16) {
+ holder.scoreView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final EditText edit = new EditText(getActivity());
+ edit.setText(String.valueOf(article.score));
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.score_for_this_article)
+ .setPositiveButton(R.string.set_score,
+ new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog,
+ int which) {
+
+ try {
+ int newScore = Integer.parseInt(edit.getText().toString());
+
+ article.score = newScore;
+
+ m_activity.saveArticleScore(article);
+
+ m_adapter.notifyItemChanged(m_list.getChildPosition(holder.view));
+ } catch (NumberFormatException e) {
+ m_activity.toast(R.string.score_invalid);
+ e.printStackTrace();
+ }
+ }
+ })
+ .setNegativeButton(getString(R.string.cancel),
+ new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog,
+ int which) {
+
+ //
+
+ }
+ }).setView(edit);
+
+ Dialog dialog = builder.create();
+ dialog.show();
+ }
+ });
+ }
+ }
if (holder.publishedView != null) {
TypedValue tv = new TypedValue();
@@ -1662,9 +1731,9 @@ public class HeadlinesFragment extends StateSavedFragment {
// store original color
origTitleColors[viewType] = Integer.valueOf(tv.getCurrentTextColor());
- if (score < -500) {
+ if (score < Article.SCORE_LOW) {
tv.setPaintFlags(tv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
- } else if (score > 500) {
+ } else if (score > Article.SCORE_HIGH) {
tv.setTextColor(titleHighScoreUnreadColor);
tv.setPaintFlags(tv.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
} else {
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 121b836c..f7681e42 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
@@ -26,6 +26,7 @@ import org.fox.ttrss.types.FeedCategory;
import java.util.Date;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.widget.Toolbar;
@@ -367,45 +368,43 @@ public class MasterActivity extends OnlineActivity implements HeadlinesEventList
case R.id.headlines_toggle_sort_order:
Dialog dialog = new Dialog(this);
- String sortMode = getSortMode();
+ LinkedHashMap<String, String> sortModes = getSortModes();
- int selectedIndex = 0;
+ CharSequence[] sortTitles = sortModes.values().toArray(new CharSequence[0]);
+ final CharSequence[] sortNames = sortModes.keySet().toArray(new CharSequence[0]);
- if (sortMode.equals("feed_dates")) {
- selectedIndex = 1;
- } else if (sortMode.equals("date_reverse")) {
- selectedIndex = 2;
- } else if (sortMode.equals("title")) {
- selectedIndex = 3;
- }
+ String currentMode = getSortMode();
+
+ int i = 0;
+ int selectedIndex = 0;
+
+ for (CharSequence tmp : sortNames) {
+ if (tmp.equals(currentMode)) {
+ selectedIndex = i;
+ break;
+ }
+
+ ++i;
+ }
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setTitle(getString(R.string.headlines_sort_articles_title))
.setSingleChoiceItems(
- new String[] {
- getString(R.string.headlines_sort_default),
- getString(R.string.headlines_sort_newest_first),
- getString(R.string.headlines_sort_oldest_first),
- getString(R.string.headlines_sort_title)
- },
+ sortTitles,
selectedIndex, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
- switch (which) {
- case 0:
- setSortMode("default");
- break;
- case 1:
- setSortMode("feed_dates");
- break;
- case 2:
- setSortMode("date_reverse");
- break;
- case 3:
- setSortMode("title");
- break;
- }
+
+ try {
+// Log.d(TAG, "sort selected index:" + which + ": " + sortNames[which]);
+
+ setSortMode((String)sortNames[which]);
+
+ } catch (IndexOutOfBoundsException e) {
+ e.printStackTrace();
+ }
+
dialog.cancel();
refresh();
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 e8559d3e..f513173a 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
@@ -1,5 +1,6 @@
package org.fox.ttrss;
+import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -31,6 +32,8 @@ import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
+import com.github.javiersantos.appupdater.AppUpdater;
+import com.github.javiersantos.appupdater.enums.UpdateFrom;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -48,7 +51,9 @@ import org.fox.ttrss.util.ImageCacheService;
import java.lang.reflect.Type;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import androidx.appcompat.view.ActionMode;
import androidx.appcompat.widget.Toolbar;
@@ -256,11 +261,20 @@ public class OnlineActivity extends CommonActivity {
switchOfflineSuccess();
} else {
checkTrial(false);
+ checkUpdates();
m_headlinesActionModeCallback = new HeadlinesActionModeCallback();
}
}
+ protected void checkUpdates() {
+ if (BuildConfig.DEBUG || BuildConfig.ENABLE_UPDATER) {
+ new AppUpdater(this)
+ .setUpdateFrom(UpdateFrom.JSON)
+ .setUpdateJSON(String.format("https://srv.tt-rss.org/fdroid/updates/%1$s.json", this.getPackageName()))
+ .start();
+ }
+ }
protected void switchOffline() {
AlertDialog.Builder builder = new AlertDialog.Builder(this)
@@ -1164,24 +1178,28 @@ public class OnlineActivity extends CommonActivity {
initMenu();
- List<PackageInfo> pkgs = getPackageManager()
- .getInstalledPackages(0);
-
- for (PackageInfo p : pkgs) {
- if ("org.fox.ttrss.key".equals(p.packageName)) {
- Log.d(TAG, "license apk found");
- menu.findItem(R.id.donate).setVisible(false);
- break;
+ if (BuildConfig.ENABLE_TRIAL && !BuildConfig.DEBUG) {
+ List<PackageInfo> pkgs = getPackageManager()
+ .getInstalledPackages(0);
+
+ for (PackageInfo p : pkgs) {
+ if ("org.fox.ttrss.key".equals(p.packageName)) {
+ Log.d(TAG, "license apk found");
+ menu.findItem(R.id.donate).setVisible(false);
+ break;
+ }
}
+ } else {
+ menu.findItem(R.id.donate).setVisible(false);
}
-
+
return true;
}
public int getApiLevel() {
return Application.getInstance().m_apiLevel;
}
-
+
protected void setApiLevel(int apiLevel) {
Application.getInstance().m_apiLevel = apiLevel;
}
@@ -1208,6 +1226,27 @@ public class OnlineActivity extends CommonActivity {
req.execute(map);
}
+ public void saveArticleScore(final Article article) {
+ ApiRequest req = new ApiRequest(getApplicationContext()) {
+ protected void onPostExecute(JsonElement result) {
+ //toast(article.marked ? R.string.notify_article_marked : R.string.notify_article_unmarked);
+ invalidateOptionsMenu();
+ }
+ };
+
+ HashMap<String, String> map = new HashMap<String, String>() {
+ {
+ put("sid", getSessionId());
+ put("op", "updateArticle");
+ put("article_ids", String.valueOf(article.id));
+ put("data", String.valueOf(article.score));
+ put("field", "4");
+ }
+ };
+
+ req.execute(map);
+ }
+
public void saveArticleMarked(final Article article) {
ApiRequest req = new ApiRequest(getApplicationContext()) {
protected void onPostExecute(JsonElement result) {
@@ -1291,8 +1330,45 @@ public class OnlineActivity extends CommonActivity {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
+ ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
+ HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (ap != null && ap.isAdded()) {
+ ap.selectArticle(false);
+ return true;
+ }
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (ap != null && ap.isAdded()) {
+ ap.selectArticle(true);
+ return true;
+ }
+ break;
+ case KeyEvent.KEYCODE_ESCAPE:
+ moveTaskToBack(true);
+ return true;
+ case KeyEvent.KEYCODE_O:
+ if (ap != null && ap.getSelectedArticle() != null) {
+ openUri(Uri.parse(ap.getSelectedArticle().link));
+ return true;
+ }
+ break;
+ case KeyEvent.KEYCODE_R:
+ refresh();
+ return true;
+ case KeyEvent.KEYCODE_U:
+ if (ap != null && ap.getSelectedArticle() != null) {
+ Article a = ap.getSelectedArticle();
+ a.unread = !a.unread;
+ saveArticleUnread(a);
+ if (hf != null) hf.notifyUpdated();
+ }
+ return true;
+ }
+
if (m_prefs.getBoolean("use_volume_keys", false)) {
- ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
if (ap != null && ap.isAdded()) {
switch (keyCode) {
@@ -1506,6 +1582,7 @@ public class OnlineActivity extends CommonActivity {
}
@SuppressWarnings("unchecked")
+ @SuppressLint("StaticFieldLeak")
protected void onPostExecute(JsonElement result) {
if (result != null) {
try {
@@ -1521,6 +1598,20 @@ public class OnlineActivity extends CommonActivity {
if (apiLevel != null) {
setApiLevel(apiLevel.getAsInt());
Log.d(TAG, "Received API level: " + getApiLevel());
+
+ // get custom sort from configuration object
+ if (getApiLevel() >= 17) {
+
+ // daemon_is_running, icons_dir, etc...
+ JsonObject config = content.get("config").getAsJsonObject();
+
+ Type hashType = new TypeToken<Map<String, String>>(){}.getType();
+ Map<String, String> customSortTypes = new Gson().fromJson(config.get("custom_sort_types"), hashType);
+
+ setCustomSortModes(customSortTypes);
+
+ Log.d(TAG, "test");
+ }
if (m_listener != null) {
m_listener.OnLoginSuccess();
@@ -1602,7 +1693,20 @@ public class OnlineActivity extends CommonActivity {
}
- public String getSortMode() {
+ public LinkedHashMap<String, String> getSortModes() {
+ LinkedHashMap<String, String> tmp = new LinkedHashMap<String, String>();
+
+ tmp.put("default", getString(R.string.headlines_sort_default));
+ tmp.put("feed_dates", getString(R.string.headlines_sort_newest_first));
+ tmp.put("date_reverse", getString(R.string.headlines_sort_oldest_first));
+ tmp.put("title", getString(R.string.headlines_sort_title));
+
+ tmp.putAll(Application.getInstance().m_customSortModes);
+
+ return tmp;
+ }
+
+ public String getSortMode() {
return m_prefs.getString("headlines_sort_mode", "default");
}
@@ -1612,6 +1716,11 @@ public class OnlineActivity extends CommonActivity {
editor.apply();
}
+ private synchronized void setCustomSortModes(Map<String, String> modes) {
+ Application.getInstance().m_customSortModes.clear();
+ Application.getInstance().m_customSortModes.putAll(modes);
+ }
+
public void setViewMode(String viewMode) {
SharedPreferences.Editor editor = m_prefs.edit();
editor.putString("view_mode", viewMode);
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java
index 441ec62b..a3b152a7 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java
@@ -235,6 +235,11 @@ public class OfflineArticleFragment extends Fragment {
}
+ ImageView score = view.findViewById(R.id.score);
+
+ if (score != null) {
+ score.setVisibility(View.GONE);
+ }
ImageView attachments = view.findViewById(R.id.attachments);
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java
index 3d9e1229..470b0aac 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java
@@ -505,6 +505,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
public View flavorImageOverflow;
public View headlineHeader;
public ImageView attachmentsView;
+ public ImageView scoreView;
public ArticleViewHolder(View v) {
@@ -549,6 +550,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
headlineHeader = v.findViewById(R.id.headline_header);
flavorImageOverflow = v.findViewById(R.id.gallery_overflow);
attachmentsView = v.findViewById(R.id.attachments);
+ scoreView = v.findViewById(R.id.score);
}
}
@@ -794,6 +796,10 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
holder.attachmentsView.setVisibility(View.GONE);
}
+ if (holder.scoreView != null) {
+ holder.scoreView.setVisibility(View.GONE);
+ }
+
if (holder.markedView != null) {
TypedValue tv = new TypedValue();
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineMasterActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineMasterActivity.java
index cdaa794e..0a3b6378 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineMasterActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineMasterActivity.java
@@ -25,6 +25,8 @@ import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
+import java.util.HashMap;
+
public class OfflineMasterActivity extends OfflineActivity implements OfflineHeadlinesEventListener {
private final String TAG = this.getClass().getSimpleName();
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 a11cd0ac..2daaba49 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
@@ -21,6 +21,9 @@ public class Article implements Parcelable {
public static final int FLAVOR_KIND_VIDEO = 2;
public static final int FLAVOR_KIND_YOUTUBE = 3;
+ public static final int SCORE_LOW = -500;
+ public static final int SCORE_HIGH = 500;
+
public int id;
public boolean unread;
public boolean marked;
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ImageCacheService.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ImageCacheService.java
index f07e23c2..24a7a732 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ImageCacheService.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ImageCacheService.java
@@ -132,7 +132,7 @@ public class ImageCacheService extends IntentService {
digest.update(s.getBytes());
byte messageDigest[] = digest.digest();
- StringBuffer hexString = new StringBuffer();
+ StringBuilder hexString = new StringBuilder();
for (int i=0; i<messageDigest.length; i++)
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));