summaryrefslogtreecommitdiff
path: root/org.fox.ttrss
diff options
context:
space:
mode:
Diffstat (limited to 'org.fox.ttrss')
-rwxr-xr-xorg.fox.ttrss/build.gradle2
-rwxr-xr-xorg.fox.ttrss/src/main/AndroidManifest.xml6
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java60
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java123
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java18
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/BaseFeedlistFragment.java50
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/CommonActivity.java129
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java8
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/FeedCategoriesFragment.java2
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java2
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java348
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java7
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java94
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesActivity.java1
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java149
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java8
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineActivity.java53
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java68
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java7
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java4
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java247
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineMasterActivity.java7
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java24
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/util/EnlargingImageView.java2
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/util/ForegroundImageView.java121
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesRequest.java14
-rw-r--r--[-rwxr-xr-x]org.fox.ttrss/src/main/java/org/fox/ttrss/util/NoChildFocusScrollView.java3
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/util/NotifyingScrollView.java45
-rw-r--r--org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_bg_pressed.9.pngbin798 -> 0 bytes
-rw-r--r--org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg.9.pngbin731 -> 0 bytes
-rw-r--r--org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg_focused.9.pngbin856 -> 0 bytes
-rw-r--r--org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_bg_pressed.9.pngbin1098 -> 0 bytes
-rw-r--r--org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg.9.pngbin1005 -> 0 bytes
-rw-r--r--org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg_focused.9.pngbin1135 -> 0 bytes
-rw-r--r--org.fox.ttrss/src/main/res/drawable/appwidget_dark_bg_clickable.xml24
-rw-r--r--org.fox.ttrss/src/main/res/layout/activity_preferences.xml1
-rw-r--r--org.fox.ttrss/src/main/res/layout/activity_video_player.xml22
-rw-r--r--org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml2
-rw-r--r--org.fox.ttrss/src/main/res/layout/article_images_image.xml12
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/article_images_pager.xml2
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/drawer_header.xml1
-rw-r--r--org.fox.ttrss/src/main/res/layout/fragment_article.xml2
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/headlines_row.xml22
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/headlines_row_unread.xml20
-rwxr-xr-xorg.fox.ttrss/src/main/res/layout/widget_small.xml13
-rw-r--r--org.fox.ttrss/src/main/res/menu/activity_video_player.xml7
-rw-r--r--org.fox.ttrss/src/main/res/menu/context_article_content_img.xml2
-rw-r--r--org.fox.ttrss/src/main/res/menu/context_headlines.xml54
-rwxr-xr-xorg.fox.ttrss/src/main/res/values-it/strings.xml8
-rwxr-xr-xorg.fox.ttrss/src/main/res/values-pt-rBR/strings.xml147
-rwxr-xr-xorg.fox.ttrss/src/main/res/values/attrs.xml3
-rwxr-xr-xorg.fox.ttrss/src/main/res/values/strings.xml3
-rwxr-xr-xorg.fox.ttrss/src/main/res/values/style.xml32
53 files changed, 1234 insertions, 745 deletions
diff --git a/org.fox.ttrss/build.gradle b/org.fox.ttrss/build.gradle
index a5aec718..94373e3a 100755
--- a/org.fox.ttrss/build.gradle
+++ b/org.fox.ttrss/build.gradle
@@ -31,7 +31,7 @@ dependencies {
compile files('libs/universal-image-loader-1.9.3.jar')
compile 'com.android.support:cardview-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
- compile 'com.google.code.gson:gson:2.3'
+ compile 'com.google.code.gson:gson:2.4'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.shamanland:fab:0.0.5'
compile 'ch.acra:acra:4.5.0'
diff --git a/org.fox.ttrss/src/main/AndroidManifest.xml b/org.fox.ttrss/src/main/AndroidManifest.xml
index 06db6351..beaef47b 100755
--- a/org.fox.ttrss/src/main/AndroidManifest.xml
+++ b/org.fox.ttrss/src/main/AndroidManifest.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.fox.ttrss"
- android:versionCode="386"
- android:versionName="1.158" >
+ android:versionCode="412"
+ android:versionName="1.178" >
<uses-sdk
android:minSdkVersion="16"
@@ -17,6 +17,7 @@
android:name=".Application"
android:allowBackup="true"
android:backupAgent=".util.PrefsBackupAgent"
+ android:fullBackupOnly="true"
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
@@ -254,6 +255,7 @@
<activity
android:name=".ArticleImagesPagerActivity"
+ android:configChanges="keyboardHidden|orientation|screenSize"
android:label="Article Images" >
</activity>
<activity
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 8f7e556d..1c0afca8 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,14 +2,13 @@ package org.fox.ttrss;
import android.annotation.SuppressLint;
import android.app.Activity;
-import android.content.Intent;
import android.content.SharedPreferences;
+import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
-import android.support.v4.widget.NestedScrollView;
import android.support.v7.app.ActionBar;
import android.text.Html;
import android.util.Log;
@@ -28,16 +27,16 @@ import android.webkit.WebView.HitTestResult;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.ScrollView;
import android.widget.TextView;
import com.shamanland.fab.ShowHideOnScroll;
import org.fox.ttrss.types.Article;
import org.fox.ttrss.types.Attachment;
-import org.fox.ttrss.util.NoChildFocusScrollView;
+import org.fox.ttrss.util.NotifyingScrollView;
import java.net.MalformedURLException;
-import java.net.URI;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
@@ -183,7 +182,7 @@ public class ArticleFragment extends Fragment {
m_contentView = view.findViewById(R.id.article_scrollview);
m_customViewContainer = (FrameLayout) view.findViewById(R.id.article_fullscreen_video);
- if (m_article.id == HeadlinesFragment.ARTICLE_SPECIAL_TOP_CHANGED) {
+ /* if (m_article.id == HeadlinesFragment.ARTICLE_SPECIAL_TOP_CHANGED) {
TextView statusMessage = (TextView) view.findViewById(R.id.article_status_message);
statusMessage.setText(R.string.headlines_row_top_changed);
statusMessage.setVisibility(View.VISIBLE);
@@ -192,17 +191,17 @@ public class ArticleFragment extends Fragment {
view.findViewById(R.id.article_fab).setVisibility(View.GONE);
return view;
- }
+ } */
- NoChildFocusScrollView scrollView = (NoChildFocusScrollView) view.findViewById(R.id.article_scrollview);
+ NotifyingScrollView scrollView = (NotifyingScrollView) view.findViewById(R.id.article_scrollview);
m_fab = view.findViewById(R.id.article_fab);
if (scrollView != null && m_activity.isSmallScreen()) {
view.findViewById(R.id.article_heading_spacer).setVisibility(View.VISIBLE);
- scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
+ scrollView.setOnScrollChangedListener(new NotifyingScrollView.OnScrollChangedListener() {
@Override
- public void onScrollChange(NestedScrollView who, int l, int t, int oldl, int oldt) {
+ public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt) {
ActionBar ab = m_activity.getSupportActionBar();
if (t >= oldt && t >= ab.getHeight()) {
@@ -223,12 +222,7 @@ public class ArticleFragment extends Fragment {
@Override
public void onClick(View view) {
try {
- URL url = new URL(m_article.link.trim());
- String uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),
- url.getPort(), url.getPath(), url.getQuery(), url.getRef()).toString();
-
- m_activity.openUri(Uri.parse(uri));
-
+ m_activity.openUri(Uri.parse(m_article.link));
} catch (Exception e) {
e.printStackTrace();
m_activity.toast(R.string.error_other_error);
@@ -262,11 +256,7 @@ public class ArticleFragment extends Fragment {
@Override
public void onClick(View v) {
try {
- URL url = new URL(m_article.link.trim());
- String uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),
- url.getPort(), url.getPath(), url.getQuery(), url.getRef()).toString();
-
- m_activity.openUri(Uri.parse(uri));
+ m_activity.openUri(Uri.parse(m_article.link));
} catch (Exception e) {
e.printStackTrace();
m_activity.toast(R.string.error_other_error);
@@ -274,7 +264,6 @@ public class ArticleFragment extends Fragment {
}
});
- registerForContextMenu(title);
}
ImageView share = (ImageView)view.findViewById(R.id.share);
@@ -301,12 +290,10 @@ public class ArticleFragment extends Fragment {
@Override
public void onClick(View v) {
try {
- URL url = new URL((m_article.comments_link != null && m_article.comments_link.length() > 0) ?
- m_article.comments_link : m_article.link);
- String uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),
- url.getPort(), url.getPath(), url.getQuery(), url.getRef()).toString();
+ String url = (m_article.comments_link != null && m_article.comments_link.length() > 0) ?
+ m_article.comments_link : m_article.link;
- m_activity.openUri(Uri.parse(uri));
+ m_activity.openUri(Uri.parse(url));
} catch (Exception e) {
e.printStackTrace();
m_activity.toast(R.string.error_other_error);
@@ -341,21 +328,6 @@ public class ArticleFragment extends Fragment {
dv.setText(df.format(d));
}
- TextView author = (TextView)view.findViewById(R.id.author);
-
- boolean hasAuthor = false;
-
- if (author != null) {
- author.setTextSize(TypedValue.COMPLEX_UNIT_SP, m_articleSmallFontSize);
-
- if (m_article.author != null && m_article.author.length() > 0) {
- author.setText(getString(R.string.author_formatted, m_article.author));
- } else {
- author.setVisibility(View.GONE);
- }
- hasAuthor = true;
- }
-
TextView tagv = (TextView)view.findViewById(R.id.tags);
if (tagv != null) {
@@ -364,7 +336,7 @@ public class ArticleFragment extends Fragment {
if (m_article.feed_title != null) {
String fTitle = m_article.feed_title;
- if (!hasAuthor && m_article.author != null && m_article.author.length() > 0) {
+ if (m_article.author != null && m_article.author.length() > 0) {
fTitle += " (" + getString(R.string.author_formatted, m_article.author) + ")";
}
@@ -476,6 +448,10 @@ public class ArticleFragment extends Fragment {
ws.setMediaPlaybackRequiresUserGesture(false);
}
+ if (CommonActivity.THEME_DARK.equals(m_prefs.getString("theme", CommonActivity.THEME_DEFAULT))) {
+ m_web.setBackgroundColor(Color.BLACK);
+ }
+
if (m_prefs.getBoolean("justify_article_text", true)) {
cssOverride += "body { text-align : justify; } ";
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java
index 39aa8fe4..2e60e6d1 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java
@@ -20,11 +20,14 @@ import android.view.ContextMenu;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AdapterView;
import android.widget.FrameLayout;
+import android.widget.PopupMenu;
import android.widget.ProgressBar;
import android.widget.TextView;
@@ -60,14 +63,6 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
@Override
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
- ActionBar bar = getSupportActionBar();
-
- if (bar.isShowing()) {
- bar.hide();
- } else {
- bar.show();
- }
-
return false;
}
@@ -90,10 +85,6 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
m_urls = urls;
}
- public ArticleImagesPagerAdapter() {
- super();
- }
-
@Override
public int getCount() {
return m_urls.size();
@@ -106,7 +97,7 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
@Override
public Object instantiateItem(ViewGroup container, int position) {
- String url = m_urls.get(position);
+ final String url = m_urls.get(position);
Log.d(TAG, "called for URL: " + url);
@@ -131,11 +122,30 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
});
if (position == 0) {
- ViewCompat.setTransitionName(imgView, "TRANSITION:ARTICLE_IMAGES_PAGER");
+ ViewCompat.setTransitionName(imgView, "gallery:" + url);
}
registerForContextMenu(imgView);
+ view.findViewById(R.id.flavor_image_overflow).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ PopupMenu popup = new PopupMenu(ArticleImagesPagerActivity.this, v);
+ MenuInflater inflater = popup.getMenuInflater();
+ inflater.inflate(R.menu.context_article_content_img, popup.getMenu());
+
+ popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ return onImageMenuItemSelected(item, url);
+ }
+ });
+
+ popup.show();
+
+ }
+ });
+
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.resetViewBeforeLoading(true)
@@ -173,7 +183,7 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
}
});
- ((ViewPager) container).addView(view, 0);
+ container.addView(view, 0);
if (position == 0) {
ActivityCompat.startPostponedEnterTransition(ArticleImagesPagerActivity.this);
@@ -329,6 +339,7 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
m_pager = (ViewPager) findViewById(R.id.article_images_pager);
m_pager.setAdapter(m_adapter);
m_pager.setPageTransformer(true, new DepthPageTransformer());
+
}
@SuppressLint("NewApi")
@@ -337,7 +348,6 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
super.onResume();
}
-
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
@@ -347,7 +357,6 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
super.onCreateContextMenu(menu, v, menuInfo);
}
-
@Override
public void onSaveInstanceState(Bundle out) {
super.onSaveInstanceState(out);
@@ -358,32 +367,18 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
}
@Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.context_article_content_img, menu);
-
-
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- return onContextItemSelected(item); // this is really bad :()
+ public boolean onContextItemSelected(MenuItem item) {
+ int position = m_pager.getCurrentItem();
+ String url = m_checkedUrls.get(position);
+
+ if (!onImageMenuItemSelected(item, url))
+ return super.onContextItemSelected(item);
+ else
+ return true;
}
- @Override
- public boolean onContextItemSelected(android.view.MenuItem item) {
- ViewPager pager = (ViewPager) findViewById(R.id.article_images_pager);
- String url = null;
-
- if (pager != null) {
- int currentItem = pager.getCurrentItem();
- url = m_urls.get(currentItem);
- }
-
+ public boolean onImageMenuItemSelected(MenuItem item, String url) {
switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
case R.id.article_img_open:
if (url != null) {
try {
@@ -401,56 +396,18 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
return true;
case R.id.article_img_share:
if (url != null) {
- Intent intent = new Intent(Intent.ACTION_SEND);
-
- intent.setType("image/png");
- intent.putExtra(Intent.EXTRA_SUBJECT, url);
- intent.putExtra(Intent.EXTRA_TEXT, url);
-
- startActivity(Intent.createChooser(intent, url));
+ shareText(url);
}
return true;
- // TODO: this needs access to article text, I'm afraid
case R.id.article_img_view_caption:
if (url != null) {
-
- // Android doesn't give us an easy way to access title tags;
- // we'll use Jsoup on the body text to grab the title text
- // from the first image tag with this url. This will show
- // the wrong text if an image is used multiple times.
- Document doc = Jsoup.parse(m_content);
- Elements es = doc.getElementsByAttributeValue("src", url);
- if (es.size() > 0) {
- if (es.get(0).hasAttr("title")) {
- Dialog dia = new Dialog(this);
- if (es.get(0).hasAttr("alt")) {
- dia.setTitle(es.get(0).attr("alt"));
- } else {
- dia.setTitle(es.get(0).attr("title"));
- }
- TextView titleText = new TextView(this);
-
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
- titleText.setPaddingRelative(24, 24, 24, 24);
- } else {
- titleText.setPadding(24, 24, 24, 24);
- }
-
- titleText.setTextSize(16);
- titleText.setText(es.get(0).attr("title"));
- dia.setContentView(titleText);
- dia.show();
- } else {
- toast(R.string.no_caption_to_display);
- }
- } else {
- toast(R.string.no_caption_to_display);
- }
+ displayImageCaption(url, m_content);
}
return true;
default:
- Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId());
- return super.onContextItemSelected(item);
+ Log.d(TAG, "onImageMenuItemSelected, unhandled id=" + item.getItemId());
+ return false;
}
}
+
}
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 6c3f90da..f1c9eab0 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
@@ -81,7 +81,13 @@ public class ArticlePager extends Fragment {
if (savedInstanceState != null) {
m_article = savedInstanceState.getParcelable("article");
- m_articles = ((DetailActivity)m_activity).m_articles;
+
+ if (! (m_activity instanceof DetailActivity)) {
+ m_articles = savedInstanceState.getParcelable("articles");
+ } else {
+ m_articles = ((DetailActivity)m_activity).m_articles;
+ }
+
m_feed = savedInstanceState.getParcelable("feed");
m_firstId = savedInstanceState.getInt("firstId");
}
@@ -159,8 +165,11 @@ public class ArticlePager extends Fragment {
if (result != null) {
- if (m_firstIdChanged) {
- m_articles.add(new Article(HeadlinesFragment.ARTICLE_SPECIAL_TOP_CHANGED));
+ if (m_firstIdChanged && !(m_activity instanceof DetailActivity && !m_activity.isPortrait())) {
+ // TODO: show an information message in viewpager without modifying m_articles
+ //m_articles.add(new Article(HeadlinesFragment.ARTICLE_SPECIAL_TOP_CHANGED));
+
+ m_activity.toast(R.string.headlines_row_top_changed);
}
ArticlePager.this.m_firstId = m_firstId;
@@ -175,7 +184,7 @@ public class ArticlePager extends Fragment {
}
if (m_article != null) {
- if (m_article.id == 0 || m_articles.indexOf(m_article) == -1) {
+ if (m_article.id == 0 || !m_articles.containsId(m_article.id)) {
if (m_articles.size() > 0) {
m_article = m_articles.get(0);
m_listener.onArticleSelected(m_article, false);
@@ -273,6 +282,7 @@ public class ArticlePager extends Fragment {
out.setClassLoader(getClass().getClassLoader());
out.putParcelable("article", m_article);
+ out.putParcelable("articles", m_articles);
out.putParcelable("feed", m_feed);
out.putInt("firstId", m_firstId);
}
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 d70ee8c8..51df75e3 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
@@ -3,6 +3,8 @@ package org.fox.ttrss;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.app.Fragment;
import android.support.v7.widget.SwitchCompat;
import android.util.TypedValue;
@@ -29,6 +31,8 @@ public abstract class BaseFeedlistFragment extends Fragment {
if (true /*m_activity.findViewById(R.id.headlines_drawer) != null*/) {
try {
+ boolean needSettingsFooter = false;
+
if (activity.isSmallScreen()) {
View layout = inflater.inflate(R.layout.drawer_header, list, false);
list.addHeaderView(layout, null, false);
@@ -51,12 +55,19 @@ public abstract class BaseFeedlistFragment extends Fragment {
try {
Intent intent = new Intent(getActivity(),
PreferencesActivity.class);
- startActivityForResult(intent, 0);
- } catch (Exception e) {
+ ActivityOptionsCompat options = ActivityOptionsCompat
+ .makeSceneTransitionAnimation(getActivity(), v, "SETTINGS_REVEAL");
+
+ ActivityCompat.startActivityForResult(getActivity(), intent, 0, options.toBundle());
+
+ } catch (Exception e) {
+ e.printStackTrace();
}
}
});
+ } else {
+ needSettingsFooter = true;
}
/* deal with ~material~ footers */
@@ -101,6 +112,41 @@ public abstract class BaseFeedlistFragment extends Fragment {
});
if (isRoot) {
+ if (needSettingsFooter) {
+ // settings (as a list footer row)
+
+ footer = inflater.inflate(R.layout.feeds_row, list, false);
+ footer.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ try {
+ Intent intent = new Intent(getActivity(),
+ PreferencesActivity.class);
+
+ ActivityOptionsCompat options = ActivityOptionsCompat
+ .makeSceneTransitionAnimation(getActivity(), v, "SETTINGS_REVEAL");
+
+ ActivityCompat.startActivityForResult(getActivity(), intent, 0, options.toBundle());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ list.addFooterView(footer);
+ text = (TextView) footer.findViewById(R.id.title);
+ text.setText(R.string.action_settings);
+
+ icon = (ImageView) footer.findViewById(R.id.icon);
+ tv = new TypedValue();
+ getActivity().getTheme().resolveAttribute(R.attr.ic_settings, tv, true);
+ icon.setImageResource(tv.resourceId);
+
+ TextView counter = (TextView) footer.findViewById(R.id.unread_counter);
+ counter.setText(R.string.blank);
+ }
+
// offline
footer = inflater.inflate(R.layout.feeds_row, list, false);
footer.setOnClickListener(new View.OnClickListener() {
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 9fd90eb5..5811a7f9 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
@@ -28,10 +28,21 @@ import android.util.TypedValue;
import android.view.Display;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.TextView;
import android.widget.Toast;
+import com.nostra13.universalimageloader.cache.disc.impl.ext.LruDiscCache;
+import com.nostra13.universalimageloader.core.DefaultConfigurationFactory;
+import com.nostra13.universalimageloader.core.ImageLoader;
+import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
+
import org.fox.ttrss.util.DatabaseHelper;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.select.Elements;
+import java.io.File;
+import java.io.IOException;
import java.util.Arrays;
public class CommonActivity extends ActionBarActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
@@ -51,6 +62,8 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc
public static final int EXCERPT_MAX_LENGTH = 256;
public static final int EXCERPT_MAX_QUERY_LENGTH = 2048;
+ public static final int PENDING_INTENT_CHROME_SHARE = 1;
+
private DatabaseHelper m_databaseHelper;
//private SQLiteDatabase m_readableDb;
@@ -154,6 +167,23 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc
CustomTabsClient.bindCustomTabsService(this, "com.android.chrome", m_customTabServiceConnection);
+ if (!ImageLoader.getInstance().isInited()) {
+ ImageLoaderConfiguration config;
+
+ try {
+ config = new ImageLoaderConfiguration.Builder(getApplicationContext())
+ .diskCache(
+ new LruDiscCache(new File(getCacheDir(), "article-images"),
+ DefaultConfigurationFactory.createFileNameGenerator(),
+ 100 * 1024 * 1024))
+ .build();
+ } catch (IOException e) {
+ config = new ImageLoaderConfiguration.Builder(getApplicationContext())
+ .build();
+ }
+ ImageLoader.getInstance().init(config);
+ }
+
super.onCreate(savedInstanceState);
}
@@ -237,6 +267,26 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc
}
}
+ protected Intent getShareIntent(String text, String subject) {
+ Intent shareIntent = new Intent(Intent.ACTION_SEND);
+ shareIntent.setType("text/plain");
+ shareIntent.putExtra(Intent.EXTRA_TEXT, text);
+
+ if (subject != null) {
+ shareIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
+ }
+
+ return shareIntent;
+ }
+
+ protected void shareText(String text) {
+ startActivity(Intent.createChooser(getShareIntent(text, null), text));
+ }
+
+ protected void shareText(String text, String subject) {
+ startActivity(Intent.createChooser(getShareIntent(text, subject), text));
+ }
+
private void openUriWithCustomTab(Uri uri) {
if (m_customTabClient != null) {
TypedValue tvBackground = new TypedValue();
@@ -249,27 +299,40 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc
builder.setToolbarColor(tvBackground.data);
- Intent shareIntent = new Intent(Intent.ACTION_SEND);
- shareIntent.setType("text/plain");
- shareIntent.putExtra(Intent.EXTRA_SUBJECT, uri.toString());
- shareIntent.putExtra(Intent.EXTRA_TEXT, uri.toString());
+ Intent shareIntent = getShareIntent(uri.toString(), null);
- PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, shareIntent, 0);
+ PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
+ CommonActivity.PENDING_INTENT_CHROME_SHARE, shareIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setActionButton(BitmapFactory.decodeResource(getResources(), R.drawable.ic_share),
getString(R.string.share_article), pendingIntent);
CustomTabsIntent intent = builder.build();
- intent.launchUrl(this, uri);
+ try {
+ intent.launchUrl(this, uri);
+ } catch (Exception e) {
+ e.printStackTrace();
+ toast(e.getMessage());
+ }
}
}
// uses chrome custom tabs when available
- public void openUri(final Uri uri) {
+ public void openUri(Uri uri) {
boolean enableCustomTabs = m_prefs.getBoolean("enable_custom_tabs", true);
final boolean askEveryTime = m_prefs.getBoolean("custom_tabs_ask_always", true);
+ if (uri.getScheme() == null) {
+ try {
+ uri = Uri.parse("https:" + uri.toString());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ final Uri finalUri = uri;
+
if (enableCustomTabs && m_customTabClient != null) {
if (askEveryTime) {
@@ -279,7 +342,6 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc
AlertDialog.Builder builder = new AlertDialog.Builder(
CommonActivity.this)
- .setTitle(R.string.open_link)
.setView(dialogView)
.setMessage(uri.toString())
.setPositiveButton(R.string.quick_preview,
@@ -293,11 +355,11 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc
editor.apply();
}
- openUriWithCustomTab(uri);
+ openUriWithCustomTab(finalUri);
}
})
- .setNegativeButton(R.string.open_with_app,
+ .setNegativeButton(R.string.open_with,
new Dialog.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
@@ -309,9 +371,14 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc
editor.apply();
}
- Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ Intent intent = new Intent(Intent.ACTION_VIEW, finalUri);
- startActivity(intent);
+ try {
+ startActivity(intent);
+ } catch (Exception e) {
+ e.printStackTrace();
+ toast(e.getMessage());
+ }
}
});
@@ -339,7 +406,43 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc
} else {
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
- startActivity(intent);
+ try {
+ startActivity(intent);
+ } catch (Exception e) {
+ toast(e.getMessage());
+ }
+ }
+ }
+
+ public void displayImageCaption(String url, String htmlContent) {
+ // Android doesn't give us an easy way to access title tags;
+ // we'll use Jsoup on the body text to grab the title text
+ // from the first image tag with this url. This will show
+ // the wrong text if an image is used multiple times.
+ Document doc = Jsoup.parse(htmlContent);
+ Elements es = doc.getElementsByAttributeValue("src", url);
+ if (es.size() > 0) {
+ if (es.get(0).hasAttr("title")) {
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this)
+ .setCancelable(true)
+ .setMessage(es.get(0).attr("title"))
+ .setPositiveButton(R.string.dialog_close, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ }
+ );
+
+ AlertDialog dialog = builder.create();
+ dialog.show();
+
+ } else {
+ toast(R.string.no_caption_to_display);
+ }
+ } else {
+ toast(R.string.no_caption_to_display);
}
}
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 8cab4845..dafcbe66 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java
@@ -279,6 +279,7 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList
Article article = hf.getActiveArticle();
if (article == null && hf.getAllArticles().size() > 0) {
+
article = hf.getAllArticles().get(0);
hf.setActiveArticle(article);
@@ -304,7 +305,12 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList
setResult(Activity.RESULT_OK, resultIntent);
- super.onBackPressed();
+ try {
+ super.onBackPressed();
+ } catch (IllegalStateException e) {
+ // java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
+ e.printStackTrace();
+ }
}
@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 02fd7985..24be6292 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
@@ -315,7 +315,7 @@ public class FeedCategoriesFragment extends BaseFeedlistFragment implements OnIt
@Override
protected void onPostExecute(JsonElement result) {
- if (isDetached()) return;
+ if (isDetached() || !isAdded()) return;
if (m_swipeLayout != null) m_swipeLayout.setRefreshing(false);
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 41c0f69c..6d567ff8 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
@@ -496,7 +496,7 @@ public class FeedsFragment extends BaseFeedlistFragment implements OnItemClickLi
@Override
protected void onPostExecute(JsonElement result) {
- if (isDetached()) return;
+ if (isDetached() || !isAdded()) return;
if (getView() != null) {
View loadingBar = getView().findViewById(R.id.feeds_loading_bar);
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 90f432b4..118d28b8 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
@@ -29,6 +29,7 @@ import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Display;
import android.view.LayoutInflater;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
@@ -43,6 +44,7 @@ import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
+import android.widget.PopupMenu;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -68,7 +70,6 @@ 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 org.jsoup.Jsoup;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
@@ -79,7 +80,7 @@ import java.util.List;
import java.util.TimeZone;
public class HeadlinesFragment extends Fragment implements OnItemClickListener, OnScrollListener {
- public static enum ArticlesSelection { ALL, NONE, UNREAD }
+ public enum ArticlesSelection { ALL, NONE, UNREAD }
public static final int FLAVOR_IMG_MIN_SIZE = 128;
public static final int THUMB_IMG_MIN_SIZE = 32;
@@ -87,8 +88,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
public static final int HEADLINES_REQUEST_SIZE = 30;
public static final int HEADLINES_BUFFER_MAX = 500;
- public static final int ARTICLE_SPECIAL_LOADMORE = -1;
- public static final int ARTICLE_SPECIAL_TOP_CHANGED = -3;
+ //public static final int ARTICLE_SPECIAL_LOADMORE = -1;
+ //public static final int ARTICLE_SPECIAL_TOP_CHANGED = -3;
private final String TAG = this.getClass().getSimpleName();
@@ -98,6 +99,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
private boolean m_refreshInProgress = false;
private boolean m_autoCatchupDisabled = false;
private int m_firstId = 0;
+ private boolean m_lazyLoadDisabled = false;
private SharedPreferences m_prefs;
@@ -114,6 +116,9 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
private int m_listPreviousVisibleItem;
private ListView m_list;
private ImageLoader m_imageLoader = ImageLoader.getInstance();
+ private View m_listLoadingView;
+ private View m_topChangedView;
+ private View m_amrFooterView;
public ArticleList getSelectedArticles() {
ArticleList tmp = new ArticleList();
@@ -142,7 +147,77 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
}
}
- @Override
+ public boolean onArticleMenuItemSelected(MenuItem item, Article article) {
+
+ if (article == null) return false;
+
+ switch (item.getItemId()) {
+ case R.id.set_labels:
+ m_activity.editArticleLabels(article);
+ return true;
+ case R.id.article_set_note:
+ m_activity.editArticleNote(article);
+ return true;
+ case R.id.headlines_article_unread:
+ article.unread = !article.unread;
+ m_activity.saveArticleUnread(article);
+ m_adapter.notifyDataSetChanged();
+ return true;
+ case R.id.headlines_article_link_copy:
+ m_activity.copyToClipboard(article.link);
+ return true;
+ case R.id.headlines_article_link_open:
+ m_activity.openUri(Uri.parse(article.link));
+
+ if (article.unread) {
+ article.unread = false;
+ m_activity.saveArticleUnread(article);
+
+ m_adapter.notifyDataSetChanged();
+ }
+ return true;
+ case R.id.headlines_share_article:
+ m_activity.shareArticle(article);
+ return true;
+ case R.id.catchup_above:
+ if (true) {
+ ArticleList articles = getAllArticles();
+ ArticleList tmp = new ArticleList();
+ for (Article a : articles) {
+ if (article.id == a.id)
+ break;
+
+ if (a.unread) {
+ a.unread = false;
+ tmp.add(a);
+ }
+ }
+ if (tmp.size() > 0) {
+ m_activity.toggleArticlesUnread(tmp);
+ //updateHeadlines();
+ }
+ m_adapter.notifyDataSetChanged();
+ }
+ return true;
+ default:
+ Log.d(TAG, "onArticleMenuItemSelected, unhandled id=" + item.getItemId());
+ return false;
+ }
+ }
+
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
+ .getMenuInfo();
+
+ Article article = getArticleAtPosition(info.position);
+
+ if (!onArticleMenuItemSelected(item, article))
+ return super.onContextItemSelected(item);
+ else
+ return true;
+ }
+
+ /*@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
@@ -291,7 +366,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId());
return super.onContextItemSelected(item);
}
- }
+ } */
public HeadlinesFragment() {
super();
@@ -310,22 +385,10 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
getActivity().getMenuInflater().inflate(R.menu.context_headlines, menu);
- if (getSelectedArticles().size() > 0) {
- menu.setHeaderTitle(R.string.headline_context_multiple);
- menu.setGroupVisible(R.id.menu_group_single_article, false);
- } else {
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
- Article article = getArticleAtPosition(info.position);
-
- menu.setHeaderTitle(Html.fromHtml(article.title));
- menu.setGroupVisible(R.id.menu_group_single_article, true);
- }
-
menu.findItem(R.id.set_labels).setEnabled(m_activity.getApiLevel() >= 1);
menu.findItem(R.id.article_set_note).setEnabled(m_activity.getApiLevel() >= 1);
super.onCreateContextMenu(menu, v, menuInfo);
-
}
@Override
@@ -345,6 +408,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
m_searchQuery = (String) savedInstanceState.getCharSequence("searchQuery");
m_compactLayoutMode = savedInstanceState.getBoolean("compactLayoutMode");
m_firstId = savedInstanceState.getInt("firstId");
+ m_lazyLoadDisabled = savedInstanceState.getBoolean("lazyLoadDisabled");
}
String headlineMode = m_prefs.getString("headline_mode", "HL_DEFAULT");
@@ -372,24 +436,37 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
m_list = (ListView)view.findViewById(R.id.headlines_list);
FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.headlines_fab);
- m_list.setOnTouchListener(new ShowHideOnScroll(fab));
- fab.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- refresh(false);
- }
- });
- if (m_prefs.getBoolean("headlines_mark_read_scroll", false)) {
+ if (! (getActivity() instanceof DetailActivity)) {
+
+ m_list.setOnTouchListener(new ShowHideOnScroll(fab));
+ fab.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ refresh(false);
+ }
+ });
+ } else {
+ fab.setVisibility(View.GONE);
+ }
+
+ m_listLoadingView = inflater.inflate(R.layout.headlines_row_loadmore, m_list, false);
+ //m_list.addFooterView(m_listLoadingView, null, false);
+ //m_listLoadingView.setVisibility(View.GONE);
+
+ m_topChangedView = inflater.inflate(R.layout.headlines_row_top_changed, m_list, false);
+ //m_list.addFooterView(m_topChangedView, null, false);
+ //m_topChangedView.setVisibility(View.GONE);*/
+
+ if (m_prefs.getBoolean("headlines_mark_read_scroll", false)) {
WindowManager wm = (WindowManager) m_activity.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int screenHeight = display.getHeight();
- View layout = inflater.inflate(R.layout.headlines_footer, container, false);
-
- layout.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, screenHeight));
+ m_amrFooterView = inflater.inflate(R.layout.headlines_footer, container, false);
+ m_amrFooterView.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, screenHeight));
- m_list.addFooterView(layout, null, false);
+ m_list.addFooterView(m_amrFooterView, null, false);
}
if (m_activity.isSmallScreen()) {
@@ -401,7 +478,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
m_activity.getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_padding_end_material));
}
- m_adapter = new ArticleListAdapter(getActivity(), R.layout.headlines_row, (ArrayList<Article>)m_articles);
+ m_adapter = new ArticleListAdapter(getActivity(), R.layout.headlines_row, m_articles);
m_animationAdapter = new SwingBottomInAnimationAdapter(m_adapter);
m_animationAdapter.setAbsListView(m_list);
@@ -492,6 +569,12 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
@SuppressWarnings({ "serial" })
public void refresh(boolean append, boolean userInitiated) {
+ m_list.removeFooterView(m_listLoadingView);
+ m_list.removeFooterView(m_topChangedView);
+ m_list.removeFooterView(m_amrFooterView);
+
+ if (!append) m_lazyLoadDisabled = false;
+
if (m_activity != null && m_feed != null) {
m_refreshInProgress = true;
@@ -530,18 +613,33 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
super.onPostExecute(result);
- if (isAdded()) {
- if (m_swipeLayout != null) m_swipeLayout.setRefreshing(false);
- }
+ if (m_swipeLayout != null) m_swipeLayout.setRefreshing(false);
+
+ //m_listLoadingView.setVisibility(View.GONE);
+ m_list.removeFooterView(m_listLoadingView);
+ m_list.removeFooterView(m_topChangedView);
+ m_list.removeFooterView(m_amrFooterView);
if (result != null) {
m_refreshInProgress = false;
- if (m_articles.indexOf(m_activeArticle) == -1)
+ if (m_activeArticle != null && !m_articles.containsId(m_activeArticle.id)) {
m_activeArticle = null;
+ }
if (m_firstIdChanged) {
- m_articles.add(new Article(ARTICLE_SPECIAL_TOP_CHANGED));
+ m_lazyLoadDisabled = true;
+
+ //m_activity.toast(R.string.headlines_row_top_changed);
+
+ //m_topChangedView.setVisibility(View.VISIBLE);
+ //m_articles.add(new Article(ARTICLE_SPECIAL_TOP_CHANGED));
+
+ m_list.addFooterView(m_topChangedView, null, false);
+ }
+
+ if (m_amountLoaded < HEADLINES_REQUEST_SIZE) {
+ m_lazyLoadDisabled = true;
}
HeadlinesFragment.this.m_firstId = m_firstId;
@@ -552,7 +650,11 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
// not sure why but listview sometimes gets positioned while ignoring the header so
// top headline content becomes partially obscured by the toolbar on phones
// (not reproducible on avd)
- if (!fappend) m_list.smoothScrollToPosition(0);
+ if (!fappend) {
+ m_list.smoothScrollToPosition(0);
+ }
+
+ //m_listLoadingView.setVisibility(m_amountLoaded == HEADLINES_REQUEST_SIZE ? View.VISIBLE : View.GONE);
} else {
if (m_lastError == ApiError.LOGIN_FAILED) {
@@ -568,6 +670,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
//m_activity.setLoadingStatus(getErrorMessage(), false);
}
}
+
+ if (m_amrFooterView != null) m_list.addFooterView(m_amrFooterView, null, false);
}
};
@@ -596,7 +700,12 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
} else {
skip = numAll;
}
-
+
+ if (skip > 0) {
+ m_list.addFooterView(m_listLoadingView, null, false);
+ //m_listLoadingView.setVisibility(View.VISIBLE);
+ }
+
} else {
//m_activity.setLoadingStatus(R.string.blank, true);
}
@@ -666,6 +775,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
out.putCharSequence("searchQuery", m_searchQuery);
out.putBoolean("compactLayoutMode", m_compactLayoutMode);
out.putInt("firstId", m_firstId);
+ out.putBoolean("lazyLoadDisabled", m_lazyLoadDisabled);
}
static class HeadlineViewHolder {
@@ -687,6 +797,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
public ImageView textChecked;
public View headlineHeader;
public View topChangedMessage;
+ public View flavorImageOverflow;
public int position;
public boolean flavorImageEmbedded;
}
@@ -698,10 +809,10 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
public static final int VIEW_UNREAD = 1;
public static final int VIEW_SELECTED = 2;
public static final int VIEW_SELECTED_UNREAD = 3;
- public static final int VIEW_LOADMORE = 4;
- public static final int VIEW_TOP_CHANGED = 5;
+ //public static final int VIEW_LOADMORE = 4;
+ //public static final int VIEW_TOP_CHANGED = 4;
- public static final int VIEW_COUNT = VIEW_TOP_CHANGED+1;
+ public static final int VIEW_COUNT = VIEW_SELECTED_UNREAD + 1;
private final Integer[] origTitleColors = new Integer[VIEW_COUNT];
private final int titleHighScoreUnreadColor;
@@ -754,11 +865,11 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
public int getItemViewType(int position) {
Article a = items.get(position);
- if (a.id == ARTICLE_SPECIAL_LOADMORE) {
- return VIEW_LOADMORE;
- } else if (a.id == ARTICLE_SPECIAL_TOP_CHANGED) {
+ /*if (a.id == ARTICLE_SPECIAL_LOADMORE) {
+ return VIEW_LOADMORE; */
+ /*if (a.id == ARTICLE_SPECIAL_TOP_CHANGED) {
return VIEW_TOP_CHANGED;
- } else if (m_activeArticle != null && a.id == m_activeArticle.id && a.unread) {
+ } else */ if (m_activeArticle != null && a.id == m_activeArticle.id && a.unread) {
return VIEW_SELECTED_UNREAD;
} else if (m_activeArticle != null && a.id == m_activeArticle.id) {
return VIEW_SELECTED;
@@ -769,7 +880,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
}
}
- private void updateTextCheckedState(final HeadlineViewHolder holder, final Article article, int position) {
+ private void updateTextCheckedState(final HeadlineViewHolder holder, final Article article, final int position) {
String tmp = article.title.length() > 0 ? article.title.substring(0, 1).toUpperCase() : "?";
if (article.selected) {
@@ -791,7 +902,6 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
} else {
if (!article.flavorImageUri.equals(holder.textImage.getTag())) {
- final int loadingPosition = position;
ImageAware imageAware = new ImageViewAware(holder.textImage, false);
DisplayImageOptions options = new DisplayImageOptions.Builder()
@@ -817,7 +927,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap bitmap) {
- if (loadingPosition == holder.position && bitmap != null) {
+ if (position == holder.position && bitmap != null) {
holder.textImage.setTag(article.flavorImageUri);
if (bitmap.getWidth() < THUMB_IMG_MIN_SIZE || bitmap.getHeight() < THUMB_IMG_MIN_SIZE) {
@@ -841,7 +951,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
}
@Override
- public View getView(final int position, View convertView, ViewGroup parent) {
+ public View getView(final int position, final View convertView, ViewGroup parent) {
View v = convertView;
@@ -855,12 +965,12 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
int layoutId = m_compactLayoutMode ? R.layout.headlines_row_compact : R.layout.headlines_row;
switch (getItemViewType(position)) {
- case VIEW_LOADMORE:
+ /*case VIEW_LOADMORE:
layoutId = R.layout.headlines_row_loadmore;
break;
case VIEW_TOP_CHANGED:
layoutId = R.layout.headlines_row_top_changed;
- break;
+ break;*/
case VIEW_UNREAD:
layoutId = m_compactLayoutMode ? R.layout.headlines_row_unread_compact : R.layout.headlines_row_unread;
break;
@@ -895,6 +1005,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
holder.textChecked = (ImageView) v.findViewById(R.id.text_checked);
holder.headlineHeader = v.findViewById(R.id.headline_header);
holder.topChangedMessage = v.findViewById(R.id.headlines_row_top_changed);
+ holder.flavorImageOverflow = v.findViewById(R.id.flavor_image_overflow);
v.setTag(holder);
@@ -904,6 +1015,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
holder = (HeadlineViewHolder) v.getTag();
}
+ //Log.d(TAG, "getView: " + position + ":" + article.title);
+
holder.position = position;
// block footer clicks to make button/selection clicking easier
@@ -942,7 +1055,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
Log.d(TAG, "num selected: " + getSelectedArticles().size());
}
});
- ViewCompat.setTransitionName(holder.textImage, "TRANSITION:ARTICLE_IMAGES_PAGER");
+ ViewCompat.setTransitionName(holder.textImage, "gallery:" + article.flavorImageUri);
if (article.flavorImage != null) {
@@ -1034,11 +1147,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
String excerpt;
try {
- if (m_activity.getApiLevel() >= 11) {
- excerpt = article.excerpt != null ? article.excerpt : "";
- excerpt = excerpt.replace("&hellip;", "…");
- excerpt = excerpt.replace("]]>", "");
- excerpt = Jsoup.parse(excerpt).text();
+ if (article.excerpt != null) {
+ excerpt = article.excerpt;
} else {
excerpt = article.articleDoc.text();
@@ -1068,16 +1178,10 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
holder.flavorImageLoadingBar.setVisibility(View.GONE);
holder.flavorImageView.setVisibility(View.GONE);
holder.flavorVideoKindView.setVisibility(View.GONE);
+ holder.flavorImageOverflow.setVisibility(View.GONE);
holder.headlineHeader.setBackgroundDrawable(null);
- holder.headlineHeader.setOnLongClickListener(new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- m_activity.openContextMenu(v);
- return true;
- }
- });
-
+ // this is needed if our flavor image goes behind base listview element
holder.headlineHeader.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@@ -1085,22 +1189,66 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
}
});
- holder.flavorImageView.setOnLongClickListener(new View.OnLongClickListener() {
+ holder.headlineHeader.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
m_activity.openContextMenu(v);
+
return true;
}
});
if (showFlavorImage && article.flavorImageUri != null && holder.flavorImageView != null) {
+ if (holder.flavorImageOverflow != null) {
+ holder.flavorImageOverflow.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ PopupMenu popup = new PopupMenu(getActivity(), holder.flavorImageOverflow);
+ MenuInflater inflater = popup.getMenuInflater();
+ inflater.inflate(R.menu.context_article_content_img, popup.getMenu());
+
+ popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.article_img_open:
+ m_activity.openUri(Uri.parse(article.flavorImageUri));
+ return true;
+ case R.id.article_img_copy:
+ m_activity.copyToClipboard(article.flavorImageUri);
+ return true;
+ case R.id.article_img_share:
+ m_activity.shareText(article.flavorImageUri);
+ return true;
+ case R.id.article_img_view_caption:
+ m_activity.displayImageCaption(article.flavorImageUri, article.content);
+ return true;
+ default:
+ return false;
+ }
+ }
+ });
+
+ popup.show();
+ }
+ });
+
+ holder.flavorImageView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+
+ m_activity.openContextMenu(v);
+
+ return true;
+ }
+ });
+ }
if (!article.flavorImageUri.equals(holder.flavorImageView.getTag())) {
//Log.d(TAG, "IMG: " + article.flavorImageUri + " STREAM: " + article.flavorStreamUri);
ImageAware imageAware = new ImageViewAware(holder.flavorImageView, false);
- final int loadingPosition = position;
m_imageLoader.displayImage(article.flavorImageUri, imageAware, displayImageOptions, new ImageLoadingListener() {
@Override
@@ -1117,13 +1265,15 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap bitmap) {
- if (loadingPosition == holder.position && bitmap != null) {
+ if (position == holder.position && bitmap != null) {
holder.flavorImageLoadingBar.setVisibility(View.GONE);
- holder.flavorImageView.setTag(article.flavorImageUri);
if (bitmap.getWidth() > FLAVOR_IMG_MIN_SIZE && bitmap.getHeight() > FLAVOR_IMG_MIN_SIZE) {
+ holder.flavorImageView.setTag(article.flavorImageUri);
+
holder.flavorImageView.setVisibility(View.VISIBLE);
+ holder.flavorImageOverflow.setVisibility(View.VISIBLE);
maybeRepositionFlavorImage(view, bitmap, holder);
adjustVideoKindView(holder, article);
@@ -1142,7 +1292,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
@Override
public void onProgressUpdate(String s, View view, int current, int total) {
if (total != 0) {
- int p = (int)((float)current/total*100);
+ int p = (int) ((float) current / total * 100);
holder.flavorImageLoadingBar.setIndeterminate(false);
holder.flavorImageLoadingBar.setProgress(p);
@@ -1154,6 +1304,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
} else { // already tagged
holder.flavorImageView.setVisibility(View.VISIBLE);
+ holder.flavorImageOverflow.setVisibility(View.VISIBLE);
adjustVideoKindView(holder, article);
@@ -1162,6 +1313,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
if (m_activity.getTheme().resolveAttribute(R.attr.headlineHeaderBackground, tv, true)) {
holder.headlineHeader.setBackgroundColor(tv.data);
}
+ } else {
+ holder.headlineHeader.setBackgroundDrawable(null);
}
}
}
@@ -1215,11 +1368,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
public void onClick(View view) {
CheckBox cb = (CheckBox)view;
- if (cb.isChecked()) {
- article.selected = true;
- } else {
- article.selected = false;
- }
+ article.selected = cb.isChecked();
m_listener.onArticleListSelectionChange(getSelectedArticles());
@@ -1235,7 +1384,22 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
holder.menuButtonView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- getActivity().openContextMenu(v);
+
+ PopupMenu popup = new PopupMenu(getActivity(), v);
+ MenuInflater inflater = popup.getMenuInflater();
+ inflater.inflate(R.menu.context_headlines, popup.getMenu());
+
+ popup.getMenu().findItem(R.id.set_labels).setEnabled(m_activity.getApiLevel() >= 1);
+ popup.getMenu().findItem(R.id.article_set_note).setEnabled(m_activity.getApiLevel() >= 1);
+
+ popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ return onArticleMenuItemSelected(item, article);
+ }
+ });
+
+ popup.show();
}
});
}
@@ -1264,9 +1428,17 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
Intent intent = new Intent(m_activity, VideoPlayerActivity.class);
intent.putExtra("streamUri", article.flavorStreamUri);
intent.putExtra("title", article.title);
+ intent.putExtra("coverSrc", article.flavorImageUri);
- startActivity(intent);
- m_activity.overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
+ //startActivity(intent);
+ //m_activity.overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
+
+ ActivityOptionsCompat options =
+ ActivityOptionsCompat.makeSceneTransitionAnimation(m_activity,
+ transitionView != null ? transitionView : holder.flavorImageView,
+ "gallery:" + article.flavorImageUri);
+
+ ActivityCompat.startActivity(m_activity, intent, options.toBundle());
} else {
@@ -1278,9 +1450,9 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation(m_activity,
- transitionView != null ? transitionView : holder.flavorImageView, // The view which starts the transition
- "TRANSITION:ARTICLE_IMAGES_PAGER" // The transitionName of the view we’re transitioning to
- );
+ transitionView != null ? transitionView : holder.flavorImageView,
+ "gallery:" + article.flavorImageUri);
+
ActivityCompat.startActivity(m_activity, intent, options.toBundle());
}
@@ -1444,10 +1616,6 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
- if (!m_refreshInProgress && m_articles.findById(ARTICLE_SPECIAL_LOADMORE) != null && firstVisibleItem + visibleItemCount == m_articles.size()) {
- refresh(true);
- }
-
if (m_prefs.getBoolean("headlines_mark_read_scroll", false) && firstVisibleItem > (m_activity.isSmallScreen() ? 1 : 0) && !m_autoCatchupDisabled) {
Article a = (Article) view.getItemAtPosition(firstVisibleItem - 1);
@@ -1473,6 +1641,10 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
m_listPreviousVisibleItem = firstVisibleItem;
}
+
+ if (!m_refreshInProgress && !m_lazyLoadDisabled && /*m_articles.findById(ARTICLE_SPECIAL_LOADMORE) != null &&*/ firstVisibleItem + visibleItemCount == m_articles.size()) {
+ refresh(true);
+ }
}
@Override
@@ -1521,7 +1693,11 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
public void setSearchQuery(String query) {
if (!m_searchQuery.equals(query)) {
m_searchQuery = query;
- refresh(false);
+
+ // could be called before fragment view has been initialized
+ if (m_list != null) {
+ refresh(false);
+ }
}
}
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 1515883c..51781582 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java
@@ -387,7 +387,12 @@ public class MasterActivity extends OnlineActivity implements HeadlinesEventList
m_drawerLayout.openDrawer(Gravity.START);
} else {
- super.onBackPressed();
+ try {
+ super.onBackPressed();
+ } catch (IllegalStateException e) {
+ // java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
+ e.printStackTrace();
+ }
}
}
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 0039d3ea..355c5a58 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
@@ -168,23 +168,6 @@ public class OnlineActivity extends CommonActivity {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
- if (!ImageLoader.getInstance().isInited()) {
- ImageLoaderConfiguration config;
-
- try {
- config = new ImageLoaderConfiguration.Builder(getApplicationContext())
- .diskCache(
- new LruDiscCache(new File(getCacheDir(), "article-images"),
- DefaultConfigurationFactory.createFileNameGenerator(),
- 100 * 1024 * 1024))
- .build();
- } catch (IOException e) {
- config = new ImageLoaderConfiguration.Builder(getApplicationContext())
- .build();
- }
- ImageLoader.getInstance().init(config);
- }
-
//m_pullToRefreshAttacher = PullToRefreshAttacher.get(this);
if (isOffline) {
@@ -289,8 +272,12 @@ public class OnlineActivity extends CommonActivity {
@Override
public void onPause() {
super.onPause();
-
- unregisterReceiver(m_broadcastReceiver);
+
+ try {
+ unregisterReceiver(m_broadcastReceiver);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ }
}
@Override
@@ -546,50 +533,12 @@ public class OnlineActivity extends CommonActivity {
return true;
case R.id.article_img_share:
if (getLastContentImageHitTestUrl() != null) {
- Intent intent = new Intent(Intent.ACTION_SEND);
-
- intent.setType("image/png");
- intent.putExtra(Intent.EXTRA_SUBJECT, getLastContentImageHitTestUrl());
- intent.putExtra(Intent.EXTRA_TEXT, getLastContentImageHitTestUrl());
-
- startActivity(Intent.createChooser(intent, getLastContentImageHitTestUrl()));
+ shareText(getLastContentImageHitTestUrl());
}
return true;
case R.id.article_img_view_caption:
if (getLastContentImageHitTestUrl() != null) {
-
- // Android doesn't give us an easy way to access title tags;
- // we'll use Jsoup on the body text to grab the title text
- // from the first image tag with this url. This will show
- // the wrong text if an image is used multiple times.
- Document doc = Jsoup.parse(ap.getSelectedArticle().content);
- Elements es = doc.getElementsByAttributeValue("src", getLastContentImageHitTestUrl());
- if (es.size() > 0){
- if (es.get(0).hasAttr("title")){
- Dialog dia = new Dialog(this);
- if (es.get(0).hasAttr("alt")){
- dia.setTitle(es.get(0).attr("alt"));
- } else {
- dia.setTitle(es.get(0).attr("title"));
- }
- TextView titleText = new TextView(this);
-
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
- titleText.setPaddingRelative(24, 24, 24, 24);
- } else {
- titleText.setPadding(24, 24, 24, 24);
- }
-
- titleText.setTextSize(16);
- titleText.setText(es.get(0).attr("title"));
- dia.setContentView(titleText);
- dia.show();
- } else {
- toast(R.string.no_caption_to_display);
- }
- } else {
- toast(R.string.no_caption_to_display);
- }
+ displayImageCaption(getLastContentImageHitTestUrl(), ap.getSelectedArticle().content);
}
return true;
case R.id.article_link_share:
@@ -598,7 +547,6 @@ public class OnlineActivity extends CommonActivity {
}
return true;
case R.id.article_link_copy:
- Log.d(TAG, "article_link_copy");
if (ap != null && ap.getSelectedArticle() != null) {
copyToClipboard(ap.getSelectedArticle().link);
}
@@ -1362,36 +1310,12 @@ public class OnlineActivity extends CommonActivity {
return tmp.replaceAll(",$", "");
}
- public void shareText(String text) {
-
- Intent intent = new Intent(Intent.ACTION_SEND);
-
- intent.setType("text/plain");
- intent.putExtra(Intent.EXTRA_TEXT, text);
-
- startActivity(Intent.createChooser(intent, text));
- }
-
public void shareArticle(Article article) {
if (article != null) {
-
- Intent intent = getShareIntent(article);
-
- startActivity(Intent.createChooser(intent,
- getString(R.string.share_article)));
+ shareText(article.link, article.title);
}
}
-
- protected Intent getShareIntent(Article article) {
- Intent intent = new Intent(Intent.ACTION_SEND);
- intent.setType("text/plain");
- intent.putExtra(Intent.EXTRA_SUBJECT, article.title);
- intent.putExtra(Intent.EXTRA_TEXT, article.link);
-
- return intent;
- }
-
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (m_prefs.getBoolean("use_volume_keys", false)) {
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesActivity.java
index 9e030748..61f914bd 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesActivity.java
@@ -23,6 +23,7 @@ public class PreferencesActivity extends CommonActivity {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
+ getSupportActionBar().hide();
android.app.FragmentTransaction ft = getFragmentManager().beginTransaction();
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java
index 4b89905b..348f36c9 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java
@@ -2,21 +2,33 @@ package org.fox.ttrss;
import android.content.Intent;
import android.content.res.Configuration;
+import android.graphics.Bitmap;
import android.graphics.Rect;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.view.WindowCompat;
import android.support.v7.widget.Toolbar;
+import android.transition.Explode;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Display;
import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
+import android.widget.ImageView;
import android.widget.MediaController;
+import android.widget.PopupMenu;
+
+import com.nostra13.universalimageloader.core.ImageLoader;
+import com.nostra13.universalimageloader.core.assist.FailReason;
+import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import java.io.IOException;
@@ -27,6 +39,7 @@ public class VideoPlayerActivity extends CommonActivity {
private String m_streamUri;
private MediaPlayer mediaPlayer;
private SurfaceView surfaceView;
+ private String m_coverUri;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -40,9 +53,7 @@ public class VideoPlayerActivity extends CommonActivity {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
- if (!isPortrait())
- getSupportActionBar().hide();
+ getSupportActionBar().hide();
surfaceView = (SurfaceView) findViewById(R.id.video_player);
registerForContextMenu(surfaceView);
@@ -51,10 +62,66 @@ public class VideoPlayerActivity extends CommonActivity {
if (savedInstanceState == null) {
m_streamUri = getIntent().getStringExtra("streamUri");
+ m_coverUri = getIntent().getStringExtra("coverSrc");
} else {
m_streamUri = savedInstanceState.getString("streamUri");
+ m_coverUri = savedInstanceState.getString("coverSrc");
}
+ ImageView coverView = (ImageView)findViewById(R.id.video_player_cover);
+
+ if (m_coverUri != null) {
+ ActivityCompat.postponeEnterTransition(VideoPlayerActivity.this);
+
+ ViewCompat.setTransitionName(coverView, "gallery:" + m_coverUri);
+
+ ImageLoader imageLoader = ImageLoader.getInstance();
+ imageLoader.displayImage(m_coverUri, coverView, new ImageLoadingListener() {
+ @Override
+ public void onLoadingStarted(String s, View view) {
+ ActivityCompat.startPostponedEnterTransition(VideoPlayerActivity.this);
+ }
+
+ @Override
+ public void onLoadingFailed(String s, View view, FailReason failReason) {
+ ActivityCompat.startPostponedEnterTransition(VideoPlayerActivity.this);
+ }
+
+ @Override
+ public void onLoadingComplete(String s, View view, Bitmap bitmap) {
+ ActivityCompat.startPostponedEnterTransition(VideoPlayerActivity.this);
+ }
+
+ @Override
+ public void onLoadingCancelled(String s, View view) {
+ ActivityCompat.startPostponedEnterTransition(VideoPlayerActivity.this);
+ }
+ });
+
+
+ } else {
+ coverView.setVisibility(View.GONE);
+ }
+
+ findViewById(R.id.video_player_overflow).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ PopupMenu popup = new PopupMenu(VideoPlayerActivity.this, v);
+ MenuInflater inflater = popup.getMenuInflater();
+ inflater.inflate(R.menu.activity_video_player, popup.getMenu());
+
+ popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ return onVideoMenuItemSelected(item);
+ }
+ });
+
+ popup.show();
+
+ }
+ });
+
final MediaController mediaController = new MediaController(this);
surfaceView.setOnClickListener(new View.OnClickListener() {
@@ -149,17 +216,22 @@ public class VideoPlayerActivity extends CommonActivity {
e.printStackTrace();
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
- @Override
- public void onPrepared(MediaPlayer mp) {
+ @Override
+ public void onPrepared(MediaPlayer mp) {
+
+ View loadingBar = findViewById(R.id.video_loading);
+ if (loadingBar != null)
+ loadingBar.setVisibility(View.GONE);
- View loadingBar = findViewById(R.id.video_loading);
- if (loadingBar != null) loadingBar.setVisibility(View.GONE);
+ View coverView = findViewById(R.id.video_player_cover);
+ if (coverView != null)
+ coverView.setVisibility(View.GONE);
- resizeSurface();
- mp.setLooping(true);
- mp.start();
- }
- }
+ resizeSurface();
+ mp.setLooping(true);
+ mp.start();
+ }
+ }
);
}
@@ -176,17 +248,13 @@ public class VideoPlayerActivity extends CommonActivity {
});
- mediaController.setAnchorView(surfaceView);
+ mediaController.setAnchorView(surfaceView);
+
}
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- if (!isPortrait())
- getSupportActionBar().hide();
- else
- getSupportActionBar().show();
-
resizeSurface();
}
@@ -195,13 +263,7 @@ public class VideoPlayerActivity extends CommonActivity {
super.onSaveInstanceState(out);
out.putString("streamUri", m_streamUri);
- }
-
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.activity_video_player, menu);
- return true;
+ out.putString("coverSrc", m_coverUri);
}
@@ -216,16 +278,15 @@ public class VideoPlayerActivity extends CommonActivity {
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- return onContextItemSelected(item); // this is really bad :()
+ public boolean onContextItemSelected(MenuItem item) {
+ if (!onVideoMenuItemSelected(item))
+ return super.onContextItemSelected(item);
+ else
+ return true;
}
- @Override
- public boolean onContextItemSelected(android.view.MenuItem item) {
+ public boolean onVideoMenuItemSelected(android.view.MenuItem item) {
switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
case R.id.article_vid_open:
if (m_streamUri != null) {
try {
@@ -236,20 +297,19 @@ public class VideoPlayerActivity extends CommonActivity {
}
}
return true;
+ case R.id.article_vid_copy:
+ if (m_streamUri != null) {
+ copyToClipboard(m_streamUri);
+ }
+ return true;
case R.id.article_vid_share:
if (m_streamUri != null) {
- Intent intent = new Intent(Intent.ACTION_SEND);
-
- intent.setType("text/plain");
- intent.putExtra(Intent.EXTRA_SUBJECT, m_streamUri);
- intent.putExtra(Intent.EXTRA_TEXT, m_streamUri);
-
- startActivity(Intent.createChooser(intent, m_streamUri));
+ shareText(m_streamUri);
}
return true;
default:
- Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId());
- return super.onContextItemSelected(item);
+ Log.d(TAG, "onVideoMenuItemSelected, unhandled id=" + item.getItemId());
+ return false;
}
}
@@ -278,14 +338,13 @@ public class VideoPlayerActivity extends CommonActivity {
surfaceView.setLayoutParams(lp);
}
- @Override
+ /*@Override
public void onPause() {
super.onPause();
if (isFinishing()) {
- overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
- }
- }
+ }
+ }*/
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java
index fc26e38e..a120f761 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java
@@ -112,13 +112,7 @@ public class YoutubePlayerActivity extends CommonActivity implements YouTubePlay
return true;
case R.id.article_vid_share:
if (m_streamUri != null) {
- Intent intent = new Intent(Intent.ACTION_SEND);
-
- intent.setType("text/plain");
- intent.putExtra(Intent.EXTRA_SUBJECT, m_streamUri);
- intent.putExtra(Intent.EXTRA_TEXT, m_streamUri);
-
- startActivity(Intent.createChooser(intent, m_streamUri));
+ shareText(m_streamUri);
}
return true;
default:
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineActivity.java
index 4575dd22..762d85d2 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineActivity.java
@@ -97,13 +97,7 @@ public class OfflineActivity extends CommonActivity {
return true;
case R.id.article_img_share:
if (getLastContentImageHitTestUrl() != null) {
- Intent intent = new Intent(Intent.ACTION_SEND);
-
- intent.setType("image/png");
- intent.putExtra(Intent.EXTRA_SUBJECT, getLastContentImageHitTestUrl());
- intent.putExtra(Intent.EXTRA_TEXT, getLastContentImageHitTestUrl());
-
- startActivity(Intent.createChooser(intent, getLastContentImageHitTestUrl()));
+ shareText(getLastContentImageHitTestUrl());
}
return true;
case R.id.article_img_view_caption:
@@ -117,39 +111,8 @@ public class OfflineActivity extends CommonActivity {
content = article.getString(article.getColumnIndex("content"));
article.close();
}
-
- // Android doesn't give us an easy way to access title tags;
- // we'll use Jsoup on the body text to grab the title text
- // from the first image tag with this url. This will show
- // the wrong text if an image is used multiple times.
- Document doc = Jsoup.parse(content);
- Elements es = doc.getElementsByAttributeValue("src", getLastContentImageHitTestUrl());
- if (es.size() > 0){
- if (es.get(0).hasAttr("title")){
- Dialog dia = new Dialog(this);
- if (es.get(0).hasAttr("alt")){
- dia.setTitle(es.get(0).attr("alt"));
- } else {
- dia.setTitle(es.get(0).attr("title"));
- }
- TextView titleText = new TextView(this);
-
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
- titleText.setPaddingRelative(24, 24, 24, 24);
- } else {
- titleText.setPadding(24, 24, 24, 24);
- }
-
- titleText.setTextSize(16);
- titleText.setText(es.get(0).attr("title"));
- dia.setContentView(titleText);
- dia.show();
- } else {
- toast(R.string.no_caption_to_display);
- }
- } else {
- toast(R.string.no_caption_to_display);
- }
+
+ displayImageCaption(getLastContentImageHitTestUrl(), content);
}
return true;
default:
@@ -697,14 +660,8 @@ public class OfflineActivity extends CommonActivity {
if (article != null) {
String title = article.getString(article.getColumnIndex("title"));
String link = article.getString(article.getColumnIndex("link"));
-
- Intent intent = new Intent(Intent.ACTION_SEND);
-
- intent.setType("text/plain");
- intent.putExtra(Intent.EXTRA_SUBJECT, title);
- intent.putExtra(Intent.EXTRA_TEXT, link);
-
- return intent;
+
+ return getShareIntent(link, title);
} else {
return null;
}
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 d71d38b6..9c7974ea 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
@@ -2,15 +2,14 @@ package org.fox.ttrss.offline;
import android.annotation.SuppressLint;
import android.app.Activity;
-import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
+import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.support.v4.app.Fragment;
-import android.support.v4.widget.NestedScrollView;
import android.support.v7.app.ActionBar;
import android.util.Log;
import android.util.TypedValue;
@@ -31,9 +30,10 @@ import android.widget.TextView;
import com.shamanland.fab.ShowHideOnScroll;
+import org.fox.ttrss.CommonActivity;
import org.fox.ttrss.R;
import org.fox.ttrss.util.ImageCacheService;
-import org.fox.ttrss.util.NoChildFocusScrollView;
+import org.fox.ttrss.util.NotifyingScrollView;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
@@ -136,25 +136,25 @@ public class OfflineArticleFragment extends Fragment {
if (m_cursor.isFirst()) {
final String link = m_cursor.getString(m_cursor.getColumnIndex("link"));
- NoChildFocusScrollView scrollView = (NoChildFocusScrollView) view.findViewById(R.id.article_scrollview);
+ NotifyingScrollView scrollView = (NotifyingScrollView) view.findViewById(R.id.article_scrollview);
View fab = view.findViewById(R.id.article_fab);
if (scrollView != null && m_activity.isSmallScreen()) {
view.findViewById(R.id.article_heading_spacer).setVisibility(View.VISIBLE);
- scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
- @Override
- public void onScrollChange(NestedScrollView who, int l, int t, int oldl, int oldt) {
- ActionBar ab = m_activity.getSupportActionBar();
+ scrollView.setOnScrollChangedListener(new NotifyingScrollView.OnScrollChangedListener() {
+ @Override
+ public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt) {
+ ActionBar ab = m_activity.getSupportActionBar();
- if (t >= oldt && t >= ab.getHeight()) {
- ab.hide();
- } else if (t <= ab.getHeight() || oldt - t >= 10) {
- ab.show();
- }
+ if (t >= oldt && t >= ab.getHeight()) {
+ ab.hide();
+ } else if (t <= ab.getHeight() || oldt - t >= 10) {
+ ab.show();
+ }
- }
- });
+ }
+ });
}
if (scrollView != null && fab != null) {
@@ -199,23 +199,18 @@ public class OfflineArticleFragment extends Fragment {
title.setText(titleStr);
//title.setPaintFlags(title.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
- title.setOnClickListener(new OnClickListener() {
+ title.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
- URL url = new URL(link.trim());
- String uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),
- url.getPort(), url.getPath(), url.getQuery(), url.getRef()).toString();
-
- m_activity.openUri(Uri.parse(uri));
+ m_activity.openUri(Uri.parse(link));
} catch (Exception e) {
e.printStackTrace();
m_activity.toast(R.string.error_other_error);
}
}
});
-
- registerForContextMenu(title);
+
}
ImageView share = (ImageView)view.findViewById(R.id.share);
@@ -245,6 +240,9 @@ public class OfflineArticleFragment extends Fragment {
final WebView web = (WebView)view.findViewById(R.id.article_content);
if (web != null) {
+ if (CommonActivity.THEME_DARK.equals(m_prefs.getString("theme", CommonActivity.THEME_DEFAULT))) {
+ web.setBackgroundColor(Color.BLACK);
+ }
web.setWebViewClient(new WebViewClient() {
@Override
@@ -391,22 +389,6 @@ public class OfflineArticleFragment extends Fragment {
dv.setText(df.format(d));
}
- TextView author = (TextView)view.findViewById(R.id.author);
-
- boolean hasAuthor = false;
-
- if (author != null) {
- author.setTextSize(TypedValue.COMPLEX_UNIT_SP, articleSmallFontSize);
-
- int authorIndex = m_cursor.getColumnIndex("author");
- if (authorIndex >= 0)
- author.setText(m_cursor.getString(authorIndex));
- else
- author.setVisibility(View.GONE);
-
- hasAuthor = true;
- }
-
TextView tagv = (TextView)view.findViewById(R.id.tags);
if (tagv != null) {
@@ -419,8 +401,12 @@ public class OfflineArticleFragment extends Fragment {
int authorIndex = m_cursor.getColumnIndex("author");
- if (!hasAuthor && authorIndex >= 0) {
- fTitle += " (" + getString(R.string.author_formatted, m_cursor.getString(authorIndex)) + ")";
+ if (authorIndex >= 0) {
+ String authorStr = m_cursor.getString(authorIndex);
+
+ if (authorStr != null && authorStr.length() > 0) {
+ fTitle += " (" + getString(R.string.author_formatted, m_cursor.getString(authorIndex)) + ")";
+ }
}
tagv.setText(fTitle);
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java
index 6031d730..4b484566 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java
@@ -201,7 +201,12 @@ public class OfflineDetailActivity extends OfflineActivity implements OfflineHea
@Override
public void onBackPressed() {
- super.onBackPressed();
+ try {
+ super.onBackPressed();
+ } catch (IllegalStateException e) {
+ // java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
+ e.printStackTrace();
+ }
}
@Override
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java
index 90bcd93e..f1827d21 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java
@@ -47,7 +47,7 @@ public class OfflineFeedCategoriesFragment extends BaseFeedlistFragment implemen
menu.findItem(R.id.create_shortcut).setEnabled(false);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
- Cursor cursor = (Cursor)getCatAtPosition(info.position);
+ Cursor cursor = getCatAtPosition(info.position);
if (cursor != null)
menu.setHeaderTitle(cursor.getString(cursor.getColumnIndex("title")));
@@ -57,7 +57,7 @@ public class OfflineFeedCategoriesFragment extends BaseFeedlistFragment implemen
}
public Cursor createCursor() {
- String unreadOnly = BaseColumns._ID + "> 0 AND " + (m_activity.getUnreadOnly() ? "unread > 0" : "1");
+ String unreadOnly = BaseColumns._ID + ">= 0 AND " + (m_activity.getUnreadOnly() ? "unread > 0" : "1");
String order = m_prefs.getBoolean("sort_feeds_by_unread", false) ? "unread DESC, title" : "title";
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 4fe21f93..b2ce09a1 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
@@ -7,6 +7,7 @@ import android.content.res.Resources.Theme;
import android.database.Cursor;
import android.database.sqlite.SQLiteStatement;
import android.graphics.Paint;
+import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
@@ -20,6 +21,7 @@ import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Display;
import android.view.LayoutInflater;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
@@ -32,6 +34,7 @@ import android.widget.AdapterView.OnItemClickListener;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
+import android.widget.PopupMenu;
import android.widget.ProgressBar;
import android.widget.TextView;
@@ -53,7 +56,7 @@ import java.util.Date;
import java.util.TimeZone;
public class OfflineHeadlinesFragment extends Fragment implements OnItemClickListener, AbsListView.OnScrollListener {
- public static enum ArticlesSelection { ALL, NONE, UNREAD }
+ public enum ArticlesSelection { ALL, NONE, UNREAD }
private final String TAG = this.getClass().getSimpleName();
@@ -101,143 +104,91 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
}
@Override
+ public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenuInfo menuInfo) {
+
+ getActivity().getMenuInflater().inflate(R.menu.context_headlines, menu);
+
+ menu.findItem(R.id.set_labels).setVisible(false);
+ menu.findItem(R.id.article_set_note).setVisible(false);
+ menu.findItem(R.id.headlines_article_unread).setVisible(false); // TODO: implement
+
+ super.onCreateContextMenu(menu, v, menuInfo);
+ }
+
+ @Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
-
+
+ int articleId = getArticleIdAtPosition(info.position);
+
+ if (!onArticleMenuItemSelected(item, articleId))
+ return super.onContextItemSelected(item);
+ else
+ return true;
+ }
+
+ private boolean onArticleMenuItemSelected(MenuItem item, int articleId) {
switch (item.getItemId()) {
- case R.id.article_link_copy:
- if (true) {
- int articleId = getArticleIdAtPosition(info.position);
-
- Cursor article = m_activity.getArticleById(articleId);
-
- if (article != null) {
- m_activity.copyToClipboard(article.getString(article.getColumnIndex("link")));
- article.close();
+ case R.id.headlines_article_link_copy:
+ if (true) {
+ Cursor article = m_activity.getArticleById(articleId);
+
+ if (article != null) {
+ m_activity.copyToClipboard(article.getString(article.getColumnIndex("link")));
+ article.close();
+ }
}
- }
- return true;
- case R.id.selection_toggle_marked:
- if (getSelectedArticleCount() > 0) {
- SQLiteStatement stmt = m_activity.getDatabase()
- .compileStatement(
- "UPDATE articles SET modified = 1, marked = NOT marked WHERE selected = 1");
- stmt.execute();
- stmt.close();
- } else {
- int articleId = getArticleIdAtPosition(info.position);
-
- SQLiteStatement stmt = m_activity.getDatabase().compileStatement(
- "UPDATE articles SET modified = 1, marked = NOT marked WHERE "
- + BaseColumns._ID + " = ?");
- stmt.bindLong(1, articleId);
- stmt.execute();
- stmt.close();
- }
- refresh();
- return true;
- case R.id.selection_toggle_published:
- if (getSelectedArticleCount() > 0) {
- SQLiteStatement stmt = m_activity.getDatabase()
- .compileStatement(
- "UPDATE articles SET modified = 1, published = NOT published WHERE selected = 1");
- stmt.execute();
- stmt.close();
- } else {
- int articleId = getArticleIdAtPosition(info.position);
-
- SQLiteStatement stmt = m_activity.getDatabase().compileStatement(
- "UPDATE articles SET modified = 1, published = NOT published WHERE "
- + BaseColumns._ID + " = ?");
- stmt.bindLong(1, articleId);
- stmt.execute();
- stmt.close();
- }
- refresh();
- return true;
- case R.id.selection_toggle_unread:
- if (getSelectedArticleCount() > 0) {
- SQLiteStatement stmt = m_activity.getDatabase()
- .compileStatement(
- "UPDATE articles SET modified = 1, unread = NOT unread WHERE selected = 1");
- stmt.execute();
- stmt.close();
- } else {
- int articleId = getArticleIdAtPosition(info.position);
-
- SQLiteStatement stmt = m_activity.getDatabase().compileStatement(
- "UPDATE articles SET modified = 1, unread = NOT unread WHERE "
- + BaseColumns._ID + " = ?");
- stmt.bindLong(1, articleId);
- stmt.execute();
- stmt.close();
- }
- refresh();
- return true;
- case R.id.headlines_share_article:
- if (true) {
- int articleId = getArticleIdAtPosition(info.position);
+ return true;
+ case R.id.headlines_article_link_open:
+ if (true) {
+ Cursor article = m_activity.getArticleById(articleId);
+
+ if (article != null) {
+ m_activity.openUri(Uri.parse(article.getString(article.getColumnIndex("link"))));
+
+ // TODO: mark article as read, set modified = 1, refresh
+
+ article.close();
+ }
+ }
+ return true;
+ case R.id.headlines_share_article:
m_activity.shareArticle(articleId);
- }
- return true;
- case R.id.catchup_above:
- if (true) {
- int articleId = getArticleIdAtPosition(info.position);
-
- SQLiteStatement stmt = null;
-
- String updatedOperator = (m_prefs.getBoolean("offline_oldest_first", false)) ? "<" : ">";
-
- if (m_feedIsCat) {
- stmt = m_activity.getDatabase().compileStatement(
- "UPDATE articles SET modified = 1, unread = 0 WHERE " +
- "updated "+updatedOperator+" (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " +
- "AND unread = 1 AND feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)");
- } else {
- stmt = m_activity.getDatabase().compileStatement(
- "UPDATE articles SET modified = 1, unread = 0 WHERE " +
- "updated "+updatedOperator+" (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " +
- "AND unread = 1 AND feed_id = ?");
+ return true;
+ case R.id.catchup_above:
+ if (true) {
+ SQLiteStatement stmt = null;
+
+ String updatedOperator = (m_prefs.getBoolean("offline_oldest_first", false)) ? "<" : ">";
+
+ if (m_feedIsCat) {
+ stmt = m_activity.getDatabase().compileStatement(
+ "UPDATE articles SET modified = 1, unread = 0 WHERE " +
+ "updated "+updatedOperator+" (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " +
+ "AND unread = 1 AND feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)");
+ } else {
+ stmt = m_activity.getDatabase().compileStatement(
+ "UPDATE articles SET modified = 1, unread = 0 WHERE " +
+ "updated "+updatedOperator+" (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " +
+ "AND unread = 1 AND feed_id = ?");
+ }
+
+ stmt.bindLong(1, articleId);
+ stmt.bindLong(2, m_feedId);
+ stmt.execute();
+ stmt.close();
}
-
- stmt.bindLong(1, articleId);
- stmt.bindLong(2, m_feedId);
- stmt.execute();
- stmt.close();
- }
- refresh();
- return true;
- default:
- Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId());
- return super.onContextItemSelected(item);
- }
- }
-
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
-
- getActivity().getMenuInflater().inflate(R.menu.context_headlines, menu);
-
- if (getSelectedArticleCount() > 0) {
- menu.setHeaderTitle(R.string.headline_context_multiple);
- menu.setGroupVisible(R.id.menu_group_single_article, false);
- } else {
- AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo;
- Cursor c = getArticleAtPosition(info.position);
- menu.setHeaderTitle(c.getString(c.getColumnIndex("title")));
- //c.close();
- menu.setGroupVisible(R.id.menu_group_single_article, true);
-
- menu.findItem(R.id.set_labels).setVisible(false);
- menu.findItem(R.id.article_set_note).setVisible(false);
+ refresh();
+ return true;
+ default:
+ Log.d(TAG, "onArticleMenuItemSelected, unhandled id=" + item.getItemId());
+ return false;
}
-
- super.onCreateContextMenu(menu, v, menuInfo);
-
+
}
-
+
@Override
public void onResume() {
super.onResume();
@@ -462,6 +413,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
public ImageView textImage;
public ImageView textChecked;
public ImageView flavorVideoKindView;
+ public View flavorImageOverflow;
public View headlineHeader;
}
@@ -583,6 +535,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
holder.textChecked = (ImageView) v.findViewById(R.id.text_checked);
holder.flavorVideoKindView = (ImageView) v.findViewById(R.id.flavor_video_kind);
holder.headlineHeader = v.findViewById(R.id.headline_header);
+ holder.flavorImageOverflow = v.findViewById(R.id.flavor_image_overflow);
v.setTag(holder);
@@ -770,8 +723,26 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
holder.flavorImageLoadingBar.setVisibility(View.GONE);
holder.flavorImageView.setVisibility(View.GONE);
holder.flavorVideoKindView.setVisibility(View.GONE);
+ holder.flavorImageOverflow.setVisibility(View.GONE);
holder.headlineHeader.setBackgroundDrawable(null);
+
+ // this is needed if our flavor image goes behind base listview element
+ holder.headlineHeader.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ m_listener.onArticleSelected(articleId);
+ }
+ });
+
+ holder.headlineHeader.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ m_activity.openContextMenu(v);
+
+ return true;
+ }
+ });
}
if (holder.menuButtonView != null) {
@@ -781,7 +752,23 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
holder.menuButtonView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- getActivity().openContextMenu(v);
+
+ PopupMenu popup = new PopupMenu(getActivity(), v);
+ MenuInflater inflater = popup.getMenuInflater();
+ inflater.inflate(R.menu.context_headlines, popup.getMenu());
+
+ popup.getMenu().findItem(R.id.set_labels).setVisible(false);
+ popup.getMenu().findItem(R.id.article_set_note).setVisible(false);
+ popup.getMenu().findItem(R.id.headlines_article_unread).setVisible(false); // TODO: implement
+
+ popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ return onArticleMenuItemSelected(item, articleId);
+ }
+ });
+
+ popup.show();
}
});
}
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 1823d133..ed146845 100644
--- 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
@@ -275,7 +275,12 @@ public class OfflineMasterActivity extends OfflineActivity implements OfflineHea
m_drawerLayout.openDrawer(Gravity.START);
} else {
- super.onBackPressed();
+ try {
+ super.onBackPressed();
+ } catch (IllegalStateException e) {
+ // java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
+ e.printStackTrace();
+ }
}
}
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 f1eafe8f..bffcb8da 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
@@ -2,7 +2,6 @@ package org.fox.ttrss.types;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.Log;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@@ -39,16 +38,13 @@ public class Article implements Parcelable {
public boolean selected;
/* not serialized */
- public Document articleDoc;
- public Element flavorImage;
+ transient public Document articleDoc;
+ transient public Element flavorImage;
- public String flavorImageUri;
- public String flavorStreamUri;
- public String youtubeVid;
-
- //public int flavorImageCount;
-
- public List<Element> mediaList = new ArrayList<>();
+ transient public String flavorImageUri;
+ transient public String flavorStreamUri;
+ transient public String youtubeVid;
+ transient public List<Element> mediaList = new ArrayList<>();
public Article(Parcel in) {
readFromParcel(in);
@@ -58,6 +54,14 @@ public class Article implements Parcelable {
}
+ public void cleanupExcerpt() {
+ if (excerpt != null) {
+ excerpt = excerpt.replace("&hellip;", "…");
+ excerpt = excerpt.replace("]]>", "");
+ excerpt = Jsoup.parse(excerpt).text();
+ }
+ }
+
public void collectMediaInfo() {
articleDoc = Jsoup.parse(content);
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/EnlargingImageView.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/EnlargingImageView.java
index bf9d48d8..ff433074 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/EnlargingImageView.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/EnlargingImageView.java
@@ -34,7 +34,7 @@ import android.view.View;
* @author Tomáš Procházka &lt;<a href="mailto:[email protected]">[email protected]</a>&gt;
* @version $Revision: 0$ ($Date: 6.6.2011 18:16:52$)
*/
-public class EnlargingImageView extends android.widget.ImageView {
+public class EnlargingImageView extends ForegroundImageView {
private int mDrawableWidth;
private int mDrawableHeight;
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ForegroundImageView.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ForegroundImageView.java
new file mode 100644
index 00000000..f02158e9
--- /dev/null
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ForegroundImageView.java
@@ -0,0 +1,121 @@
+package org.fox.ttrss.util;
+
+// https://gist.github.com/JakeWharton/0a251d67649305d84e8a
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+import org.fox.ttrss.R;
+
+public class ForegroundImageView extends ImageView {
+ private Drawable foreground;
+
+ public ForegroundImageView(Context context) {
+ this(context, null);
+ }
+
+ public ForegroundImageView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ForegroundImageView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ForegroundImageView);
+ Drawable foreground = a.getDrawable(R.styleable.ForegroundImageView_android_foreground);
+ if (foreground != null) {
+ setForeground(foreground);
+ }
+ a.recycle();
+ }
+
+ /**
+ * Supply a drawable resource that is to be rendered on top of all of the child
+ * views in the frame layout.
+ *
+ * @param drawableResId The drawable resource to be drawn on top of the children.
+ */
+ public void setForegroundResource(int drawableResId) {
+ setForeground(getContext().getResources().getDrawable(drawableResId));
+ }
+
+ /**
+ * Supply a Drawable that is to be rendered on top of all of the child
+ * views in the frame layout.
+ *
+ * @param drawable The Drawable to be drawn on top of the children.
+ */
+ public void setForeground(Drawable drawable) {
+ if (foreground == drawable) {
+ return;
+ }
+ if (foreground != null) {
+ foreground.setCallback(null);
+ unscheduleDrawable(foreground);
+ }
+
+ foreground = drawable;
+
+ if (drawable != null) {
+ drawable.setCallback(this);
+ if (drawable.isStateful()) {
+ drawable.setState(getDrawableState());
+ }
+ }
+ requestLayout();
+ invalidate();
+ }
+
+ @Override protected boolean verifyDrawable(Drawable who) {
+ return super.verifyDrawable(who) || who == foreground;
+ }
+
+ @Override public void jumpDrawablesToCurrentState() {
+ super.jumpDrawablesToCurrentState();
+ if (foreground != null) foreground.jumpToCurrentState();
+ }
+
+ @Override protected void drawableStateChanged() {
+ super.drawableStateChanged();
+ if (foreground != null && foreground.isStateful()) {
+ foreground.setState(getDrawableState());
+ }
+ }
+
+ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ if (foreground != null) {
+ foreground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
+ invalidate();
+ }
+ }
+
+ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ if (foreground != null) {
+ foreground.setBounds(0, 0, w, h);
+ invalidate();
+ }
+ }
+
+ @Override public void draw(Canvas canvas) {
+ super.draw(canvas);
+
+ if (foreground != null) {
+ foreground.draw(canvas);
+ }
+ }
+
+ @Override public void drawableHotspotChanged(float x, float y) {
+ super.drawableHotspotChanged(x, y);
+
+ if (foreground != null && android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ foreground.setHotspot(x, y);
+ }
+ }
+} \ No newline at end of file
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
index 8581addc..54df9da4 100755
--- 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
@@ -32,6 +32,7 @@ public class HeadlinesRequest extends ApiRequest {
protected boolean m_firstIdChanged = false;
protected int m_firstId = 0;
+ protected int m_amountLoaded = 0;
public HeadlinesRequest(Context context, OnlineActivity activity, final Feed feed, ArticleList articles) {
super(context);
@@ -86,22 +87,25 @@ public class HeadlinesRequest extends ApiRequest {
m_articles.remove(0);
}
- if (m_articles.get(m_articles.size()-1).id == HeadlinesFragment.ARTICLE_SPECIAL_LOADMORE) {
+ /*if (m_articles.get(m_articles.size()-1).id == HeadlinesFragment.ARTICLE_SPECIAL_LOADMORE) {
m_articles.remove(m_articles.size()-1); // remove previous placeholder
- }
+ }*/
}
-
+
+ m_amountLoaded = articles.size();
+
for (Article f : articles)
if (!m_articles.containsId(f.id)) {
f.collectMediaInfo();
+ f.cleanupExcerpt();
m_articles.add(f);
}
- if (articles.size() == HEADLINES_REQUEST_SIZE) {
+ /*if (articles.size() == HEADLINES_REQUEST_SIZE) {
Article placeholder = new Article(HeadlinesFragment.ARTICLE_SPECIAL_LOADMORE);
m_articles.add(placeholder);
- }
+ }*/
/* if (m_articles.size() == 0)
m_activity.setLoadingStatus(R.string.no_headlines_to_display, false);
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NoChildFocusScrollView.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NoChildFocusScrollView.java
index af0454fa..5e5c8c48 100755..100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NoChildFocusScrollView.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NoChildFocusScrollView.java
@@ -1,13 +1,12 @@
package org.fox.ttrss.util;
import android.content.Context;
-import android.support.v4.widget.NestedScrollView;
import android.util.AttributeSet;
import android.view.View;
import android.webkit.WebView;
import android.widget.ScrollView;
-public class NoChildFocusScrollView extends NestedScrollView {
+public class NoChildFocusScrollView extends NotifyingScrollView {
public NoChildFocusScrollView(Context context) {
super(context);
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NotifyingScrollView.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NotifyingScrollView.java
new file mode 100644
index 00000000..e128856f
--- /dev/null
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NotifyingScrollView.java
@@ -0,0 +1,45 @@
+package org.fox.ttrss.util;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ScrollView;
+
+/**
+ * @author Cyril Mottier
+ */
+public class NotifyingScrollView extends ScrollView {
+
+ /**
+ * @author Cyril Mottier
+ */
+ public interface OnScrollChangedListener {
+ void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt);
+ }
+
+ private OnScrollChangedListener mOnScrollChangedListener;
+
+ public NotifyingScrollView(Context context) {
+ super(context);
+ }
+
+ public NotifyingScrollView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public NotifyingScrollView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ super.onScrollChanged(l, t, oldl, oldt);
+ if (mOnScrollChangedListener != null) {
+ mOnScrollChangedListener.onScrollChanged(this, l, t, oldl, oldt);
+ }
+ }
+
+ public void setOnScrollChangedListener(OnScrollChangedListener listener) {
+ mOnScrollChangedListener = listener;
+ }
+
+} \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_bg_pressed.9.png b/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_bg_pressed.9.png
deleted file mode 100644
index efacbcfa..00000000
--- a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_bg_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg.9.png b/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg.9.png
deleted file mode 100644
index 02ee4401..00000000
--- a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg_focused.9.png b/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg_focused.9.png
deleted file mode 100644
index ccc01774..00000000
--- a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_bg_pressed.9.png b/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_bg_pressed.9.png
deleted file mode 100644
index 97a3ba09..00000000
--- a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_bg_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg.9.png b/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg.9.png
deleted file mode 100644
index 7ccb762b..00000000
--- a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg_focused.9.png b/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg_focused.9.png
deleted file mode 100644
index da9289e6..00000000
--- a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/org.fox.ttrss/src/main/res/drawable/appwidget_dark_bg_clickable.xml b/org.fox.ttrss/src/main/res/drawable/appwidget_dark_bg_clickable.xml
deleted file mode 100644
index 7cfc9d2b..00000000
--- a/org.fox.ttrss/src/main/res/drawable/appwidget_dark_bg_clickable.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- Copyright 2011 Google Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/appwidget_bg_pressed" android:state_pressed="true" />
- <item android:drawable="@drawable/appwidget_dark_bg_focused"
- android:state_focused="true"
- android:state_enabled="true"
- android:state_window_focused="true" />
- <item android:drawable="@drawable/appwidget_dark_bg" />
-</selector>
diff --git a/org.fox.ttrss/src/main/res/layout/activity_preferences.xml b/org.fox.ttrss/src/main/res/layout/activity_preferences.xml
index 431b7da4..bd37a3ce 100644
--- a/org.fox.ttrss/src/main/res/layout/activity_preferences.xml
+++ b/org.fox.ttrss/src/main/res/layout/activity_preferences.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:transitionName="SETTINGS_REVEAL"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/org.fox.ttrss/src/main/res/layout/activity_video_player.xml b/org.fox.ttrss/src/main/res/layout/activity_video_player.xml
index 2f81860c..1fbeb587 100644
--- a/org.fox.ttrss/src/main/res/layout/activity_video_player.xml
+++ b/org.fox.ttrss/src/main/res/layout/activity_video_player.xml
@@ -2,7 +2,7 @@
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
- android:background="?android:colorBackground"
+ android:background="@android:color/black"
tools:context="org.fox.ttrss.VideoPlayerActivity">
<FrameLayout
@@ -14,8 +14,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
- android:id="@+id/video_player"
- android:transitionName="TRANSITION:ARTICLE_VIDEO_PLAYER" />
+ android:id="@+id/video_player" />
+
+ <ImageView
+ android:id="@+id/video_player_cover"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
<ProgressBar
android:layout_width="wrap_content"
@@ -23,6 +27,18 @@
android:id="@+id/video_loading"
android:layout_gravity="center"
android:indeterminate="true" />
+
+ <ImageView
+ android:id="@+id/video_player_overflow"
+ android:clickable="true"
+ android:layout_width="wrap_content"
+ android:layout_height="26dp"
+ android:layout_weight="0"
+ android:background="@drawable/ripple"
+ android:src="@drawable/ic_dots_vertical"
+ android:layout_gravity="top|right"
+ android:layout_marginRight="8dp"
+ android:layout_marginTop="@dimen/activity_vertical_margin" />
</FrameLayout>
<include layout="@layout/toolbar" android:id="@+id/toolbar" />
diff --git a/org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml b/org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml
index afd37335..3d2c9c9a 100644
--- a/org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml
+++ b/org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml
@@ -2,7 +2,7 @@
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
- android:background="?android:colorBackground"
+ android:background="@android:color/black"
tools:context="org.fox.ttrss.VideoPlayerActivity">
<FrameLayout
diff --git a/org.fox.ttrss/src/main/res/layout/article_images_image.xml b/org.fox.ttrss/src/main/res/layout/article_images_image.xml
index 2b6d5856..37f44c38 100644
--- a/org.fox.ttrss/src/main/res/layout/article_images_image.xml
+++ b/org.fox.ttrss/src/main/res/layout/article_images_image.xml
@@ -26,4 +26,16 @@
android:layout_gravity="center"
android:scaleType="fitCenter" />
+ <ImageView
+ android:id="@+id/flavor_image_overflow"
+ android:clickable="true"
+ android:layout_width="wrap_content"
+ android:layout_height="26dp"
+ android:layout_weight="0"
+ android:background="@drawable/ripple"
+ android:src="@drawable/ic_dots_vertical"
+ android:layout_gravity="top|right"
+ android:layout_marginRight="8dp"
+ android:layout_marginTop="@dimen/activity_vertical_margin" />
+
</FrameLayout> \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/res/layout/article_images_pager.xml b/org.fox.ttrss/src/main/res/layout/article_images_pager.xml
index 8744af67..eaaca37a 100755
--- a/org.fox.ttrss/src/main/res/layout/article_images_pager.xml
+++ b/org.fox.ttrss/src/main/res/layout/article_images_pager.xml
@@ -3,7 +3,7 @@
android:id="@+id/article_images"
android:layout_width="fill_parent"
android:animateLayoutChanges="true"
- android:background="?headlinesBackground"
+ android:background="@android:color/black"
android:layout_height="fill_parent">
<org.fox.ttrss.ArticleImagesPager
diff --git a/org.fox.ttrss/src/main/res/layout/drawer_header.xml b/org.fox.ttrss/src/main/res/layout/drawer_header.xml
index d2ea0660..d39cdad0 100755
--- a/org.fox.ttrss/src/main/res/layout/drawer_header.xml
+++ b/org.fox.ttrss/src/main/res/layout/drawer_header.xml
@@ -28,6 +28,7 @@
android:clickable="true"
android:layout_marginBottom="16dp"
android:layout_marginRight="12dp"
+ android:transitionName="SETTINGS_REVEAL"
android:background="@drawable/ripple" />
<LinearLayout
diff --git a/org.fox.ttrss/src/main/res/layout/fragment_article.xml b/org.fox.ttrss/src/main/res/layout/fragment_article.xml
index 04fd22b2..3db6adc3 100644
--- a/org.fox.ttrss/src/main/res/layout/fragment_article.xml
+++ b/org.fox.ttrss/src/main/res/layout/fragment_article.xml
@@ -14,6 +14,7 @@
<org.fox.ttrss.util.NoChildFocusScrollView
android:id="@+id/article_scrollview"
+ android:scrollbars="vertical|horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="false" >
@@ -137,6 +138,7 @@
<org.fox.ttrss.util.LessBrokenWebView
android:layout_margin="16dp"
android:id="@+id/article_content"
+ android:scrollbars="none"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
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 f06e1d40..87734749 100755
--- a/org.fox.ttrss/src/main/res/layout/headlines_row.xml
+++ b/org.fox.ttrss/src/main/res/layout/headlines_row.xml
@@ -44,6 +44,7 @@
<org.fox.ttrss.util.EnlargingImageView
android:id="@+id/flavor_image"
+ android:foreground="@drawable/ripple"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
@@ -57,6 +58,7 @@
<RelativeLayout
android:id="@+id/headline_header"
+ android:clickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?headlineHeaderBackground"
@@ -64,6 +66,7 @@
<TextView
android:id="@+id/title"
+ android:background="@drawable/ripple"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_span="2"
@@ -120,15 +123,28 @@
android:id="@+id/flavor_video_kind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="bottom|right"
+ android:layout_gravity="left|bottom"
android:scaleType="fitXY"
android:src="@drawable/ic_play_circle"
android:visibility="visible"
android:layout_below="@+id/headline_header"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
- android:layout_marginRight="8dp"
- android:layout_marginBottom="8dp" />
+ android:layout_marginBottom="8dp"
+ android:layout_marginLeft="8dp" />
+
+ <ImageView
+ android:id="@+id/flavor_image_overflow"
+ android:clickable="true"
+ android:layout_width="wrap_content"
+ android:layout_height="24dp"
+ android:layout_weight="0"
+ android:background="@drawable/ripple"
+ android:paddingLeft="4dp"
+ android:paddingRight="4dp"
+ android:src="@drawable/ic_dots_vertical"
+ android:layout_gravity="bottom|right"
+ android:layout_marginBottom="10dp" />
</FrameLayout>
</TableRow>
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 cca55565..f9347788 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
@@ -45,6 +45,7 @@
<org.fox.ttrss.util.EnlargingImageView
android:id="@+id/flavor_image"
+ android:foreground="@drawable/ripple"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
@@ -58,6 +59,7 @@
<RelativeLayout
android:id="@+id/headline_header"
+ android:clickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?headlineHeaderBackground"
@@ -65,6 +67,7 @@
<TextView
android:id="@+id/title"
+ android:background="@drawable/ripple"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_span="2"
@@ -121,16 +124,29 @@
android:id="@+id/flavor_video_kind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="bottom|right"
+ android:layout_gravity="bottom|left"
android:scaleType="fitXY"
android:src="@drawable/ic_play_circle"
android:visibility="visible"
android:layout_below="@+id/headline_header"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
- android:layout_marginRight="8dp"
+ android:layout_marginLeft="8dp"
android:layout_marginBottom="8dp" />
+ <ImageView
+ android:id="@+id/flavor_image_overflow"
+ android:clickable="true"
+ android:layout_width="wrap_content"
+ android:layout_height="24dp"
+ android:layout_weight="0"
+ android:background="@drawable/ripple"
+ android:paddingLeft="4dp"
+ android:paddingRight="4dp"
+ android:src="@drawable/ic_dots_vertical"
+ android:layout_gravity="bottom|right"
+ android:layout_marginBottom="10dp" />
+
</FrameLayout>
</TableRow>
diff --git a/org.fox.ttrss/src/main/res/layout/widget_small.xml b/org.fox.ttrss/src/main/res/layout/widget_small.xml
index f1a90491..99124a3c 100755
--- a/org.fox.ttrss/src/main/res/layout/widget_small.xml
+++ b/org.fox.ttrss/src/main/res/layout/widget_small.xml
@@ -5,28 +5,29 @@
android:padding="@dimen/widget_margin" >
<LinearLayout
- android:background="@drawable/appwidget_dark_bg_clickable"
+ android:background="@android:color/white"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
- android:padding="8dp"
android:orientation="vertical" >
<ImageView
- android:layout_width="36dp"
- android:layout_height="36dp"
+ android:padding="8dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher" />
<TextView
+ android:padding="4dp"
+ android:background="#6482af"
android:id="@+id/widget_unread_counter"
android:layout_weight="0"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:gravity="center_horizontal"
android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/primary_text_dark"
android:textSize="13sp" />
diff --git a/org.fox.ttrss/src/main/res/menu/activity_video_player.xml b/org.fox.ttrss/src/main/res/menu/activity_video_player.xml
index 0b5d1ae6..b323d3b7 100644
--- a/org.fox.ttrss/src/main/res/menu/activity_video_player.xml
+++ b/org.fox.ttrss/src/main/res/menu/activity_video_player.xml
@@ -6,7 +6,12 @@
<item
android:id="@+id/article_vid_open"
app:showAsAction=""
- android:title="@string/video_player_open"/>
+ android:title="@string/open_with"/>
+ <item
+ android:id="@+id/article_vid_copy"
+ app:showAsAction=""
+ android:icon="@drawable/ic_content_copy"
+ android:title="@string/article_link_copy"/>
<item
android:id="@+id/article_vid_share"
android:icon="@drawable/ic_share"
diff --git a/org.fox.ttrss/src/main/res/menu/context_article_content_img.xml b/org.fox.ttrss/src/main/res/menu/context_article_content_img.xml
index 52855d14..33b60653 100644
--- a/org.fox.ttrss/src/main/res/menu/context_article_content_img.xml
+++ b/org.fox.ttrss/src/main/res/menu/context_article_content_img.xml
@@ -3,7 +3,7 @@
<item
android:id="@+id/article_img_open"
app:showAsAction=""
- android:title="@string/article_img_open"/>
+ android:title="@string/open_with"/>
<item
android:id="@+id/article_img_copy"
app:showAsAction=""
diff --git a/org.fox.ttrss/src/main/res/menu/context_headlines.xml b/org.fox.ttrss/src/main/res/menu/context_headlines.xml
index fafac872..dffc9e47 100644
--- a/org.fox.ttrss/src/main/res/menu/context_headlines.xml
+++ b/org.fox.ttrss/src/main/res/menu/context_headlines.xml
@@ -1,42 +1,32 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item
- android:id="@+id/selection_toggle_unread"
+ android:id="@+id/headlines_article_link_open"
app:showAsAction=""
- android:title="@string/context_selection_toggle_unread"/>
+ android:title="@string/open_with"/>
<item
- android:id="@+id/selection_toggle_marked"
+ android:id="@+id/headlines_share_article"
app:showAsAction=""
- android:title="@string/context_selection_toggle_marked"/>
+ android:title="@string/share_article"/>
+
<item
- android:id="@+id/selection_toggle_published"
+ android:id="@+id/headlines_article_link_copy"
app:showAsAction=""
- android:title="@string/context_selection_toggle_published"/>
-
- <group android:id="@+id/menu_group_single_article" >
- <item
- android:id="@+id/headlines_share_article"
- app:showAsAction=""
- android:title="@string/share_article"/>
- <item
- android:id="@+id/headlines_article_link_open"
- app:showAsAction=""
- android:title="@string/open_article_in_web_browser"/>
- <item
- android:id="@+id/headlines_article_link_copy"
- app:showAsAction=""
- android:title="@string/article_link_copy"/>
- <item
- android:id="@+id/catchup_above"
- app:showAsAction=""
- android:title="@string/article_mark_read_above"/>
- <item
- android:id="@+id/set_labels"
- android:title="@string/article_set_labels"/>
- <item
- android:id="@+id/article_set_note"
- app:showAsAction=""
- android:title="@string/article_set_note"/>
- </group>
+ android:title="@string/article_link_copy"/>
+ <item
+ android:id="@+id/catchup_above"
+ app:showAsAction=""
+ android:title="@string/article_mark_read_above"/>
+ <item
+ android:id="@+id/set_labels"
+ android:title="@string/article_set_labels"/>
+ <item
+ android:id="@+id/article_set_note"
+ app:showAsAction=""
+ android:title="@string/article_set_note"/>
+ <item
+ android:id="@+id/headlines_article_unread"
+ app:showAsAction=""
+ android:title="@string/context_selection_toggle_unread"/>
</menu> \ No newline at end of file
diff --git a/org.fox.ttrss/src/main/res/values-it/strings.xml b/org.fox.ttrss/src/main/res/values-it/strings.xml
index a170ccf3..511186d2 100755
--- a/org.fox.ttrss/src/main/res/values-it/strings.xml
+++ b/org.fox.ttrss/src/main/res/values-it/strings.xml
@@ -233,4 +233,12 @@
<string name="flavor_image_prompt">(più immagini…)</string>
<string name="headlines_row_top_changed">Nuovi articoli trovati, ricarica il notiziario per visualizzarli.</string>
+ <string name="prefs_custom_tabs_summary">Apri i link esterni con una Chrome custom tabs (più veloce, usato se disponibile)</string>
+ <string name="prefs_use_custom_tabs">Usa preview rapida</string>
+ <string name="ask_me_every_time">Chiedimelo ogni volta</string>
+ <string name="open_link">Apri link</string>
+ <string name="quick_preview">Preview rapida</string>
+ <string name="open_with_app">Apri con app</string>
+ <string name="prefs_opening_links">Apertura link</string>
+ <string name="open_with">Apri con…</string>
</resources>
diff --git a/org.fox.ttrss/src/main/res/values-pt-rBR/strings.xml b/org.fox.ttrss/src/main/res/values-pt-rBR/strings.xml
index 231b6d24..fd5113a4 100755
--- a/org.fox.ttrss/src/main/res/values-pt-rBR/strings.xml
+++ b/org.fox.ttrss/src/main/res/values-pt-rBR/strings.xml
@@ -7,45 +7,47 @@
<string name="login_ready">Pronto para conectar.</string>
<string name="login_login">Conectar</string>
<string name="logout">Desconectar</string>
- <string name="login">Conectar</string>
- <string name="debugging">Debugando</string>
+ <string name="login">Nome de usuário</string>
+ <string name="debugging">Depuração</string>
<string name="password">Senha</string>
<string name="default_url">http://example.domain/tt-rss/</string>
<string name="look_and_feel">Aparência</string>
<string name="pref_theme">Tema</string>
<string name="ttrss_url">URL do Tiny Tiny RSS</string>
+ <string name="theme_light">Claro</string>
<string name="theme_dark">Escuro</string>
<string name="preferences">Configurações</string>
- <string name="theme_light">Claro</string>
- <string name="connection">Conecção</string>
+ <string name="connection">Conexão</string>
<string name="headline_context_multiple">Artigos selecionados</string>
<string name="http_authentication">Autenticação HTTP</string>
- <string name="loading_message">Carregando, aguarde...</string>
+ <string name="loading_message">Carregando, aguarde…</string>
<string name="menu_unread_feeds">Mostrar feeds não lidos</string>
<string name="menu_all_feeds">Mostrar todos os feeds</string>
+ <string name="unread_only">Apenas não lidos</string>
<string name="update_feeds">Atualizar</string>
<string name="share_article">Compartilhar artigo</string>
<string name="catchup">Marcar como lido</string>
- <string name="sort_feeds_by_unread">Ordenar por não lidos</string>
+ <string name="sort_feeds_by_unread">Ordenar por número de não lidos</string>
<string name="ssl_trust_any">Aceitar qualquer certificado</string>
<string name="category_browse_feeds">Navegar pelos feeds</string>
- <string name="blank"></string>
+ <string name="blank"/>
<string name="transport_debugging">Registrar no log os dados enviados e recebidos</string>
<string name="article_toggle_marked">Colocar/Retirar estrela</string>
+ <string name="article_toggle_unread">Marcar como lido/não-lido</string>
<string name="article_toggle_published">Publicar/Não publicar</string>
<string name="headlines_select">Selecionar artigos</string>
<string name="headlines_select_dialog">Selecionar artigos</string>
- <string name="headlines_select_all">Tudo</string>
+ <string name="headlines_select_all">Todos</string>
<string name="headlines_select_unread">Não lidos</string>
- <string name="headlines_select_none">Deselecionar tudo</string>
+ <string name="headlines_select_none">Nenhum</string>
<string name="selection_toggle_marked">Colocar/Retirar estrela</string>
<string name="selection_toggle_published">Publicar/Não publicar</string>
- <string name="selection_toggle_unread">Lido/Não lido</string>
+ <string name="selection_toggle_unread">Marcar como lido/não-lido</string>
<string name="context_selection_toggle_marked">Colocar/Remover estrela</string>
- <string name="context_selection_toggle_published">Publicar/Nâo publica</string>
- <string name="context_selection_toggle_unread">Lido/Não lido</string>
+ <string name="context_selection_toggle_published">Publicar/Não publicar</string>
+ <string name="context_selection_toggle_unread">Marcar como lido/não-lido</string>
<string name="article_mark_read_above">Marcar acima como lido</string>
- <string name="http_login_summary">Opcional. Preencha este campo se sua instalação do tt-rss usa autenticação básica por http</string>
+ <string name="http_login_summary">Opcional. Preencha este campo se sua instalação do tt-rss usa autenticação básica HTTP</string>
<string name="login_summary">Seu usuário tt-rss. Não é necessário no modo mono usuário</string>
<string name="ttrss_url_summary">URL da sua instalação tt-rss, por exemplo http://site.com/tt-rss/</string>
<string name="enable_cats">Habilitar categorias</string>
@@ -61,9 +63,9 @@
<string name="error_http_other_error">Erro: Outro erro HTTP (veja log)</string>
<string name="error_ssl_rejected">Erro: Certificado SSL foi rejeitado</string>
<string name="error_parse_error">Erro: Falha ao converter string JSON</string>
- <string name="error_io_error">Erro: Falha de I/O (Servidor fora?)</string>
+ <string name="error_io_error">Erro: Falha de I/O (Servidor fora do ar?)</string>
<string name="error_other_error">Erro: Erro desconhecido (veja log)</string>
- <string name="error_api_disabled">Erro: Habilite o acesso por API externa na configuração do avançada do tt-rss</string>
+ <string name="error_api_disabled">Erro: Habilite o acesso por API externa na configuração tt-rss (seção Avançado)</string>
<string name="error_api_unknown">Erro: Erro desconhecido na API (veja log)</string>
<string name="error_api_incorrect_usage">Erro: Uso incorreto da API</string>
<string name="error_login_failed">Erro: Usuário ou senha inválidos</string>
@@ -71,15 +73,16 @@
<string name="go_offline">Modo offline</string>
<string name="go_online">Modo online</string>
<string name="offline_switch_error">Falha ao preparar o modo offline (ver log)</string>
- <string name="no_feeds">Nenhuma assinatura para mostrar</string>
- <string name="dialog_offline_prompt">O Login falhou mas você tem dados armazenados, ir para modo offline?</string>
+ <string name="no_feeds">Nenhum feed para mostrar</string>
+ <string name="dialog_offline_prompt">O Login falhou, mas você tem dados armazenados. Mudar para modo offline?</string>
<string name="dialog_offline_success">Modo offline está disponível</string>
- <string name="dialog_offline_go">Ir para offline</string>
+ <string name="dialog_offline_go">Mudar para offline</string>
<string name="dialog_cancel">Cancelar</string>
<string name="dialog_offline_switch_prompt">Baixar artigos não lidos e mudar para offline?</string>
<string name="notify_downloading_articles">Baixando artigos (%1$d)…</string>
<string name="notify_downloading_init">Iniciando download…</string>
- <string name="notify_downloading_feeds">Baixando assinaturas…</string>
+ <string name="notify_downloading_feeds">Baixando feeds…</string>
+ <string name="notify_downloading_categories">Baixando categorias…</string>
<string name="notify_uploading_sending_data">Enviando dados para o servidor…</string>
<string name="notify_downloading_title">Preparando modo offline</string>
<string name="notify_uploading_title">Sincronizando dados offline</string>
@@ -88,7 +91,7 @@
<string name="offline_image_cache_enabled">Armazenar imagens</string>
<string name="offline_image_cache_enabled_summary">Baixar imagens para o cartão SD. Isso pode aumentar consideravelmente o tempo para o modo offline.</string>
<string name="notify_downloading_images">Baixando imagens (%1$d)…</string>
- <string name="article_set_labels">Definir tags</string>
+ <string name="article_set_labels">Definir marcadores</string>
<string name="search">Pesquisar</string>
<string name="cancel">Cancelar</string>
<string name="pref_font_size">Tamanho do texto dos artigos</string>
@@ -104,48 +107,52 @@
<string name="dialog_offline_sync_continue">Continuar</string>
<string name="article_set_note">Publicar com anotação</string>
<string name="dialog_open_preferences">Configuração</string>
- <string name="dialog_need_configure_prompt">Preencha com a informação do servidor tt-rss como URL, login e senha.</string>
+ <string name="dialog_need_configure_prompt">Preencha com a informação do servidor tt-rss como URL, nome de usuário e senha.</string>
<string name="update_headlines">Atualizar</string>
<string name="error_network_unavailable">Erro: Rede indisponível</string>
<string name="category_browse_headlines">Navegar pelos títulos</string>
<string name="use_volume_keys">Usar botões de volume</string>
<string name="use_volume_keys_long">Mudar entre artigos usando os botões de volume</string>
- <string name="ssl_trust_any_host">Não verificar hostname</string>
- <string name="error_api_unknown_method">Erro: metodo API desconhecido</string>
+ <string name="ssl_trust_any_host">Não verificar nome de host</string>
+ <string name="error_api_unknown_method">Erro: método API desconhecido</string>
<string name="ssl_trust_any_long">Aceitar qualquer certificado SSL sem verificação</string>
- <string name="ssl_trust_any_host_long">Não verificar o nome do servidor</string>
+ <string name="ssl_trust_any_host_long">Não verificar o nome de host do servidor</string>
<string name="ssl">SSL</string>
- <string name="error_ssl_hostname_rejected">Erro: Nome SSL não verificado</string>
+ <string name="error_ssl_hostname_rejected">Erro: Nome de host SSL não corresponde</string>
<plurals name="article_comments">
+ <item quantity="one">%1$d comentário</item>
<item quantity="other">%1$d comentários</item>
</plurals>
<plurals name="trial_mode_prompt">
- <item quantity="other">Modo de teste, resta(m) %1$d dia(s).</item>
+ <item quantity="one">Modo de teste, resta um dia.</item>
+ <item quantity="other">Modo de teste, restam %1$d dias.</item>
</plurals>
+
<string name="trial_purchase">Desbloquear a versão completa</string>
<string name="trial_expired">Período de teste encerrado</string>
<string name="trial_expired_message">Para continuar usando o Tiny Tiny RSS por favor desbloqueie a versão completa comprando a chave.</string>
- <string name="theme_sepia">Sepia</string>
- <string name="reading">Lendo</string>
+ <string name="theme_sepia">Sépia</string>
+ <string name="theme_amber">Âmbar</string>
+ <string name="reading">Leitura</string>
<string name="offline_articles_to_download">Número de artigos a baixar</string>
- <string name="offline_articles_to_download_long">Número de artigos a baixar para o modo Offline (mais novos primeiro).</string>
+ <string name="offline_articles_to_download_long">Número de artigos a baixar para o modo offline (mais novos primeiro).</string>
<string name="pref_headlines_show_content_long">Mostrar prévia do conteúdo na lista de títulos</string>
- <string name="pref_headlines_show_content">Prévia do conteúdos do artigo</string>
+ <string name="pref_headlines_show_content">Prévia do conteúdo do artigo</string>
<string name="api_too_low">Esta ação precisa de uma nova versão do Tiny Tiny RSS</string>
<string name="share_url_hint">URL do artigo</string>
<string name="share_content_hint">Conteúdo do artigo</string>
<string name="share_title_hint">Título do artigo</string>
<string name="share_share_button">Compartilhar</string>
<string name="share_article_posted">Artigo postado.</string>
- <string name="subscribe_name">Assinar com Tiny Tiny RSS</string>
- <string name="feed_url">URL da assinatura</string>
- <string name="subscribe_to_feed">Assinar feed</string>
- <string name="error_while_subscribing">Erro ao assinar.</string>
+ <string name="subscribe_name">Inscrever-se com Tiny Tiny RSS</string>
+ <string name="feed_url">URL do feed</string>
+ <string name="subscribe_to_feed">Inscrever-se feed</string>
+ <string name="error_while_subscribing">Erro ao increver-se.</string>
<string name="category_list_updated">Lista de categorias atualizada</string>
- <string name="subscribed_to_feed">Feed assinado</string>
- <string name="error_feed_already_exists_">Erro: Assinatura já existe.</string>
+ <string name="subscribed_to_feed">Inscrito no feed</string>
+ <string name="error_feed_already_exists_">Erro: já inscrito neste feed.</string>
<string name="error_invalid_url">Erro: URL inválida.</string>
<string name="error_url_is_an_html_page_no_feeds_found">Erro: URL é de uma página HTML, nenhum feed encontrado.</string>
<string name="error_url_contains_multiple_feeds">Erro: URL contém múltiplos feeds</string>
@@ -160,15 +167,77 @@
<string name="article_img_open">Abrir imagem</string>
<string name="article_img_share">Compartilhar imagem</string>
<string name="article_img_view_caption">Ver legenda</string>
- <string name="pref_headlines_mark_read_scroll">Marcar como lida ao visualizar</string>
- <string name="pref_headlines_mark_read_scroll_long">Títulos serão marcados como lidos ao rodar depois deles</string>
+ <string name="pref_headlines_mark_read_scroll">Marcar como lido ao visualizar</string>
+ <string name="pref_headlines_mark_read_scroll_long">Artigos serão marcados como lidos ao rodar depois deles</string>
+
<plurals name="mark_num_headlines_as_read">
- <item quantity="other">Marcar %1$d artigo(s) como lido(s)?</item>
+ <item quantity="one">Marcar um artigos como lido?</item>
+ <item quantity="other">Marcar %1$d artigos como lidos?</item>
</plurals>
+
<string name="prefs_confirm_headlines_catchup">Confirme marcação de artigos como lidos</string>
<string name="author_formatted">por %1$s</string>
+
<plurals name="n_unread_articles">
+ <item quantity="one">%1$d artigo não lido</item>
<item quantity="other">%1$d artigos não lidos</item>
</plurals>
+
<string name="pref_headline_font_size">Tamanho do texto para os títulos</string>
+ <string name="context_confirm_catchup">Marcar todos os artigos em %1$s como lidos?</string>
+ <string name="accel_webview_summary">Desabilite se vir problemas visuais</string>
+ <string name="accel_webview_title">Usar web views com aceleração (3.0+)</string>
+ <string name="place_shortcut">Criar atalho</string>
+ <string name="shortcut_has_been_placed_on_the_home_screen">Foi criado um atalho na tela inicial</string>
+ <string name="download_articles_and_go_offline">Baixar artigos e mudar para modo offline</string>
+ <string name="tasker_save_and_close">Salvar e fechar</string>
+ <string name="synchronize_read_articles_and_go_online">Sincronizar artigos lidos e voltar ao modo online</string>
+ <string name="font_size_dialog_suffix">sp</string>
+ <string name="server_function_not_available">Desculpe, esta função não está disponível na sua versão do tt-rss.</string>
+ <string name="unsubscribe">Cancelar inscrição</string>
+ <string name="unsubscribe_from_prompt">Cancelar inscrição em %1$s?</string>
+ <string name="open_article_in_web_browser">Abrir no navegador</string>
+ <string name="error_loading_image">Erro ao carregar imagem.</string>
+ <string name="toggle_sort_order">Alternar entre mais novo ou mais antigo primeiro</string>
+ <string name="headlines_sort_default">Padrão</string>
+ <string name="headlines_sort_newest_first">Mais novo primeiro</string>
+ <string name="headlines_sort_oldest_first">Mais antigo primeiro</string>
+ <string name="headlines_sort_title">Título</string>
+ <string name="headlines_sort_articles_title">Ordenar artigos</string>
+ <string name="fresh_articles">Artigos recentes</string>
+ <string name="feed_all_articles">Todos os artigos</string>
+ <string name="prefs_enable_fab">Habilitar BFA</string>
+ <string name="prefs_enable_fab_long">Exibir botão flutuante de ação durante a leitura</string>
+ <string name="prefs_open_fresh_on_startup">Abrir artigos recentes ao iniciar</string>
+ <string name="prefs_headline_display_mode">Modo de exibição dos títulos</string>
+ <string name="prefs_headline_display_mode_long">Padrão, sem imagens, ou modo compacto</string>
+ <string name="headline_display_mode_default">Padrão</string>
+ <string name="headline_display_mode_no_images">Sem imagens</string>
+ <string name="headline_display_mode_compact">Compacto</string>
+ <string name="headline_display_mode_compact_noimages">Compacto (sem imagens)</string>
+ <string name="prefs_version">%1$s (%2$d)</string>
+ <string name="prefs_version_title">Versão</string>
+ <string name="prefs_build_timestamp">%1$s</string>
+ <string name="prefs_build_timestamp_title">Hora da compilação</string>
+ <string name="crash_dialog_text">Infelizmente, o Tiny Tiny RSS parou. Enviar registro da falha para tt-rss.org?</string>
+ <string name="prefs_widget_show_fresh">Mostrar artigos recentes</string>
+ <string name="prefs_widget_show_fresh_summary">Ao invés do total de artigos não lidos, exibir a quantidade de artigos recentes</string>
+ <string name="prefs_widget">Widget</string>
+ <string name="title_activity_video_player">Reprodutor de vídeos</string>
+
+ <string name="hello_world">Olá, mundo!</string>
+ <string name="action_settings">Configurações</string>
+ <string name="video_player_share">Compartilhar vídeo</string>
+ <string name="video_player_open">Abrir vídeo</string>
+
+ <string name="flavor_image_prompt">(mais imagens…)</string>
+ <string name="headlines_row_top_changed">Novos artigos encontrados, recarregue o feed para continuar.</string>
+ <string name="prefs_custom_tabs_summary">Abrir links externos com custom tabs do Chrome (mais rápido, usado se disponível)</string>
+ <string name="prefs_use_custom_tabs">Usar vizualiação rápida</string>
+ <string name="ask_me_every_time">Perguntar toda vez</string>
+ <string name="open_link">Abrir link</string>
+ <string name="quick_preview">Vizualização rápida</string>
+ <string name="open_with_app">Abrir com aplicativo</string>
+ <string name="prefs_opening_links">Abertura de links</string>
+ <string name="open_with">Abrir com…</string>
</resources>
diff --git a/org.fox.ttrss/src/main/res/values/attrs.xml b/org.fox.ttrss/src/main/res/values/attrs.xml
index e0bfb02c..3f4922d0 100755
--- a/org.fox.ttrss/src/main/res/values/attrs.xml
+++ b/org.fox.ttrss/src/main/res/values/attrs.xml
@@ -49,4 +49,7 @@
<attr format="reference|color" name="insetForeground">
</attr></declare-styleable>
<attr name="drawer_header" format="reference" />
+ <declare-styleable name="ForegroundImageView">
+ <attr name="android:foreground"/>
+ </declare-styleable>
</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 c6fa04fc..cef96477 100755
--- a/org.fox.ttrss/src/main/res/values/strings.xml
+++ b/org.fox.ttrss/src/main/res/values/strings.xml
@@ -231,7 +231,7 @@
<string name="video_player_share">Share video</string>
<string name="video_player_open">Open video</string>
- <string name="flavor_image_prompt">(more images...)</string>
+ <string name="flavor_image_prompt">(more images…)</string>
<string name="headlines_row_top_changed">New articles found, reload feed to continue.</string>
<string name="prefs_custom_tabs_summary">Open external links with Chrome custom tabs (faster, used if available)</string>
<string name="prefs_use_custom_tabs">Use quick preview</string>
@@ -240,4 +240,5 @@
<string name="quick_preview">Quick preview</string>
<string name="open_with_app">Open with app</string>
<string name="prefs_opening_links">Opening links</string>
+ <string name="open_with">Open with…</string>
</resources>
diff --git a/org.fox.ttrss/src/main/res/values/style.xml b/org.fox.ttrss/src/main/res/values/style.xml
index 74aad95a..71c8b612 100755
--- a/org.fox.ttrss/src/main/res/values/style.xml
+++ b/org.fox.ttrss/src/main/res/values/style.xml
@@ -18,14 +18,14 @@
<item name="headlineHeaderBackground">#ccffffff</item>
<item name="headlineUnreadBackground">@android:color/white</item>
<item name="feedsSelectedBackground">#dddddd</item>
- <item name="feedlistTextColor">@android:color/primary_text_light</item>
- <item name="feedlistSelectedTextColor">@android:color/primary_text_light</item>
- <item name="headlineUnreadTextColor">@android:color/primary_text_light</item>
- <item name="headlineSelectedTextColor">@android:color/primary_text_light</item>
- <item name="headlineExcerptTextColor">@android:color/secondary_text_light</item>
+ <item name="feedlistTextColor">@android:color/black</item>
+ <item name="feedlistSelectedTextColor">@android:color/black</item>
+ <item name="headlineUnreadTextColor">@android:color/black</item>
+ <item name="headlineSelectedTextColor">@android:color/black</item>
+ <item name="headlineExcerptTextColor">#323232</item>
<item name="headlineSecondaryTextColor">#909090</item>
<item name="headlineSelectedSecondaryTextColor">?headlineSelectedExcerptTextColor</item>
- <item name="headlineSelectedExcerptTextColor">@android:color/secondary_text_light</item>
+ <item name="headlineSelectedExcerptTextColor">#323232</item>
<item name="headlineTitleHighScoreUnreadTextColor">#008000</item>
<item name="linkColor">?colorPrimary</item>
<item name="loadingBackground">@android:color/white</item>
@@ -33,7 +33,7 @@
<item name="articleNoteBackground">#fff7d5</item>
<item name="parentBtnBackground">#dddddd</item>
<item name="articleHeader">@android:color/transparent</item>
- <item name="articleHeaderTextColor">@android:color/primary_text_light</item>
+ <item name="articleHeaderTextColor">@android:color/black</item>
<item name="articleTextColor">@android:color/black</item>
<item name="floatingActionButtonStyle">@style/FabTheme</item>
<item name="headlineFooterColor">?colorPrimary</item>
@@ -71,34 +71,34 @@
<!-- <item name="statusBarHintColor">?colorPrimary</item> -->
<item name="unreadCounterColor">#909090</item>
- <item name="feedlistTextColor">@android:color/primary_text_dark</item>
- <item name="headlineUnreadTextColor">@android:color/primary_text_dark</item>
+ <item name="feedlistTextColor">@android:color/white</item>
+ <item name="headlineUnreadTextColor">@android:color/white</item>
<item name="headlineSelectedTextColor">@android:color/white</item>
- <item name="headlineExcerptTextColor">@android:color/secondary_text_dark</item>
+ <item name="headlineExcerptTextColor">#bebebe</item>
<item name="headlineSecondaryTextColor">#909090</item>
<item name="headlineTitleHighScoreUnreadTextColor">#00FF00</item>
- <item name="headlineSelectedExcerptTextColor">@android:color/secondary_text_dark</item>
+ <item name="headlineSelectedExcerptTextColor">#bebebe</item>
<item name="headlineSelectedSecondaryTextColor">?headlineSelectedExcerptTextColor</item>
<item name="headlineSelectedBackground">#1c1c1c</item>
<item name="headlineHeaderBackground">#99000000</item>
<item name="headlineUnreadBackground">#101010</item>
<item name="linkColor">?colorPrimary</item>
<item name="loadingBackground">@android:color/black</item>
- <item name="articleNoteTextColor">@android:color/secondary_text_dark</item>
+ <item name="articleNoteTextColor">#bebebe</item>
<item name="articleNoteBackground">#303030</item>
<item name="parentBtnBackground">#101010</item>
<item name="ttrssHorizontalDivider">@android:drawable/divider_horizontal_dark</item>
<item name="feedlistBackground">#1c1d1e</item>
<item name="headlinesBackground">#1c1d1e</item>
- <item name="articleBackground">#1c1d1e</item>
+ <item name="articleBackground">@android:color/black</item>
<item name="feedsSelectedBackground">#1c1c1c</item>
- <item name="feedlistSelectedTextColor">@android:color/primary_text_dark</item>
+ <item name="feedlistSelectedTextColor">@android:color/white</item>
<item name="articleHeader">@android:color/transparent</item>
- <item name="articleHeaderTextColor">@android:color/primary_text_dark</item>
+ <item name="articleHeaderTextColor">@android:color/white</item>
<item name="floatingActionButtonStyle">@style/FabTheme</item>
<item name="articleTextColor">#e0e0e0</item>
<item name="headlineFooterColor">?colorPrimary</item>
- <item name="articleHeaderSeparator">@android:color/black</item>
+ <item name="articleHeaderSeparator">#303030</item>
<item name="colorPrimary">#607D8B</item>
<item name="colorPrimaryDark">#455A64</item>