Merge "Import translations. DO NOT MERGE" into jb-ub-mail
diff --git a/assets/script.js b/assets/script.js
index 7efdc31..ee15d03 100644
--- a/assets/script.js
+++ b/assets/script.js
@@ -105,14 +105,12 @@
*/
function rewriteRelativeImageSrc(imgElement) {
var src = imgElement.src;
- if (src.indexOf(ACCOUNT_URI) == 0) {
- var questionPos = src.indexOf('?');
- if (ACCOUNT_URI.indexOf('content://') == 0 && questionPos != -1) {
- // For some reason, when webview makes a content provider openFile call the query
- // parameters are removed. Instead, replace the '?' with '/'
- src = src.substring(0, questionPos) + "/" + src.substring(questionPos + 1);
- imgElement.src = src;
- }
+
+ // DOC_BASE_URI will always be a unique x-thread:// uri for this particular conversation
+ if (src.indexOf(DOC_BASE_URI) == 0 && (DOC_BASE_URI != CONVERSATION_BASE_URI)) {
+ // The conversation specifies a different base uri than the document
+ src = CONVERSATION_BASE_URI + src.substring(DOC_BASE_URI.length);
+ imgElement.src = src;
}
};
diff --git a/res/raw/template_conversation_lower.html b/res/raw/template_conversation_lower.html
index 9f69deb..7523981 100644
--- a/res/raw/template_conversation_lower.html
+++ b/res/raw/template_conversation_lower.html
@@ -2,7 +2,8 @@
<script type="text/javascript">
var MSG_HIDE_ELIDED = '%s';
var MSG_SHOW_ELIDED = '%s';
- var ACCOUNT_URI = '%s';
+ var DOC_BASE_URI = '%s';
+ var CONVERSATION_BASE_URI = '%s';
var VIEW_WIDTH = %d;
var WIDE_VIEWPORT_WIDTH = %d;
</script>
diff --git a/src/com/android/mail/browse/ConversationItemViewCoordinates.java b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
index 95cdfaf..0a35b88 100644
--- a/src/com/android/mail/browse/ConversationItemViewCoordinates.java
+++ b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
@@ -439,7 +439,7 @@
public static int getMinHeight(Context context, ViewMode viewMode) {
int mode = ConversationItemViewCoordinates.getMode(context, viewMode);
return context.getResources().getDimensionPixelSize(
- mode == WIDE_MODE ? R.dimen.conversation_item_height
- : R.dimen.conversation_item_height_wide);
+ mode == WIDE_MODE ?
+ R.dimen.conversation_item_height_wide : R.dimen.conversation_item_height);
}
}
diff --git a/src/com/android/mail/browse/ConversationItemViewModel.java b/src/com/android/mail/browse/ConversationItemViewModel.java
index 6508ea4..267900e 100644
--- a/src/com/android/mail/browse/ConversationItemViewModel.java
+++ b/src/com/android/mail/browse/ConversationItemViewModel.java
@@ -234,8 +234,7 @@
* Returns the layout hashcode to compare to see if the layout state has changed.
*/
private int getLayoutHashCode() {
- return mDataHashCode ^ viewWidth ^ standardScaledDimen
- ^ Boolean.valueOf(checkboxVisible).hashCode();
+ return Objects.hashCode(mDataHashCode, viewWidth, standardScaledDimen, checkboxVisible);
}
private Object getConvInfo() {
diff --git a/src/com/android/mail/compose/AttachmentsView.java b/src/com/android/mail/compose/AttachmentsView.java
index b068cd3..c566214 100644
--- a/src/com/android/mail/compose/AttachmentsView.java
+++ b/src/com/android/mail/compose/AttachmentsView.java
@@ -15,6 +15,8 @@
*/
package com.android.mail.compose;
+import android.animation.LayoutTransition;
+import android.animation.LayoutTransition.TransitionListener;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
@@ -52,7 +54,7 @@
/*
* View for displaying attachments in the compose screen.
*/
-class AttachmentsView extends LinearLayout implements OnClickListener {
+class AttachmentsView extends LinearLayout implements OnClickListener, TransitionListener {
private static final String LOG_TAG = LogTag.getLogTag();
private final Resources mResources;
@@ -64,8 +66,10 @@
private GridLayout mCollapseLayout;
private TextView mCollapseText;
private ImageView mCollapseCaret;
+ private LayoutTransition mComposeLayoutTransition;
private boolean mIsExpanded;
+ private long mChangingDelay;
public AttachmentsView(Context context) {
this(context, null);
@@ -96,9 +100,13 @@
case R.id.attachment_collapse_view:
if (mIsExpanded) {
collapseView();
+ mComposeLayoutTransition.setStartDelay(
+ LayoutTransition.CHANGING, mChangingDelay);
} else {
expandView();
+ mComposeLayoutTransition.setStartDelay(LayoutTransition.CHANGING, 0l);
}
+ mComposeLayoutTransition.enableTransitionType(LayoutTransition.CHANGING);
break;
}
}
@@ -197,6 +205,14 @@
@VisibleForTesting
protected void deleteAttachment(final View attachmentView,
final Attachment attachment) {
+ mComposeLayoutTransition.enableTransitionType(LayoutTransition.CHANGING);
+ mComposeLayoutTransition.setStartDelay(
+ LayoutTransition.CHANGING, mChangingDelay);
+ final LayoutTransition transition = getLayoutTransition();
+ transition.enableTransitionType(LayoutTransition.CHANGING);
+ transition.setStartDelay(LayoutTransition.CHANGING, mChangingDelay);
+ transition.addTransitionListener(this);
+
mAttachments.remove(attachment);
((ViewGroup) attachmentView.getParent()).removeView(attachmentView);
if (mChangeListener != null) {
@@ -210,6 +226,26 @@
}
}
+ public void setComposeLayoutTransition(LayoutTransition transition) {
+ mComposeLayoutTransition = transition;
+ mComposeLayoutTransition.addTransitionListener(this);
+ mChangingDelay =
+ mComposeLayoutTransition.getDuration(LayoutTransition.DISAPPEARING);
+ }
+
+ @Override
+ public void startTransition(LayoutTransition transition, ViewGroup container, View view,
+ int transitionType) {
+ /* Do nothing */
+ }
+
+ @Override
+ public void endTransition(LayoutTransition transition, ViewGroup container, View view,
+ int transitionType) {
+ transition.disableTransitionType(LayoutTransition.CHANGING);
+ transition.setStartDelay(LayoutTransition.CHANGING, 0l);
+ }
+
/**
* Get all attachments being managed by this view.
* @return attachments.
diff --git a/src/com/android/mail/compose/ComposeActivity.java b/src/com/android/mail/compose/ComposeActivity.java
index addc645..766aa6f 100644
--- a/src/com/android/mail/compose/ComposeActivity.java
+++ b/src/com/android/mail/compose/ComposeActivity.java
@@ -799,18 +799,15 @@
}
private void findViews() {
- LayoutTransition transition =
- ((ViewGroup) findViewById(R.id.content)).getLayoutTransition();
- transition.enableTransitionType(LayoutTransition.CHANGING);
- long delay = transition.getDuration(LayoutTransition.DISAPPEARING);
- transition.setStartDelay(LayoutTransition.CHANGING, delay);
-
mCcBccButton = (Button) findViewById(R.id.add_cc_bcc);
if (mCcBccButton != null) {
mCcBccButton.setOnClickListener(this);
}
mCcBccView = (CcBccView) findViewById(R.id.cc_bcc_wrapper);
mAttachmentsView = (AttachmentsView)findViewById(R.id.attachments);
+ LayoutTransition transition =
+ ((ViewGroup) findViewById(R.id.content)).getLayoutTransition();
+ mAttachmentsView.setComposeLayoutTransition(transition);
mAttachmentsButton = (ImageView) findViewById(R.id.add_attachment);
if (mAttachmentsButton != null) {
mAttachmentsButton.setOnClickListener(this);
diff --git a/src/com/android/mail/providers/Conversation.java b/src/com/android/mail/providers/Conversation.java
index 8a06a48..ccb36ea 100644
--- a/src/com/android/mail/providers/Conversation.java
+++ b/src/com/android/mail/providers/Conversation.java
@@ -130,10 +130,14 @@
*/
public ConversationInfo conversationInfo;
/**
- * @see UIProvider.ConversationColumns#CONVERSATION_INFO
+ * @see UIProvider.ConversationColumns#CONVERSATION_BASE_URI
*/
public Uri conversationBaseUri;
/**
+ * @see UIProvider.ConversationColumns#CONVERSATION_COOKIE
+ */
+ public String conversationCookie;
+ /**
* @see UIProvider.ConversationColumns#REMOTE
*/
public boolean isRemote;
@@ -189,6 +193,7 @@
dest.writeParcelable(accountUri, 0);
dest.writeString(ConversationInfo.toString(conversationInfo));
dest.writeParcelable(conversationBaseUri, 0);
+ dest.writeString(conversationCookie);
dest.writeInt(isRemote ? 1 : 0);
}
@@ -219,6 +224,7 @@
localDeleteOnUpdate = false;
conversationInfo = ConversationInfo.fromString(in.readString());
conversationBaseUri = in.readParcelable(null);
+ conversationCookie = in.readString();
isRemote = in.readInt() != 0;
}
@@ -283,6 +289,7 @@
cursor.getString(UIProvider.CONVERSATION_BASE_URI_COLUMN);
conversationBaseUri = !TextUtils.isEmpty(conversationBase) ?
Uri.parse(conversationBase) : null;
+ conversationCookie = cursor.getString(UIProvider.CONVERSATION_COOKIE_COLUMN);
if (conversationInfo == null) {
snippet = cursor.getString(UIProvider.CONVERSATION_SNIPPET_COLUMN);
senders = emptyIfNull(cursor.getString(UIProvider.CONVERSATION_SENDER_INFO_COLUMN));
@@ -301,7 +308,7 @@
int numMessages, int numDrafts, int sendingState, int priority, boolean read,
boolean starred, String rawFolders, int convFlags, int personalLevel, boolean spam,
boolean phishing, boolean muted, Uri accountUri, ConversationInfo conversationInfo,
- Uri conversationBase, boolean isRemote) {
+ Uri conversationBase, String conversationCookie, boolean isRemote) {
final Conversation conversation = new Conversation();
@@ -329,6 +336,7 @@
conversation.accountUri = accountUri;
conversation.conversationInfo = conversationInfo;
conversation.conversationBaseUri = conversationBase;
+ conversation.conversationCookie = conversationCookie;
conversation.isRemote = isRemote;
return conversation;
}
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index 630e663..af2db9e 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -770,6 +770,7 @@
ConversationColumns.ACCOUNT_URI,
ConversationColumns.SENDER_INFO,
ConversationColumns.CONVERSATION_BASE_URI,
+ ConversationColumns.CONVERSATION_COOKIE,
ConversationColumns.REMOTE
};
@@ -799,7 +800,8 @@
public static final int CONVERSATION_ACCOUNT_URI_COLUMN = 21;
public static final int CONVERSATION_SENDER_INFO_COLUMN = 22;
public static final int CONVERSATION_BASE_URI_COLUMN = 23;
- public static final int CONVERSATION_REMOTE_COLUMN = 24;
+ public static final int CONVERSATION_COOKIE_COLUMN = 24;
+ public static final int CONVERSATION_REMOTE_COLUMN = 25;
public static final class ConversationSendingState {
public static final int OTHER = 0;
@@ -961,12 +963,17 @@
* {@link Conversation} object.
*/
public static final String VIEWED = "viewed";
-
/**
* This String column contains the base uri for this conversation. This uri can be used
* when handling relative urls in the message content
*/
public static final String CONVERSATION_BASE_URI = "conversationBaseUri";
+ /**
+ * This String column contains the cookie needed for accessing inline content. The cookie
+ * specified here will be set on the uri specified in the {@link CONVERSATION_BASE_URI}
+ * column.
+ */
+ public static final String CONVERSATION_COOKIE = "conversationCookie";
private ConversationColumns() {
}
diff --git a/src/com/android/mail/ui/AnimatedAdapter.java b/src/com/android/mail/ui/AnimatedAdapter.java
index 1728ed7..d33be03 100644
--- a/src/com/android/mail/ui/AnimatedAdapter.java
+++ b/src/com/android/mail/ui/AnimatedAdapter.java
@@ -271,19 +271,10 @@
return v;
}
}
- // TODO: do this in the swipe helper?
- // If this view gets recycled, we need to reset things set by the
- // animation.
- if (convertView != null) {
- if (convertView.getAlpha() < 1) {
- convertView.setAlpha(1);
- }
- if (convertView.getTranslationX() != 0) {
- convertView.setTranslationX(0);
- }
- if (convertView instanceof SwipeableConversationItemView) {
- ((SwipeableConversationItemView)convertView).reset();
- }
+ if (!(convertView instanceof SwipeableConversationItemView)) {
+ convertView = null;
+ } else if (convertView != null) {
+ ((SwipeableConversationItemView) convertView).reset();
}
View v = super.getView(position, convertView, parent);
if (v == null) {
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index 87b6826..d656d08 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -29,6 +29,7 @@
import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Browser;
@@ -40,6 +41,8 @@
import android.view.View;
import android.view.ViewGroup;
import android.webkit.ConsoleMessage;
+import android.webkit.CookieManager;
+import android.webkit.CookieSyncManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
@@ -240,6 +243,13 @@
mWebView.setOnCreateContextMenuListener(new WebViewContextMenu(activity));
showConversation();
+
+ if (mConversation.conversationBaseUri != null &&
+ !TextUtils.isEmpty(mConversation.conversationCookie)) {
+ // Set the cookie for this base url
+ new SetCookieTask(mConversation.conversationBaseUri.toString(),
+ mConversation.conversationCookie).execute();
+ }
}
@Override
@@ -251,10 +261,9 @@
mAccount = args.getParcelable(ARG_ACCOUNT);
mConversation = args.getParcelable(ARG_CONVERSATION);
mFolder = args.getParcelable(ARG_FOLDER);
- // If the provider has specified a base uri to be used, use that one.
- mBaseUri = mConversation.conversationBaseUri != null ?
- mConversation.conversationBaseUri.toString() :
- "x-thread://" + mAccount.name + "/" + mConversation.id;
+ // Since the uri specified in the conversation base uri may not be unique, we specify a
+ // base uri that us guaranteed to be unique for this conversation.
+ mBaseUri = "x-thread://" + mAccount.name + "/" + mConversation.id;
// Not really, we just want to get a crack to store a reference to the change_folder item
setHasOptionsMenu(true);
@@ -600,7 +609,11 @@
mWebView.getSettings().setBlockNetworkImage(!allowNetworkImages);
- return mTemplates.endConversation(mBaseUri, 320, mWebView.getViewportWidth());
+ // If the conversation has specified a base uri, use it here, use mBaseUri
+ final String conversationBaseUri = mConversation.conversationBaseUri != null ?
+ mConversation.conversationBaseUri.toString() : mBaseUri;
+ return mTemplates.endConversation(mBaseUri, conversationBaseUri, 320,
+ mWebView.getViewportWidth());
}
private void renderSuperCollapsedBlock(int start, int end) {
@@ -1172,4 +1185,22 @@
return mAccount.settings;
}
+ private class SetCookieTask extends AsyncTask<Void, Void, Void> {
+ final String mUri;
+ final String mCookie;
+
+ SetCookieTask(String uri, String cookie) {
+ mUri = uri;
+ mCookie = cookie;
+ }
+
+ @Override
+ public Void doInBackground(Void... args) {
+ final CookieSyncManager csm =
+ CookieSyncManager.createInstance(mContext);
+ CookieManager.getInstance().setCookie(mUri, mCookie);
+ csm.sync();
+ return null;
+ }
+ }
}
diff --git a/src/com/android/mail/ui/HtmlConversationTemplates.java b/src/com/android/mail/ui/HtmlConversationTemplates.java
index 002bed4..16b26b7 100644
--- a/src/com/android/mail/ui/HtmlConversationTemplates.java
+++ b/src/com/android/mail/ui/HtmlConversationTemplates.java
@@ -187,13 +187,15 @@
mInProgress = true;
}
- public String endConversation(String baseUri, int viewWidth, int viewportWidth) {
+ public String endConversation(String docBaseUri, String conversationBaseUri, int viewWidth,
+ int viewportWidth) {
if (!mInProgress) {
throw new IllegalStateException("must call startConversation first");
}
append(sConversationLower, mContext.getString(R.string.hide_elided),
- mContext.getString(R.string.show_elided), baseUri, viewWidth, viewportWidth);
+ mContext.getString(R.string.show_elided), docBaseUri, conversationBaseUri,
+ viewWidth, viewportWidth);
mInProgress = false;
diff --git a/src/com/android/mail/ui/SwipeableListView.java b/src/com/android/mail/ui/SwipeableListView.java
index 233726c..985f38c 100644
--- a/src/com/android/mail/ui/SwipeableListView.java
+++ b/src/com/android/mail/ui/SwipeableListView.java
@@ -17,8 +17,6 @@
package com.android.mail.ui;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.res.Configuration;
import android.net.Uri;
@@ -320,7 +318,8 @@
// We made it up to the window without find this list view
return INVALID_POSITION;
} catch (NullPointerException e) {
- LogUtils.e(LOG_TAG, e, "WHAT HAS NO PARENT " + (v != null ? v.getClass() : null));
+ LogUtils.e(LOG_TAG, e, "WHAT HAS NO PARENT "
+ + (listItem != null ? listItem.getClass() : null));
return INVALID_POSITION;
}
return super.getPositionForView(view);
@@ -329,26 +328,23 @@
/**
* Archive items using the swipe away animation before shrinking them away.
*/
- public void destroyItems(ArrayList<ConversationItemView> views,
+ public void destroyItems(final ArrayList<ConversationItemView> views,
final DestructiveAction listener) {
if (views == null || views.size() == 0) {
return;
}
+ // Need to find the items in the LIST!
final ArrayList<Conversation> conversations = new ArrayList<Conversation>();
for (ConversationItemView view : views) {
Conversation conv = view.getConversation();
- conv.position = view.getParent() != null ? getPositionForView(view) : -1;
+ conv.position = conv.position == -1 && view.getParent() != null ?
+ getPositionForView(view) : conv.position;
conversations.add(conv);
}
- mSwipeHelper.dismissChildren(views.get(0), views, new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- AnimatedAdapter adapter = getAnimatedAdapter();
- if (adapter != null) {
- adapter.delete(conversations, listener);
- }
- }
- });
+ AnimatedAdapter adapter = getAnimatedAdapter();
+ if (adapter != null) {
+ adapter.delete(conversations, listener);
+ }
}
private AnimatedAdapter getAnimatedAdapter() {