summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2014-10-16 01:21:49 +0400
committerAndrew Dolgov <[email protected]>2014-10-16 01:21:49 +0400
commit8da85b9157ef4ffd8b04a8b817f7c6f51c641c68 (patch)
tree32d2b77dc33d3aa3e45f9f67d40f139b78f52a02
parenta77d00eeea212f17df05bf63a23745b2d46ba2d3 (diff)
add headlines flavor images
-rw-r--r--libs/universal-image-loader-1.9.3.jarbin0 -> 160443 bytes
-rw-r--r--res/layout/headlines_row.xml27
-rw-r--r--res/layout/headlines_row_selected.xml25
-rw-r--r--res/layout/headlines_row_selected_unread.xml25
-rw-r--r--res/layout/headlines_row_unread.xml50
-rw-r--r--src/org/fox/ttrss/CommonActivity.java27
-rw-r--r--src/org/fox/ttrss/HeadlinesFragment.java231
7 files changed, 259 insertions, 126 deletions
diff --git a/libs/universal-image-loader-1.9.3.jar b/libs/universal-image-loader-1.9.3.jar
new file mode 100644
index 00000000..e8ca33b7
--- /dev/null
+++ b/libs/universal-image-loader-1.9.3.jar
Binary files differ
diff --git a/res/layout/headlines_row.xml b/res/layout/headlines_row.xml
index 326ff49c..1d40e1bf 100644
--- a/res/layout/headlines_row.xml
+++ b/res/layout/headlines_row.xml
@@ -74,6 +74,24 @@
android:textSize="12sp" />
</LinearLayout>
+ <FrameLayout
+ android:paddingTop="3dp"
+ android:id="@+id/flavorImageHolder"
+ android:layout_width="match_parent"
+ android:layout_gravity="center"
+ android:layout_height="wrap_content" >
+
+ <ImageView
+ android:id="@+id/flavor_image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:adjustViewBounds="true"
+ android:maxHeight="128dp"
+ android:scaleType="centerInside"
+ android:src="@null"
+ android:visibility="gone" />
+ </FrameLayout>
+
<TextView
android:id="@+id/excerpt"
android:layout_width="match_parent"
@@ -83,14 +101,7 @@
android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
android:textColor="?headlineExcerptTextColor"
android:textSize="13sp" />
-
- <WebView
- android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingTop="3dp"
- android:visibility="gone" />
-
+
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/res/layout/headlines_row_selected.xml b/res/layout/headlines_row_selected.xml
index 0418d7b8..332b239a 100644
--- a/res/layout/headlines_row_selected.xml
+++ b/res/layout/headlines_row_selected.xml
@@ -72,6 +72,24 @@
android:textSize="12sp" />
</LinearLayout>
+ <FrameLayout
+ android:paddingTop="3dp"
+ android:id="@+id/flavorImageHolder"
+ android:layout_width="match_parent"
+ android:layout_gravity="center"
+ android:layout_height="wrap_content" >
+
+ <ImageView
+ android:id="@+id/flavor_image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:adjustViewBounds="true"
+ android:maxHeight="128dp"
+ android:scaleType="centerInside"
+ android:src="@null"
+ android:visibility="gone" />
+ </FrameLayout>
+
<TextView
android:id="@+id/excerpt"
android:layout_width="match_parent"
@@ -81,13 +99,6 @@
android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
android:textColor="?headlineSelectedExcerptTextColor"
android:textSize="13sp" />
-
- <WebView
- android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingTop="3dp"
- android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
diff --git a/res/layout/headlines_row_selected_unread.xml b/res/layout/headlines_row_selected_unread.xml
index abca9eaf..553bb9f8 100644
--- a/res/layout/headlines_row_selected_unread.xml
+++ b/res/layout/headlines_row_selected_unread.xml
@@ -73,6 +73,24 @@
android:textSize="12sp" />
</LinearLayout>
+ <FrameLayout
+ android:paddingTop="3dp"
+ android:id="@+id/flavorImageHolder"
+ android:layout_width="match_parent"
+ android:layout_gravity="center"
+ android:layout_height="wrap_content" >
+
+ <ImageView
+ android:id="@+id/flavor_image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:adjustViewBounds="true"
+ android:maxHeight="128dp"
+ android:scaleType="centerInside"
+ android:src="@null"
+ android:visibility="gone" />
+ </FrameLayout>
+
<TextView
android:id="@+id/excerpt"
android:layout_width="match_parent"
@@ -82,13 +100,6 @@
android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
android:textColor="?headlineSelectedExcerptTextColor"
android:textSize="13sp" />
-
- <WebView
- android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingTop="3dp"
- android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
diff --git a/res/layout/headlines_row_unread.xml b/res/layout/headlines_row_unread.xml
index b54f91d6..70fc7a9e 100644
--- a/res/layout/headlines_row_unread.xml
+++ b/res/layout/headlines_row_unread.xml
@@ -14,7 +14,10 @@
android:layout_height="match_parent"
android:background="?headlineUnreadBackground"
android:orientation="vertical"
- android:paddingTop="6dp" android:paddingLeft="6dp" android:paddingRight="6dp" android:paddingBottom="2dp" > >
+ android:paddingBottom="2dp"
+ android:paddingLeft="6dp"
+ android:paddingRight="6dp"
+ android:paddingTop="6dp" >
<LinearLayout
android:id="@+id/linearLayout6"
@@ -51,16 +54,16 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
+ android:fontFamily="sans-serif-light"
android:gravity="center_vertical"
android:singleLine="true"
- android:fontFamily="sans-serif-light"
- android:text="Example Feed"
+ android:text="Example Feed"
android:textColor="?headlineSecondaryTextColor"
android:textSize="12sp" />
<TextView
android:id="@+id/date"
- android:layout_width="wrap_content"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="sans-serif-light"
@@ -70,23 +73,34 @@
android:textSize="12sp" />
</LinearLayout>
+ <FrameLayout
+ android:paddingTop="3dp"
+ android:id="@+id/flavorImageHolder"
+ android:layout_width="match_parent"
+ android:layout_gravity="center"
+ android:layout_height="wrap_content" >
+
+ <ImageView
+ android:id="@+id/flavor_image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:adjustViewBounds="true"
+ android:maxHeight="128dp"
+ android:scaleType="centerInside"
+ android:src="@null"
+ android:visibility="gone" />
+ </FrameLayout>
+
<TextView
android:id="@+id/excerpt"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingTop="3dp"
android:lineSpacingExtra="2sp"
+ android:paddingTop="3dp"
android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
android:textColor="?headlineExcerptTextColor"
android:textSize="13sp" />
- <WebView
- android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingTop="3dp"
- android:visibility="gone" />
-
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -95,7 +109,7 @@
<CheckBox
android:id="@+id/selected"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="wrap_content"
android:layout_weight="0"
android:focusable="false" />
@@ -105,30 +119,30 @@
android:layout_height="match_parent"
android:layout_weight="1"
android:ellipsize="end"
+ android:fontFamily="sans-serif-light"
android:gravity="center_vertical"
android:singleLine="true"
android:text="by Author"
- android:fontFamily="sans-serif-light"
- android:textStyle="italic"
android:textColor="?headlineSecondaryTextColor"
- android:textSize="12sp" />
+ android:textSize="12sp"
+ android:textStyle="italic" />
<ImageView
android:id="@+id/marked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_marginRight="8dp"
android:layout_weight="0"
android:clickable="true"
- android:layout_marginRight="8dp"
android:src="@drawable/ic_star_empty" />
<ImageView
android:id="@+id/published"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_marginRight="6dp"
android:layout_weight="0"
android:clickable="true"
- android:layout_marginRight="6dp"
android:src="@drawable/ic_unpublished" />
<ImageView
diff --git a/src/org/fox/ttrss/CommonActivity.java b/src/org/fox/ttrss/CommonActivity.java
index f853d9b9..bf05d33b 100644
--- a/src/org/fox/ttrss/CommonActivity.java
+++ b/src/org/fox/ttrss/CommonActivity.java
@@ -1,13 +1,21 @@
package org.fox.ttrss;
+import java.io.File;
+import java.io.IOException;
+
import org.fox.ttrss.util.DatabaseHelper;
+import com.nostra13.universalimageloader.core.ImageLoader;
+import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
+import com.nostra13.universalimageloader.utils.StorageUtils;
import com.readystatesoftware.systembartint.SystemBarTintManager;
import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
+import android.graphics.BitmapFactory;
import android.graphics.Point;
+import android.net.http.HttpResponseCache;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.widget.SwipeRefreshLayout;
@@ -44,6 +52,19 @@ public class CommonActivity extends ActionBarActivity {
protected SharedPreferences m_prefs;
+ /* protected void enableHttpCaching() {
+ // enable resource caching
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ try {
+ File httpCacheDir = new File(getApplicationContext().getCacheDir(), "http");
+ long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
+ HttpResponseCache.install(httpCacheDir, httpCacheSize);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ } */
+
protected void setSmallScreen(boolean smallScreen) {
Log.d(TAG, "m_smallScreenMode=" + smallScreen);
m_smallScreenMode = smallScreen;
@@ -128,11 +149,14 @@ public class CommonActivity extends ActionBarActivity {
}
initDatabase();
-
+
m_compatMode = android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB;
Log.d(TAG, "m_compatMode=" + m_compatMode);
+ ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()).build();
+ ImageLoader.getInstance().init(config);
+
super.onCreate(savedInstanceState);
}
@@ -225,5 +249,4 @@ public class CommonActivity extends ActionBarActivity {
return display.getWidth();
}
}
-
}
diff --git a/src/org/fox/ttrss/HeadlinesFragment.java b/src/org/fox/ttrss/HeadlinesFragment.java
index 66202e3c..9a47328e 100644
--- a/src/org/fox/ttrss/HeadlinesFragment.java
+++ b/src/org/fox/ttrss/HeadlinesFragment.java
@@ -1,5 +1,10 @@
package org.fox.ttrss;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
@@ -24,10 +29,14 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources.Theme;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.net.Uri;
+import android.net.http.HttpResponseCache;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
@@ -57,6 +66,10 @@ import android.widget.ListView;
import android.widget.TextView;
import com.google.gson.JsonElement;
+import com.nostra13.universalimageloader.core.DisplayImageOptions;
+import com.nostra13.universalimageloader.core.ImageLoader;
+import com.nostra13.universalimageloader.core.assist.FailReason;
+import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
public class HeadlinesFragment extends Fragment implements OnItemClickListener, OnScrollListener {
public static enum ArticlesSelection { ALL, NONE, UNREAD };
@@ -781,98 +794,92 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
}
});
}
-
- TextView te = (TextView)v.findViewById(R.id.excerpt);
String articleContent = article.content != null ? article.content : "";
- /* if (m_prefs.getBoolean("headlines_full_content", false)) {
- final WebView content = (WebView)v.findViewById(R.id.content);
-
- if (content != null) {
-
- Document doc = Jsoup.parse(articleContent);
-
- if (doc != null) {
- // thanks webview for crashing on <video> tag
- Elements videos = doc.select("video");
-
- for (Element video : videos)
- video.remove();
-
- articleContent = doc.toString();
- }
-
- content.setVisibility(View.VISIBLE);
- if (te != null) te.setVisibility(View.GONE);
-
- String baseUrl = null;
-
- try {
- URL url = new URL(article.link);
- baseUrl = url.getProtocol() + "://" + url.getHost();
- } catch (MalformedURLException e) {
- //
- }
-
- TypedValue tv = new TypedValue();
- getActivity().getTheme().resolveAttribute(R.attr.linkColor, tv, true);
-
- String cssOverride = "";
- String theme = m_prefs.getString("theme", CommonActivity.THEME_DEFAULT);
-
- if (CommonActivity.THEME_HOLO.equals(theme)) {
- cssOverride = "body { background : transparent; color : #e0e0e0}";
- } else if (CommonActivity.THEME_DARK.equals(theme)) {
- cssOverride = "body { background : transparent; color : #e0e0e0}";
- } else {
- cssOverride = "body { background : transparent; }";
- }
-
- content.setBackgroundColor(Color.TRANSPARENT);
-
- String hexColor = String.format("#%06X", (0xFFFFFF & tv.data));
-
- if (m_prefs.getBoolean("justify_article_text", true)) {
- cssOverride += "body { text-align : justify; } ";
- }
+ TextView te = (TextView)v.findViewById(R.id.excerpt);
+
+ if (te != null) {
+ if (!m_prefs.getBoolean("headlines_show_content", true)) {
+ te.setVisibility(View.GONE);
+ } else {
+ String excerpt = Jsoup.parse(articleContent).text();
- articleContent = "<html>" +
- "<head>" +
- "<meta content=\"text/html; charset=utf-8\" http-equiv=\"content-type\">" +
- "<meta name=\"viewport\" content=\"width=device-width, user-scalable=no\" />" +
- "<style type=\"text/css\">" +
- "body { padding : 0px; margin : 0px; line-height : 130%; }" +
- cssOverride +
- "img { max-width : 100%; max-height : "+m_maxImageSize+"px; width : auto; height : auto; }" +
- "table { width : 100%; }" +
- "a:link {color: "+hexColor+";} a:visited { color: "+hexColor+";}" +
- "</style>" +
- "</head>" +
- "<body>" + articleContent + "</body></html>";
+ if (excerpt.length() > CommonActivity.EXCERPT_MAX_SIZE)
+ excerpt = excerpt.substring(0, CommonActivity.EXCERPT_MAX_SIZE) + "...";
- WebSettings ws = content.getSettings();
- ws.setSupportZoom(false);
- ws.setDefaultFontSize(headlineFontSize);
-
- content.loadDataWithBaseURL(baseUrl, articleContent, "text/html", "utf-8", null);
+ te.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineFontSize);
+ te.setText(excerpt);
}
-
- } else { */
- if (te != null) {
- if (!m_prefs.getBoolean("headlines_show_content", true)) {
- te.setVisibility(View.GONE);
- } else {
- String excerpt = Jsoup.parse(articleContent).text();
-
- if (excerpt.length() > CommonActivity.EXCERPT_MAX_SIZE)
- excerpt = excerpt.substring(0, CommonActivity.EXCERPT_MAX_SIZE) + "...";
+ }
+
+ final ImageView flavorImage = (ImageView) v.findViewById(R.id.flavor_image);
+
+ if (flavorImage != null && m_prefs.getBoolean("headlines_show_content", true)) {
+ flavorImage.setVisibility(View.GONE);
+
+ Document doc = Jsoup.parse(articleContent);
+
+ if (doc != null) {
+ Element img = doc.select("img").first();
+
+ if (img != null) {
+ URL imgUri;
+ try {
+ imgUri = new URL(img.attr("src"));
+
+ flavorImage.setTag(imgUri);
+
+ DisplayImageOptions options = new DisplayImageOptions.Builder().
+ cacheInMemory(true).
+ cacheOnDisk(true).
+ build();
+
+ ImageLoader.getInstance().displayImage(imgUri.toString(), flavorImage, options, new ImageLoadingListener() {
+
+ @Override
+ public void onLoadingCancelled(String arg0,
+ View arg1) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onLoadingComplete(String arg0,
+ View arg1, Bitmap arg2) {
+ // TODO Auto-generated method stub
+
+ flavorImage.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onLoadingFailed(String arg0,
+ View arg1, FailReason arg2) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onLoadingStarted(String arg0,
+ View arg1) {
+ // TODO Auto-generated method stub
+
+ }
+
+ });
+
+ //new DownloadFlavorImagesTask().execute(flavorImage);
+
+ } catch (MalformedURLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
- te.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineFontSize);
- te.setText(excerpt);
}
+
}
- // }
+
+ }
String articleAuthor = article.author != null ? article.author : "";
@@ -1081,5 +1088,61 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
public Feed getFeed() {
return m_feed;
}
-
+
+ /* class DownloadFlavorImagesTask extends AsyncTask<ImageView, Void, Bitmap> {
+ ImageView imageView = null;
+ @Override
+ protected Bitmap doInBackground(ImageView... imageViews) {
+ this.imageView = imageViews[0];
+ return download((URL)imageView.getTag());
+ }
+
+ @Override
+ protected void onPostExecute(Bitmap result) {
+ if (result != null) {
+ imageView.setImageBitmap(result);
+ imageView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ private Bitmap download(URL url) {
+ try {
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+
+ conn.setDoInput(true);
+ conn.setUseCaches(true);
+ conn.connect();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ byte[] buf = new byte[256];
+ int read = 0;
+
+ while ((read = conn.getInputStream().read(buf)) >= 0) {
+ bos.write(buf, 0, read);
+ }
+
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+
+ byte[] bitmap = bos.toByteArray();
+
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length, options);
+ options.inJustDecodeBounds = false;
+
+ int inSampleSize = CommonActivity.calculateInSampleSize(options, 128, 128);
+
+ Bitmap decodedBitmap = BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length, options);
+
+ return decodedBitmap;
+ } catch (OutOfMemoryError e) {
+ Log.d(TAG, "OOM while trying to decode headline flavor image. :(");
+ e.printStackTrace();
+ } catch (IOException e) {
+ //
+ }
+
+ return null;
+ }
+ } */
}