diff --git a/WordPress/src/main/assets/ic_reader_video_overlay.png b/WordPress/src/main/assets/ic_reader_video_overlay.png
new file mode 120000
index 000000000000..a58cc199483f
--- /dev/null
+++ b/WordPress/src/main/assets/ic_reader_video_overlay.png
@@ -0,0 +1 @@
+../res/drawable-xhdpi/ic_reader_video_overlay.png
\ No newline at end of file
diff --git a/WordPress/src/main/java/org/wordpress/android/datasets/ReaderDatabase.java b/WordPress/src/main/java/org/wordpress/android/datasets/ReaderDatabase.java
index e94203ba982d..abe69084ec24 100644
--- a/WordPress/src/main/java/org/wordpress/android/datasets/ReaderDatabase.java
+++ b/WordPress/src/main/java/org/wordpress/android/datasets/ReaderDatabase.java
@@ -19,7 +19,7 @@
*/
public class ReaderDatabase extends SQLiteOpenHelper {
protected static final String DB_NAME = "wpreader.db";
- private static final int DB_VERSION = 85;
+ private static final int DB_VERSION = 83;
/*
* version history
@@ -40,8 +40,6 @@ public class ReaderDatabase extends SQLiteOpenHelper {
* 81 - added image_url to tbl_blog_info
* 82 - added idx_posts_timestamp to tbl_posts
* 83 - removed tag_list from tbl_posts
- * 84 - added tbl_attachments
- * 85 - removed tbl_attachments, added attachments_json to tbl_posts
*/
/*
diff --git a/WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java b/WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java
index c1d9bc01414e..6bc66eafdee9 100644
--- a/WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java
+++ b/WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java
@@ -47,8 +47,7 @@ public class ReaderPostTable {
+ "primary_tag," // 26
+ "secondary_tag," // 27
+ "is_likes_enabled," // 28
- + "is_sharing_enabled," // 29
- + "attachments_json"; // 30
+ + "is_sharing_enabled"; // 29
protected static void createTables(SQLiteDatabase db) {
@@ -82,7 +81,6 @@ protected static void createTables(SQLiteDatabase db) {
+ " secondary_tag TEXT,"
+ " is_likes_enabled INTEGER DEFAULT 0,"
+ " is_sharing_enabled INTEGER DEFAULT 0,"
- + " attachments_json TEXT,"
+ " PRIMARY KEY (post_id, blog_id)"
+ ")");
db.execSQL("CREATE INDEX idx_posts_timestamp ON tbl_posts(timestamp)");
@@ -375,7 +373,7 @@ public static void addOrUpdatePosts(final ReaderTag tag, ReaderPostList posts) {
SQLiteStatement stmtPosts = db.compileStatement(
"INSERT OR REPLACE INTO tbl_posts ("
+ COLUMN_NAMES
- + ") VALUES (?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12,?13,?14,?15,?16,?17,?18,?19,?20,?21,?22,?23,?24,?25,?26,?27,?28,?29,?30)");
+ + ") VALUES (?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12,?13,?14,?15,?16,?17,?18,?19,?20,?21,?22,?23,?24,?25,?26,?27,?28,?29)");
SQLiteStatement stmtTags = db.compileStatement(
"INSERT OR REPLACE INTO tbl_post_tags (post_id, blog_id, pseudo_id, tag_name, tag_type) VALUES (?1,?2,?3,?4,?5)");
@@ -412,7 +410,6 @@ public static void addOrUpdatePosts(final ReaderTag tag, ReaderPostList posts) {
stmtPosts.bindString(27, post.getSecondaryTag());
stmtPosts.bindLong (28, SqlUtils.boolToSql(post.isLikesEnabled));
stmtPosts.bindLong (29, SqlUtils.boolToSql(post.isSharingEnabled));
- stmtPosts.bindString(30, post.getAttachmentsJson());
stmtPosts.execute();
}
@@ -563,8 +560,6 @@ private static class PostColumnIndexes {
private final int idx_is_likes_enabled;
private final int idx_is_sharing_enabled;
- private final int idx_attachments_json;
-
private PostColumnIndexes(Cursor c) {
if (c == null)
throw new IllegalArgumentException("PostColumnIndexes > null cursor");
@@ -605,8 +600,6 @@ private PostColumnIndexes(Cursor c) {
idx_is_likes_enabled = c.getColumnIndex("is_likes_enabled");
idx_is_sharing_enabled = c.getColumnIndex("is_sharing_enabled");
-
- idx_attachments_json = c.getColumnIndex("attachments_json");
}
}
@@ -659,8 +652,6 @@ private static ReaderPost getPostFromCursor(Cursor c, PostColumnIndexes cols) {
post.isLikesEnabled = SqlUtils.sqlToBool(c.getInt(cols.idx_is_likes_enabled));
post.isSharingEnabled = SqlUtils.sqlToBool(c.getInt(cols.idx_is_sharing_enabled));
- post.setAttachmentsJson(c.getString(cols.idx_attachments_json));
-
return post;
}
}
diff --git a/WordPress/src/main/java/org/wordpress/android/models/ReaderPost.java b/WordPress/src/main/java/org/wordpress/android/models/ReaderPost.java
index 313298d7ff28..0290b69484ce 100644
--- a/WordPress/src/main/java/org/wordpress/android/models/ReaderPost.java
+++ b/WordPress/src/main/java/org/wordpress/android/models/ReaderPost.java
@@ -52,8 +52,6 @@ public class ReaderPost {
public boolean isLikesEnabled;
public boolean isSharingEnabled; // currently unused
- private String attachmentsJson;
-
public static ReaderPost fromJson(JSONObject json) {
if (json == null) {
throw new IllegalArgumentException("null json post");
@@ -157,12 +155,6 @@ public static ReaderPost fromJson(JSONObject json) {
// parse the tags section
assignTagsFromJson(post, json.optJSONObject("tags"));
- // parse the attachments
- JSONObject jsonAttachments = json.optJSONObject("attachments");
- if (jsonAttachments != null) {
- post.attachmentsJson = jsonAttachments.toString();
- }
-
// the single-post sites/$site/posts/$post endpoint returns all site metadata
// under meta/data/site (assuming ?meta=site was added to the request)
JSONObject jsonSite = JSONUtil.getJSONChild(json, "meta/data/site");
@@ -351,6 +343,8 @@ public void setPublished(String published) {
this.published = StringUtils.notNullStr(published);
}
+ // --------------------------------------------------------------------------------------------
+
public String getPrimaryTag() {
return StringUtils.notNullStr(primaryTag);
}
@@ -374,17 +368,7 @@ public void setSecondaryTag(String tagName) {
}
}
- /*
- * attachments are stored as the actual JSON to avoid having a separate table for
- * them, may need to revisit this if/when attachments become more important
- */
- public String getAttachmentsJson() {
- return StringUtils.notNullStr(attachmentsJson);
- }
- public void setAttachmentsJson(String json) {
- attachmentsJson = StringUtils.notNullStr(json);
- }
-
+ // --------------------------------------------------------------------------------------------
public boolean hasText() {
return !TextUtils.isEmpty(text);
@@ -450,8 +434,12 @@ public String getFeaturedImageForDisplay(int width, int height) {
if (featuredImageForDisplay == null) {
if (!hasFeaturedImage()) {
featuredImageForDisplay = "";
+ } else if (isPrivate) {
+ // images in private posts can't use photon, so handle separately
+ featuredImageForDisplay = ReaderUtils.getPrivateImageForDisplay(featuredImage, width, height);
} else {
- featuredImageForDisplay = ReaderUtils.getResizedImageUrl(featuredImage, width, height, isPrivate);
+ // not private, so set to correctly sized photon url
+ featuredImageForDisplay = PhotonUtils.getPhotonImageUrl(featuredImage, width, height);
}
}
return featuredImageForDisplay;
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPhotoView.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPhotoView.java
index 34a4437b1585..e50c12ea19f5 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPhotoView.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPhotoView.java
@@ -21,6 +21,7 @@
import org.wordpress.android.ui.reader.utils.ReaderUtils;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.DisplayUtils;
+import org.wordpress.android.util.PhotonUtils;
import uk.co.senab.photoview.PhotoViewAttacher;
@@ -76,8 +77,13 @@ public void setImageUrl(String imageUrl,
boolean isPrivate,
PhotoViewListener listener) {
int loResWidth = (int) (hiResWidth * 0.10f);
- mLoResImageUrl = ReaderUtils.getResizedImageUrl(imageUrl, loResWidth, 0, isPrivate);
- mHiResImageUrl = ReaderUtils.getResizedImageUrl(imageUrl, hiResWidth, 0, isPrivate);
+ if (isPrivate) {
+ mLoResImageUrl = ReaderUtils.getPrivateImageForDisplay(imageUrl, loResWidth, 0);
+ mHiResImageUrl = ReaderUtils.getPrivateImageForDisplay(imageUrl, hiResWidth, 0);
+ } else {
+ mLoResImageUrl = PhotonUtils.getPhotonImageUrl(imageUrl, loResWidth, 0);
+ mHiResImageUrl = PhotonUtils.getPhotonImageUrl(imageUrl, hiResWidth, 0);
+ }
mPhotoViewListener = listener;
loadLoResImage();
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPhotoViewerActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPhotoViewerActivity.java
index 814c195a77ef..6451112c7c36 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPhotoViewerActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPhotoViewerActivity.java
@@ -16,7 +16,6 @@
import org.wordpress.android.ui.reader.ReaderViewPagerTransformer.TransformType;
import org.wordpress.android.ui.reader.models.ReaderImageList;
import org.wordpress.android.ui.reader.utils.ReaderImageScanner;
-import org.wordpress.android.util.AppLog;
import javax.annotation.Nonnull;
@@ -69,35 +68,26 @@ public void onPageSelected(int position) {
}
private void loadImageList() {
- // content will be empty unless this was called by ReaderPostDetailFragment to show
- // a list of images in a post (in which case, it's the content of the post)
- if (TextUtils.isEmpty(mContent)) {
- final ReaderImageList imageList = new ReaderImageList(mIsPrivate);
- if (!TextUtils.isEmpty(mInitialImageUrl)) {
- imageList.add(mInitialImageUrl);
- }
- setImageList(imageList, mInitialImageUrl);
- } else {
- // parse images from content and make sure the list includes the passed url
- new Thread() {
- @Override
- public void run() {
- final ReaderImageList imageList = new ReaderImageScanner(mContent, mIsPrivate).getImageList();
- if (!TextUtils.isEmpty(mInitialImageUrl) && !imageList.hasImageUrl(mInitialImageUrl)) {
- AppLog.w(AppLog.T.READER, "reader photo viewer > initial image not in list");
- imageList.addImageUrl(0, mInitialImageUrl);
- }
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (!isFinishing()) {
- setImageList(imageList, mInitialImageUrl);
- }
- }
- });
+ new Thread() {
+ @Override
+ public void run() {
+ // parse list of images from content that was (optionally) passed to
+ // this activity, and make sure the list includes the passed url
+ ReaderImageScanner scanner = new ReaderImageScanner(mContent, mIsPrivate);
+ final ReaderImageList imageList = scanner.getImageList();
+ if (!TextUtils.isEmpty(mInitialImageUrl) && !imageList.hasImageUrl(mInitialImageUrl)) {
+ imageList.addImageUrl(0, mInitialImageUrl);
}
- }.start();
- }
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (!isFinishing()) {
+ setImageList(imageList, mInitialImageUrl);
+ }
+ }
+ });
+ }
+ }.start();
}
private void setImageList(ReaderImageList imageList, String initialImageUrl) {
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailFragment.java
index 0d77842d9dc4..c7e44f8742e7 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailFragment.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailFragment.java
@@ -3,7 +3,10 @@
import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
+import android.content.Context;
import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
@@ -33,6 +36,7 @@
import org.wordpress.android.datasets.ReaderPostTable;
import org.wordpress.android.models.ReaderComment;
import org.wordpress.android.models.ReaderPost;
+import org.wordpress.android.ui.WPActionBarActivity;
import org.wordpress.android.ui.reader.ReaderActivityLauncher.OpenUrlType;
import org.wordpress.android.ui.reader.ReaderTypes.ReaderPostListType;
import org.wordpress.android.ui.reader.ReaderWebView.ReaderCustomViewListener;
@@ -49,7 +53,11 @@
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
import org.wordpress.android.util.DateTimeUtils;
+import org.wordpress.android.util.DisplayUtils;
import org.wordpress.android.util.EditTextUtils;
+import org.wordpress.android.util.HtmlUtils;
+import org.wordpress.android.util.PhotonUtils;
+import org.wordpress.android.util.StringUtils;
import org.wordpress.android.util.ToastUtils;
import org.wordpress.android.util.UrlUtils;
import org.wordpress.android.widgets.WPListView;
@@ -69,7 +77,7 @@ public class ReaderPostDetailFragment extends Fragment
private long mPostId;
private long mBlogId;
private ReaderPost mPost;
- private ReaderPostRenderer mRenderer;
+
private ReaderPostListType mPostListType;
private ViewGroup mLayoutIcons;
@@ -94,7 +102,7 @@ public class ReaderPostDetailFragment extends Fragment
private int mPrevScrollState = SCROLL_STATE_IDLE;
private Parcelable mListState;
- private ReaderResourceVars mResourceVars;
+ private ResourceVars mResourceVars;
private ReaderUtils.FullScreenListener mFullScreenListener;
@@ -122,6 +130,60 @@ public static ReaderPostDetailFragment newInstance(long blogId,
return fragment;
}
+ /*
+ * class which holds all resource-based variables used by this fragment
+ */
+ private static class ResourceVars {
+ final int displayWidth;
+ final int actionBarHeight;
+ final int likeAvatarSize;
+ final int videoOverlaySize;
+
+ final int marginLarge;
+ final int marginSmall;
+ final int marginExtraSmall;
+ final int listMarginWidth;
+ final int fullSizeImageWidth;
+
+ final int colorGreyExtraLight;
+ final int mediumAnimTime;
+
+ final String linkColorStr;
+ final String greyLightStr;
+ final String greyExtraLightStr;
+
+ private ResourceVars(Context context) {
+ Resources resources = context.getResources();
+
+ displayWidth = DisplayUtils.getDisplayPixelWidth(context);
+ actionBarHeight = DisplayUtils.getActionBarHeight(context);
+ likeAvatarSize = resources.getDimensionPixelSize(R.dimen.avatar_sz_small);
+ videoOverlaySize = resources.getDimensionPixelSize(R.dimen.reader_video_overlay_size);
+
+ marginLarge = resources.getDimensionPixelSize(R.dimen.margin_large);
+ marginSmall = resources.getDimensionPixelSize(R.dimen.margin_small);
+ marginExtraSmall = resources.getDimensionPixelSize(R.dimen.margin_extra_small);
+ listMarginWidth = resources.getDimensionPixelOffset(R.dimen.reader_list_margin);
+
+ colorGreyExtraLight = resources.getColor(R.color.grey_extra_light);
+ mediumAnimTime = resources.getInteger(android.R.integer.config_mediumAnimTime);
+
+ linkColorStr = HtmlUtils.colorResToHtmlColor(context, R.color.reader_hyperlink);
+ greyLightStr = HtmlUtils.colorResToHtmlColor(context, R.color.grey_light);
+ greyExtraLightStr = HtmlUtils.colorResToHtmlColor(context, R.color.grey_extra_light);
+
+ int imageWidth = displayWidth - (listMarginWidth * 2);
+ boolean hasStaticMenuDrawer =
+ (context instanceof WPActionBarActivity)
+ && (((WPActionBarActivity) context).isStaticMenuDrawer());
+ if (hasStaticMenuDrawer) {
+ int drawerWidth = resources.getDimensionPixelOffset(R.dimen.menu_drawer_width);
+ imageWidth -= drawerWidth;
+ }
+ fullSizeImageWidth = imageWidth;
+ }
+ }
+
/*
* adapter containing comments for this post
*/
@@ -224,7 +286,7 @@ public void setArguments(Bundle args) {
public void onAttach(Activity activity) {
super.onAttach(activity);
- mResourceVars = new ReaderResourceVars(activity);
+ mResourceVars = new ResourceVars(activity);
if (activity instanceof ReaderUtils.FullScreenListener) {
mFullScreenListener = (ReaderUtils.FullScreenListener) activity;
@@ -238,13 +300,14 @@ public void onAttach(Activity activity) {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.reader_fragment_post_detail, container, false);
+ final Context context = container.getContext();
// locate & init listView
mListView = (WPListView) view.findViewById(android.R.id.list);
if (isFullScreenSupported()) {
mListView.setOnScrollDirectionListener(this);
mListView.setOnScrollListener(this);
- ReaderUtils.addListViewHeader(mListView, mResourceVars.actionBarHeightPx);
+ ReaderUtils.addListViewHeader(mListView, mResourceVars.actionBarHeight);
}
// add post detail as header to listView - must be done before setting adapter
@@ -943,7 +1006,33 @@ private void refreshFollowed() {
ReaderUtils.showFollowStatus(txtFollow, isFollowed);
}
- private boolean showPhotoViewer(String imageUrl, View sourceView, int startX, int startY) {
+ /*
+ * creates formatted div for passed video with passed (optional) thumbnail
+ */
+ private static final String OVERLAY_IMG = "file:///android_asset/ic_reader_video_overlay.png";
+
+ private String makeVideoDiv(String videoUrl, String thumbnailUrl) {
+ if (TextUtils.isEmpty(videoUrl)) {
+ return "";
+ }
+
+ // sometimes we get src values like "//player.vimeo.com/video/70534716" - prefix these with http:
+ if (videoUrl.startsWith("//")) {
+ videoUrl = "http:" + videoUrl;
+ }
+
+ int overlaySz = mResourceVars.videoOverlaySize / 2;
+ if (TextUtils.isEmpty(thumbnailUrl)) {
+ return String.format("
", videoUrl, overlaySz, overlaySz, OVERLAY_IMG);
+ } else {
+ return ""
+ + String.format("
", videoUrl, thumbnailUrl)
+ + String.format("
", videoUrl, OVERLAY_IMG, overlaySz, overlaySz)
+ + "
";
+ }
+ }
+
+ private boolean showPhotoViewer(String imageUrl, View source, int startX, int startY) {
if (!isAdded() || TextUtils.isEmpty(imageUrl)) {
return false;
}
@@ -953,14 +1042,13 @@ private boolean showPhotoViewer(String imageUrl, View sourceView, int startX, in
return false;
}
- String postContent = (mRenderer != null ? mRenderer.getRenderedHtml() : null);
boolean isPrivatePost = (mPost != null && mPost.isPrivate);
ReaderActivityLauncher.showReaderPhotoViewer(
getActivity(),
imageUrl,
- postContent,
- sourceView,
+ getPostContent(),
+ source,
isPrivatePost,
startX,
startY);
@@ -968,6 +1056,134 @@ private boolean showPhotoViewer(String imageUrl, View sourceView, int startX, in
return true;
}
+ /*
+ * returns the basic content of the post tweaked for use here
+ */
+ private String getPostContent() {
+ if (mPost == null) {
+ return "";
+ } else if (mPost.hasText()) {
+ // some content (such as Vimeo embeds) don't have "http:" before links, correct this here
+ String content = mPost.getText().replace("src=\"//", "src=\"http://");
+ // insert video div before content if this is a VideoPress post (video otherwise won't appear)
+ if (mPost.isVideoPress) {
+ content = makeVideoDiv(mPost.getFeaturedVideo(), mPost.getFeaturedImage()) + content;
+ } else if (mPost.hasFeaturedImage() && !PhotonUtils.isMshotsUrl(mPost.getFeaturedImage())) {
+ // if the post has a featured image other than an mshot that's not in the content,
+ // add it to the content
+ Uri uri = Uri.parse(mPost.getFeaturedImage());
+ String path = StringUtils.notNullStr(uri.getLastPathSegment());
+ if (!content.contains(path)) {
+ AppLog.d(T.READER, "reader post detail > added featured image to content");
+ content = String.format("", mPost.getFeaturedImage())
+ + content;
+ }
+ }
+ return content;
+ } else if (mPost.hasFeaturedImage()) {
+ // some photo blogs have posts with empty content but still have a featured image, so
+ // use the featured image as the content
+ return String.format("", mPost.getFeaturedImage());
+ } else {
+ return "";
+ }
+ }
+
+ /*
+ * returns the full content, including CSS, that will be shown in the WebView for this post
+ */
+ private String getPostContentForWebView(Context context) {
+ if (mPost == null || context == null) {
+ return "";
+ }
+
+ String content = getPostContent();
+
+ StringBuilder sbHtml = new StringBuilder("");
+
+ // title isn't strictly necessary, but source is invalid html5 without one
+ sbHtml.append("Reader Post");
+
+ // https://developers.google.com/chrome/mobile/docs/webview/pixelperfect
+ sbHtml.append("");
+
+ // use "Open Sans" Google font
+ sbHtml.append("");
+
+ sbHtml.append("")
+ .append(content)
+ .append("");
+
+ return sbHtml.toString();
+ }
+
/*
* called when the post doesn't exist in local db, need to get it from server
*/
@@ -1001,10 +1217,16 @@ private void postFailed() {
}
}
+ /*
+ * javascript should only be enabled for wp blogs (not external feeds)
+ */
+ private boolean canEnableJavaScript() {
+ return (mPost != null && mPost.isWP());
+ }
+
private void showPost() {
if (mIsPostTaskRunning) {
AppLog.w(T.READER, "reader post detail > show post task already running");
- return;
}
new ShowPostTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@@ -1028,6 +1250,8 @@ private class ShowPostTask extends AsyncTask {
WPNetworkImageView imgAvatar;
ViewGroup layoutDetailHeader;
+ String postHtml;
+
@Override
protected void onPreExecute() {
mIsPostTaskRunning = true;
@@ -1064,6 +1288,8 @@ protected Boolean doInBackground(Void... params) {
layoutDetailHeader = (ViewGroup) container.findViewById(R.id.layout_detail_header);
+ postHtml = getPostContentForWebView(container.getContext());
+
return true;
}
@@ -1080,15 +1306,17 @@ protected void onPostExecute(Boolean result) {
// the server if it hasn't already been requested
if (!mHasAlreadyRequestedPost) {
mHasAlreadyRequestedPost = true;
- AppLog.i(T.READER, "reader post detail > post not found, requesting it");
requestPost();
}
return;
}
- // render the post in the webView
- mRenderer = new ReaderPostRenderer(mReaderWebView, mPost);
- mRenderer.beginRender();
+ // enable JavaScript in the webView if it's safe to do so
+ mReaderWebView.getSettings().setJavaScriptEnabled(canEnableJavaScript());
+
+ // IMPORTANT: use loadDataWithBaseURL() since loadData() may fail
+ // https://code.google.com/p/android/issues/detail?id=4401
+ mReaderWebView.loadDataWithBaseURL(null, postHtml, "text/html", "UTF-8", null);
txtTitle.setText(mPost.hasTitle() ? mPost.getTitle() : getString(R.string.reader_untitled_post));
@@ -1121,13 +1349,13 @@ public void onClick(View view) {
if (mPost.hasPostAvatar()) {
imgAvatar.setImageUrl(mPost.getPostAvatarForDisplay(
- mResourceVars.likeAvatarSizePx), WPNetworkImageView.ImageType.AVATAR);
+ mResourceVars.likeAvatarSize), WPNetworkImageView.ImageType.AVATAR);
imgAvatar.setVisibility(View.VISIBLE);
} else {
imgAvatar.setVisibility(View.GONE);
}
- // hide header if this fragment was shown from blog preview
+ // hide blog name, avatar & follow button if this fragment was shown from blog preview
if (isBlogPreview()) {
layoutDetailHeader.setVisibility(View.GONE);
}
@@ -1204,6 +1432,7 @@ public void onClick(View view) {
}
}
+
/*
* called by the web view when the content finishes loading - likes & comments aren't displayed
* until this is triggered, to avoid having them appear before the webView content
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java
index 2d0884d392c6..641140877d03 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java
@@ -17,6 +17,7 @@
import org.wordpress.android.datasets.ReaderTagTable;
import org.wordpress.android.models.ReaderTag;
import org.wordpress.android.models.ReaderTagType;
+import org.wordpress.android.util.NetworkUtils;
import org.wordpress.android.ui.WPActionBarActivity;
import org.wordpress.android.ui.accounts.WPComLoginActivity;
import org.wordpress.android.ui.prefs.AppPrefs;
@@ -29,7 +30,6 @@
import org.wordpress.android.ui.reader.services.ReaderUpdateService.UpdateTask;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
-import org.wordpress.android.util.NetworkUtils;
import org.wordpress.android.util.StringUtils;
import java.util.EnumSet;
@@ -412,11 +412,6 @@ public void onReceive(Context context, Intent intent) {
} else if (listFragment.getPostListType() == ReaderTypes.ReaderPostListType.TAG_FOLLOWED) {
// list fragment is viewing followed tags, tell it to refresh the list of tags
listFragment.refreshTags();
- // update the current tag if the list fragment is empty - this will happen if
- // the tag table was previously empty (ie: first run)
- if (listFragment.isPostAdapterEmpty()) {
- listFragment.updateCurrentTag();
- }
}
} else if (action.equals(ReaderUpdateService.ACTION_FOLLOWED_BLOGS_CHANGED)) {
// followed blogs have changed, so remove posts in blogs that are
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java
index 832605d939c3..d85df3f9af96 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java
@@ -872,10 +872,6 @@ public void onActionResult(boolean succeeded) {
ReaderPostActions.requestPostsForBlog(mCurrentBlogId, mCurrentBlogUrl, updateAction, listener);
}
- void updateCurrentTag() {
- updatePostsWithTag(getCurrentTag(), RequestDataAction.LOAD_NEWER, ReaderTypes.RefreshType.AUTOMATIC);
- }
-
/*
* get latest posts for this tag from the server
*/
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostPagerActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostPagerActivity.java
index 7d2f500dfa7a..6d883f454118 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostPagerActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostPagerActivity.java
@@ -25,6 +25,7 @@
import org.wordpress.android.models.ReaderPost;
import org.wordpress.android.models.ReaderPostList;
import org.wordpress.android.models.ReaderTag;
+import org.wordpress.android.util.NetworkUtils;
import org.wordpress.android.ui.reader.ReaderAnim.AnimationEndListener;
import org.wordpress.android.ui.reader.ReaderAnim.Duration;
import org.wordpress.android.ui.reader.ReaderPostPagerEndFragment.EndFragmentType;
@@ -39,7 +40,6 @@
import org.wordpress.android.ui.reader.models.ReaderBlogIdPostIdList;
import org.wordpress.android.ui.reader.utils.ReaderUtils;
import org.wordpress.android.util.AppLog;
-import org.wordpress.android.util.NetworkUtils;
import org.wordpress.android.util.ToastUtils;
import javax.annotation.Nonnull;
@@ -232,12 +232,15 @@ private void loadPosts(final long blogId,
new Thread() {
@Override
public void run() {
- final ReaderBlogIdPostIdList idList;
+ final ReaderPostList postList;
if (mIsSinglePostView) {
- idList = new ReaderBlogIdPostIdList();
- idList.add(new ReaderBlogIdPostId(blogId, postId));
+ ReaderPost post = ReaderPostTable.getPost(blogId, postId);
+ if (post == null) {
+ return;
+ }
+ postList = new ReaderPostList();
+ postList.add(post);
} else {
- final ReaderPostList postList;
int maxPosts = ReaderConstants.READER_MAX_POSTS_TO_DISPLAY;
switch (getPostListType()) {
case TAG_FOLLOWED:
@@ -250,22 +253,22 @@ public void run() {
default:
return;
}
- idList = postList.getBlogIdPostIdList();
}
+ final ReaderBlogIdPostIdList ids = postList.getBlogIdPostIdList();
final int currentPosition = mViewPager.getCurrentItem();
final int newPosition;
if (gotoNext) {
- newPosition = idList.indexOf(blogId, postId) + 1;
+ newPosition = ids.indexOf(blogId, postId) + 1;
} else {
- newPosition = idList.indexOf(blogId, postId);
+ newPosition = ids.indexOf(blogId, postId);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
mPagerAdapter = new PostPagerAdapter(getFragmentManager());
- mPagerAdapter.showPosts(idList);
+ mPagerAdapter.showPosts(ids);
mViewPager.setAdapter(mPagerAdapter);
if (mPagerAdapter.isValidPosition(newPosition)) {
mViewPager.setCurrentItem(newPosition);
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostRenderer.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostRenderer.java
deleted file mode 100644
index f7c41302226e..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostRenderer.java
+++ /dev/null
@@ -1,427 +0,0 @@
-package org.wordpress.android.ui.reader;
-
-import android.annotation.SuppressLint;
-import android.net.Uri;
-import android.os.Handler;
-import android.text.TextUtils;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.wordpress.android.WordPress;
-import org.wordpress.android.models.ReaderPost;
-import org.wordpress.android.ui.reader.utils.ReaderImageScanner;
-import org.wordpress.android.ui.reader.utils.ReaderUtils;
-import org.wordpress.android.util.AppLog;
-import org.wordpress.android.util.DisplayUtils;
-import org.wordpress.android.util.JSONUtil;
-import org.wordpress.android.util.PhotonUtils;
-import org.wordpress.android.util.StringUtils;
-import org.wordpress.android.util.UrlUtils;
-
-import java.lang.ref.WeakReference;
-import java.util.HashMap;
-import java.util.Iterator;
-
-/**
- * generates and displays the HTML for post detail content - main purpose is to assign the
- * height/width attributes on image tags to (1) avoid the webView resizing as images are
- * loaded, and (2) avoid requesting images at a size larger than the display
- *
- * important to note that displayed images rely on dp rather than px sizes due to the
- * fact that WebView "converts CSS pixel values to density-independent pixel values"
- * http://developer.android.com/guide/webapps/targeting.html
- */
-class ReaderPostRenderer {
-
- private final ReaderResourceVars mResourceVars;
- private final ReaderPost mPost;
- private final int mMinFullSizeWidthDp;
- private final int mMinMidSizeWidthDp;
- private final WeakReference mWeakWebView;
-
- private StringBuilder mRenderBuilder;
- private String mRenderedHtml;
- private ImageSizeMap mAttachmentSizes;
-
- @SuppressLint("SetJavaScriptEnabled")
- ReaderPostRenderer(ReaderWebView webView, ReaderPost post) {
- if (webView == null) {
- throw new IllegalArgumentException("ReaderPostRenderer requires a webView");
- }
- if (post == null) {
- throw new IllegalArgumentException("ReaderPostRenderer requires a post");
- }
-
- mPost = post;
- mWeakWebView = new WeakReference(webView);
- mResourceVars = new ReaderResourceVars(webView.getContext());
-
- mMinFullSizeWidthDp = pxToDp(mResourceVars.fullSizeImageWidthPx / 3);
- mMinMidSizeWidthDp = mMinFullSizeWidthDp / 2;
-
- // enable JavaScript in the webView if it's safe to do so, otherwise videos
- // and other embedded content won't work
- webView.getSettings().setJavaScriptEnabled(canEnableJavaScript());
- }
-
- void beginRender() {
- mRenderBuilder = new StringBuilder(getPostContent());
-
- // start image scanner to find images so we can replace them with ones that have h/w set
- final Handler handler = new Handler();
- new Thread() {
- @Override
- public void run() {
- ReaderImageScanner.ImageScanListener imageListener = new ReaderImageScanner.ImageScanListener() {
- @Override
- public void onImageFound(String imageTag, String imageUrl, int start, int end) {
- replaceImageTag(imageTag, imageUrl);
- }
-
- @Override
- public void onScanCompleted() {
- final String htmlContent = formatPostContentForWebView(mRenderBuilder.toString());
- mRenderBuilder = null;
- handler.post(new Runnable() {
- @Override
- public void run() {
- renderHtmlContent(htmlContent);
- }
- });
- }
- };
- ReaderImageScanner scanner = new ReaderImageScanner(mRenderBuilder.toString(), mPost.isPrivate);
- scanner.beginScan(imageListener);
- }
- }.start();
- }
-
- /*
- * called once the content is ready to be rendered in the webView
- */
- private void renderHtmlContent(final String htmlContent) {
- mRenderedHtml = htmlContent;
-
- // make sure webView is still valid (containing fragment may have been detached)
- ReaderWebView webView = mWeakWebView.get();
- if (webView == null) {
- AppLog.w(AppLog.T.READER, "reader renderer > null webView");
- return;
- }
-
- // IMPORTANT: use loadDataWithBaseURL() since loadData() may fail
- // https://code.google.com/p/android/issues/detail?id=4401
- // also important to use null as the baseUrl since onPageFinished
- // doesn't appear to fire when it's set to an actual url
- webView.loadDataWithBaseURL(null, htmlContent, "text/html", "UTF-8", null);
- }
-
- /*
- * called when image scanner finds an image, tries to replace the image tag with one that
- * has height & width attributes set correctly for the current display, if that fails
- * replaces it with one that has our 'size-none' class
- */
- private void replaceImageTag(final String imageTag, final String imageUrl) {
- ImageSize origSize = getImageSize(imageTag, imageUrl);
- boolean hasWidth = (origSize != null && origSize.width > 0);
- boolean isFullSize = hasWidth && (origSize.width >= mMinFullSizeWidthDp);
- boolean isMidSize = hasWidth
- && (origSize.width >= mMinMidSizeWidthDp)
- && (origSize.width < mMinFullSizeWidthDp);
-
- final String newImageTag;
- if (isFullSize) {
- newImageTag = makeFullSizeImageTag(imageUrl, origSize.width, origSize.height);
- } else if (isMidSize) {
- newImageTag = makeImageTag(imageUrl, origSize.width, origSize.height, "size-medium");
- } else if (hasWidth) {
- newImageTag = makeImageTag(imageUrl, origSize.width, origSize.height, "size-none");
- } else {
- newImageTag = "";
- }
-
- int start = mRenderBuilder.indexOf(imageTag);
- if (start == -1) {
- AppLog.w(AppLog.T.READER, "reader renderer > image not found in builder");
- return;
- }
-
- mRenderBuilder.replace(start, start + imageTag.length(), newImageTag);
- }
-
- private String makeImageTag(final String imageUrl, int width, int height, final String imageClass) {
- String newImageUrl = ReaderUtils.getResizedImageUrl(imageUrl, width, height, mPost.isPrivate);
- if (height > 0) {
- return new StringBuilder("")
- .toString();
- } else {
- return new StringBuilder("")
- .toString();
- }
- }
-
- private String makeFullSizeImageTag(final String imageUrl, int width, int height) {
- int newWidth;
- int newHeight;
- if (width > 0 && height > 0) {
- if (height > width) {
- newHeight = mResourceVars.fullSizeImageWidthPx;
- float ratio = ((float) width / (float) height);
- newWidth = (int) (newHeight * ratio);
- } else {
- float ratio = ((float) height / (float) width);
- newWidth = mResourceVars.fullSizeImageWidthPx;
- newHeight = (int) (newWidth * ratio);
- }
- } else {
- newWidth = mResourceVars.fullSizeImageWidthPx;
- newHeight = 0;
- }
-
- return makeImageTag(imageUrl, newWidth, newHeight, "size-full");
- }
-
- /*
- * returns true if the post has a featured image and there are no images in the
- * post's content - when this is the case, the featured image is inserted at
- * the top of the content
- */
- private boolean shouldAddFeaturedImage() {
- return mPost.hasFeaturedImage()
- && !mPost.getText().contains(" added featured image");
- content = getFeaturedImageHtml() + content;
- }
- return content;
- }
-
- /*
- * returns the HTML that was last rendered, will be null prior to rendering
- */
- String getRenderedHtml() {
- return mRenderedHtml;
- }
-
- /*
- * returns the HTML to use when inserting a featured image into the rendered content
- */
- private String getFeaturedImageHtml() {
- String imageUrl = ReaderUtils.getResizedImageUrl(
- mPost.getFeaturedImage(),
- mResourceVars.fullSizeImageWidthPx,
- mResourceVars.featuredImageHeightPx,
- mPost.isPrivate);
-
- return "";
- }
-
- /*
- * returns the full content, including CSS, that will be shown in the WebView for this post
- */
- private String formatPostContentForWebView(final String content) {
- StringBuilder sbHtml = new StringBuilder("");
-
- // title isn't necessary, but it's invalid html5 without one
- sbHtml.append("Reader Post")
-
- // https://developers.google.com/chrome/mobile/docs/webview/pixelperfect
- .append("")
-
- // use "Open Sans" Google font
- .append("")
-
- .append("")
- .append("")
- .append(content)
- .append("");
-
- return sbHtml.toString();
- }
-
- private ImageSize getImageSize(final String imageTag, final String imageUrl) {
- ImageSize size = getImageSizeFromAttachments(imageUrl);
- if (size == null && imageUrl.contains("?")) {
- size = getImageSizeFromQueryParams(imageUrl);
- }
- if (size == null && imageTag.contains("width=")) {
- size = getImageSizeFromAttributes(imageTag);
- }
- return size;
- }
-
- private ImageSize getImageSizeFromAttachments(final String imageUrl) {
- if (mAttachmentSizes == null) {
- mAttachmentSizes = new ImageSizeMap(mPost.getAttachmentsJson());
- }
- return mAttachmentSizes.getAttachmentSize(imageUrl);
- }
-
- private ImageSize getImageSizeFromQueryParams(final String imageUrl) {
- if (imageUrl.contains("w=")) {
- Uri uri = Uri.parse(imageUrl.replace("&", "&"));
- return new ImageSize(
- StringUtils.stringToInt(uri.getQueryParameter("w")),
- StringUtils.stringToInt(uri.getQueryParameter("h")));
- } else if (imageUrl.contains("resize=")) {
- Uri uri = Uri.parse(imageUrl.replace("&", "&"));
- String param = uri.getQueryParameter("resize");
- if (param != null) {
- String[] sizes = param.split(",");
- if (sizes.length == 2) {
- return new ImageSize(
- StringUtils.stringToInt(sizes[0]),
- StringUtils.stringToInt(sizes[1]));
- }
- }
- }
-
- return null;
- }
-
- private ImageSize getImageSizeFromAttributes(final String imageTag) {
- return new ImageSize(
- ReaderImageScanner.getWidthAttrValue(imageTag),
- ReaderImageScanner.getHeightAttrValue(imageTag));
- }
-
- private int pxToDp(int px) {
- if (px == 0) {
- return 0;
- }
- return DisplayUtils.pxToDp(WordPress.getContext(), px);
- }
-
- /*
- * javascript should only be enabled for wp blogs (not external feeds)
- */
- private boolean canEnableJavaScript() {
- return mPost.isWP();
- }
-
- /*
- * hash map of sizes of attachments in the current post for quick lookup - created from
- * the json "attachments" section of the post endpoints
- */
- class ImageSizeMap extends HashMap {
- ImageSizeMap(String jsonString) {
- if (TextUtils.isEmpty(jsonString)) {
- return;
- }
-
- try {
- JSONObject json = new JSONObject(jsonString);
- Iterator it = json.keys();
- if (!it.hasNext()) {
- return;
- }
-
- while (it.hasNext()) {
- JSONObject jsonAttach = json.optJSONObject(it.next());
- if (jsonAttach != null && JSONUtil.getString(jsonAttach, "mime_type").startsWith("image")) {
- String normUrl = UrlUtils.normalizeUrl(UrlUtils.removeQuery(JSONUtil.getString(json, "URL")));
- int width = jsonAttach.optInt("width");
- int height = jsonAttach.optInt("height");
- this.put(normUrl, new ImageSize(width, height));
- }
- }
- } catch (JSONException e) {
- AppLog.e(AppLog.T.READER, e);
- }
- }
-
- ImageSize getAttachmentSize(final String imageUrl) {
- if (imageUrl == null) {
- return null;
- } else {
- return super.get(UrlUtils.normalizeUrl(UrlUtils.removeQuery(imageUrl)));
- }
- }
- }
-
- static class ImageSize {
- final int width;
- final int height;
- ImageSize(int width, int height) {
- this.width = width;
- this.height = height;
- }
- }
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderResourceVars.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderResourceVars.java
deleted file mode 100644
index 03ac68be85b4..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderResourceVars.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.wordpress.android.ui.reader;
-
-import android.content.Context;
-import android.content.res.Resources;
-
-import org.wordpress.android.R;
-import org.wordpress.android.ui.WPActionBarActivity;
-import org.wordpress.android.util.DisplayUtils;
-import org.wordpress.android.util.HtmlUtils;
-
-/*
- * class which holds all resource-based variables used when rendering post detail
- */
-class ReaderResourceVars {
- final int displayWidthPx;
- final int actionBarHeightPx;
- final int likeAvatarSizePx;
-
- final int marginLargePx;
- final int marginSmallPx;
- final int marginExtraSmallPx;
- final int listMarginWidthPx;
-
- final int fullSizeImageWidthPx;
- final int featuredImageHeightPx;
-
- final int videoWidthPx;
- final int videoHeightPx;
-
- final int colorGreyExtraLight;
- final int mediumAnimTime;
-
- final String linkColorStr;
- final String greyMediumDarkStr;
- final String greyLightStr;
- final String greyExtraLightStr;
-
- ReaderResourceVars(Context context) {
- Resources resources = context.getResources();
-
- displayWidthPx = DisplayUtils.getDisplayPixelWidth(context);
- actionBarHeightPx = DisplayUtils.getActionBarHeight(context);
- likeAvatarSizePx = resources.getDimensionPixelSize(R.dimen.avatar_sz_small);
- featuredImageHeightPx = resources.getDimensionPixelSize(R.dimen.reader_featured_image_height);
-
- marginLargePx = resources.getDimensionPixelSize(R.dimen.margin_large);
- marginSmallPx = resources.getDimensionPixelSize(R.dimen.margin_small);
- marginExtraSmallPx = resources.getDimensionPixelSize(R.dimen.margin_extra_small);
- listMarginWidthPx = resources.getDimensionPixelOffset(R.dimen.reader_list_margin);
-
- colorGreyExtraLight = resources.getColor(R.color.grey_extra_light);
- mediumAnimTime = resources.getInteger(android.R.integer.config_mediumAnimTime);
-
- linkColorStr = HtmlUtils.colorResToHtmlColor(context, R.color.reader_hyperlink);
- greyMediumDarkStr = HtmlUtils.colorResToHtmlColor(context, R.color.grey_medium_dark);
- greyLightStr = HtmlUtils.colorResToHtmlColor(context, R.color.grey_light);
- greyExtraLightStr = HtmlUtils.colorResToHtmlColor(context, R.color.grey_extra_light);
-
- // full-size image width must take list margin and padding into account
- int listPadding = resources.getDimensionPixelOffset(R.dimen.margin_large);
- int imageWidth = displayWidthPx - (listMarginWidthPx * 2) - (listPadding * 2);
- boolean hasStaticMenuDrawer =
- (context instanceof WPActionBarActivity)
- && (((WPActionBarActivity) context).isStaticMenuDrawer());
- if (hasStaticMenuDrawer) {
- int drawerWidth = resources.getDimensionPixelOffset(R.dimen.menu_drawer_width);
- imageWidth -= drawerWidth;
- }
- fullSizeImageWidthPx = imageWidth;
-
- // 16:9 ratio (YouTube standard)
- videoWidthPx = fullSizeImageWidthPx - (marginLargePx * 2);
- videoHeightPx = (int) (videoWidthPx * 0.5625f);
- }
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/utils/ReaderImageScanner.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/utils/ReaderImageScanner.java
index 08173de03623..3549e6f2930d 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/utils/ReaderImageScanner.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/utils/ReaderImageScanner.java
@@ -1,7 +1,6 @@
package org.wordpress.android.ui.reader.utils;
import android.net.Uri;
-import android.text.TextUtils;
import org.wordpress.android.ui.reader.models.ReaderImageList;
import org.wordpress.android.util.PhotonUtils;
@@ -13,18 +12,13 @@
public class ReaderImageScanner {
- public static interface ImageScanListener {
- public void onImageFound(String imageTag, String imageUrl, int start, int end);
- public void onScanCompleted();
- }
private final String mContent;
private final boolean mIsPrivate;
- private final boolean mContentContainsImages;
private static final int MIN_FEATURED_IMAGE_WIDTH = 500;
// regex for matching img tags in html content
private static final Pattern IMG_TAG_PATTERN = Pattern.compile(
- "",
+ "",
Pattern.DOTALL| Pattern.CASE_INSENSITIVE);
// regex for matching width attributes in tags
@@ -32,11 +26,6 @@ public static interface ImageScanListener {
"width\\s*=\\s*(?:'|\")(.*?)(?:'|\")",
Pattern.DOTALL|Pattern.CASE_INSENSITIVE);
- // regex for matching height attributes in tags
- private static final Pattern HEIGHT_ATTR_PATTERN = Pattern.compile(
- "height\\s*=\\s*(?:'|\")(.*?)(?:'|\")",
- Pattern.DOTALL|Pattern.CASE_INSENSITIVE);
-
// regex for matching src attributes in tags
private static final Pattern SRC_ATTR_PATTERN = Pattern.compile(
"src\\s*=\\s*(?:'|\")(.*?)(?:'|\")",
@@ -45,41 +34,15 @@ public static interface ImageScanListener {
public ReaderImageScanner(String contentOfPost, boolean isPrivate) {
mContent = contentOfPost;
mIsPrivate = isPrivate;
- mContentContainsImages = mContent != null && mContent.contains(" 0 && height > 0) {
- query = "?w=" + width + "&h=" + height;
+ query = String.format("?w=%d&h=%d", width, height);
} else if (width > 0) {
- query = "?w=" + width;
+ query = String.format("?w=%d", width);
} else if (height > 0) {
- query = "?h=" + height;
+ query = String.format("?h=%d", height);
} else {
query = "";
}
diff --git a/WordPress/src/main/res/layout/reader_listitem_post_detail.xml b/WordPress/src/main/res/layout/reader_listitem_post_detail.xml
index e346246e84d9..3642f6314220 100644
--- a/WordPress/src/main/res/layout/reader_listitem_post_detail.xml
+++ b/WordPress/src/main/res/layout/reader_listitem_post_detail.xml
@@ -40,7 +40,7 @@
android:layout_marginBottom="@dimen/margin_small"
android:ellipsize="end"
android:maxLines="2"
- android:textColor="@color/grey_dark"
+ android:textColor="@color/reader_hyperlink"
android:textSize="@dimen/text_sz_medium"
tools:text="text_blog_name" />
diff --git a/WordPress/src/main/res/values/dimens.xml b/WordPress/src/main/res/values/dimens.xml
index 7fee4b237e47..943037c2ca23 100644
--- a/WordPress/src/main/res/values/dimens.xml
+++ b/WordPress/src/main/res/values/dimens.xml
@@ -68,6 +68,7 @@
340dp
@dimen/reader_featured_image_height_default
+ 48dp
12dp
@dimen/margin_large
diff --git a/libs/utils/WordPressUtils/src/main/java/org/wordpress/android/util/PhotonUtils.java b/libs/utils/WordPressUtils/src/main/java/org/wordpress/android/util/PhotonUtils.java
index bf275e56abdc..497d756ee377 100644
--- a/libs/utils/WordPressUtils/src/main/java/org/wordpress/android/util/PhotonUtils.java
+++ b/libs/utils/WordPressUtils/src/main/java/org/wordpress/android/util/PhotonUtils.java
@@ -24,7 +24,7 @@ public static String fixAvatar(final String imageUrl, int avatarSz) {
return getPhotonImageUrl(imageUrl, avatarSz, avatarSz);
// remove all other params, then add query string for size and "mystery man" default
- return UrlUtils.removeQuery(imageUrl) + "?s=" + avatarSz + "&d=mm";
+ return UrlUtils.removeQuery(imageUrl) + String.format("?s=%d&d=mm", avatarSz);
}
/*
@@ -64,18 +64,18 @@ public static String getPhotonImageUrl(String imageUrl, int width, int height) {
// see http://wp.tutsplus.com/tutorials/how-to-generate-website-screenshots-for-your-wordpress-site/
// ex: http://s.wordpress.com/mshots/v1/http%3A%2F%2Fnickbradbury.com?w=600
if (isMshotsUrl(imageUrl)) {
- return imageUrl + "?w=" + width + "&h=" + height;
+ return imageUrl + String.format("?w=%d&h=%d", width, height);
}
// if both width & height are passed use the "resize" param, use only "w" or "h" if just
// one of them is set, otherwise no query string
final String query;
if (width > 0 && height > 0) {
- query = "?resize=" + width + "," + height;
+ query = String.format("?resize=%d,%d", width, height);
} else if (width > 0) {
- query = "?w=" + width;
+ query = String.format("?w=%d", width);
} else if (height > 0) {
- query = "?h=" + height;
+ query = String.format("?h=%d", height);
} else {
query = "";
}