Conversation UI Visual Refresh: border fixes.
Borders now expand and collapsed based upon the state
of the messages above and below them. Also fixed a bug
where replying to a message added an additional border.
Change-Id: Ia90caf4ea595767a90213fe33b29e1bd75c0aca0
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index e0a45d6..b298e69 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -645,6 +645,9 @@
ConversationMessage prevCollapsedMsg = null;
boolean prevSafeForImages = false;
+ // Store the previous expanded state so that the border between
+ // the previous and current message can be properly initialized.
+ int previousExpandedState = ExpansionState.NONE;
while (messageCursor.moveToPosition(++pos)) {
final ConversationMessage msg = messageCursor.getMessage();
@@ -693,15 +696,18 @@
// This line puts the from address in the address cache so that
// we get the sender image for it if it's in a super-collapsed block.
getAddress(msg.getFrom());
+ previousExpandedState = expandedState;
continue;
}
// resolve any deferred decisions on previous collapsed items
if (collapsedStart >= 0) {
if (pos - collapsedStart == 1) {
- // special-case for a single collapsed message: no need to super-collapse it
- renderMessage(prevCollapsedMsg, false /* expanded */,
- prevSafeForImages, true /* firstBorder */);
+ // Special-case for a single collapsed message: no need to super-collapse it.
+ // Since it is super-collapsed, there is no previous message to be
+ // collapsed and the border above it is the first border.
+ renderMessage(prevCollapsedMsg, false /* previousCollapsed */,
+ false /* expanded */, prevSafeForImages, true /* firstBorder */);
} else {
renderSuperCollapsedBlock(collapsedStart, pos - 1);
}
@@ -709,15 +715,19 @@
collapsedStart = -1;
}
- renderMessage(msg, ExpansionState.isExpanded(expandedState), safeForImages,
+ renderMessage(msg, ExpansionState.isCollapsed(previousExpandedState),
+ ExpansionState.isExpanded(expandedState), safeForImages,
pos == 0 /* firstBorder */);
+
+ previousExpandedState = expandedState;
}
mWebView.getSettings().setBlockNetworkImage(!allowNetworkImages);
final boolean applyTransforms = shouldApplyTransforms();
- renderBorder(true /* contiguous */, false /* firstBorder */);
+ renderBorder(true /* contiguous */, true /* expanded */,
+ false /* firstBorder */, true /* lastBorder */);
// If the conversation has specified a base uri, use it here, otherwise use mBaseUri
return mTemplates.endConversation(mBaseUri, mConversation.getBaseUri(mBaseUri), 320,
@@ -726,27 +736,33 @@
}
private void renderSuperCollapsedBlock(int start, int end) {
- renderBorder(true /* contiguous */, true /* firstBorder */);
+ renderBorder(true /* contiguous */, true /* expanded */,
+ true /* firstBorder */, false /* lastBorder */);
final int blockPos = mAdapter.addSuperCollapsedBlock(start, end);
final int blockPx = measureOverlayHeight(blockPos);
mTemplates.appendSuperCollapsedHtml(start, mWebView.screenPxToWebPx(blockPx));
}
- protected void renderBorder(boolean contiguous, boolean firstBorder) {
- final int blockPos = mAdapter.addBorder(contiguous, firstBorder);
+ protected void renderBorder(
+ boolean contiguous, boolean expanded, boolean firstBorder, boolean lastBorder) {
+ final int blockPos = mAdapter.addBorder(contiguous, expanded, firstBorder, lastBorder);
final int blockPx = measureOverlayHeight(blockPos);
mTemplates.appendBorder(mWebView.screenPxToWebPx(blockPx));
}
- private void renderMessage(ConversationMessage msg, boolean expanded,
- boolean safeForImages, boolean firstBorder) {
- renderMessage(msg, expanded, safeForImages, true /* renderBorder */, firstBorder);
+ private void renderMessage(ConversationMessage msg, boolean previousCollapsed,
+ boolean expanded, boolean safeForImages, boolean firstBorder) {
+ renderMessage(msg, previousCollapsed, expanded, safeForImages,
+ true /* renderBorder */, firstBorder);
}
- private void renderMessage(ConversationMessage msg, boolean expanded,
- boolean safeForImages, boolean renderBorder, boolean firstBorder) {
+ private void renderMessage(ConversationMessage msg, boolean previousCollapsed,
+ boolean expanded, boolean safeForImages, boolean renderBorder, boolean firstBorder) {
if (renderBorder) {
- renderBorder(true /* contiguous */, firstBorder);
+ // The border should be collapsed only if both the current
+ // and previous messages are collapsed.
+ renderBorder(true /* contiguous */, !previousCollapsed || expanded,
+ firstBorder, false /* lastBorder */);
}
final int headerPos = mAdapter.addMessageHeader(msg, expanded,
@@ -785,8 +801,10 @@
borderPx = 0;
first = false;
} else {
- final BorderItem border =
- mAdapter.newBorderItem(true /* contiguous */, false /* firstBorder */);
+ // When replacing the super-collapsed block,
+ // the border is always collapsed between messages.
+ final BorderItem border = mAdapter.newBorderItem(
+ true /* contiguous */, false /* expanded */);
borderPx = measureOverlayHeight(border);
replacements.add(border);
mTemplates.appendBorder(mWebView.screenPxToWebPx(borderPx));
@@ -881,15 +899,19 @@
}
@Override
- public void setMessageExpanded(MessageHeaderItem item, int newSpacerHeightPx) {
+ public void setMessageExpanded(MessageHeaderItem item, int newSpacerHeightPx,
+ int topBorderHeight, int bottomBorderHeight) {
mConversationContainer.invalidateSpacerGeometry();
// show/hide the HTML message body and update the spacer height
final int h = mWebView.screenPxToWebPx(newSpacerHeightPx);
+ final int topHeight = mWebView.screenPxToWebPx(topBorderHeight);
+ final int bottomHeight = mWebView.screenPxToWebPx(bottomBorderHeight);
LogUtils.i(LAYOUT_TAG, "setting HTML spacer expanded=%s h=%dwebPx (%dscreenPx)",
item.isExpanded(), h, newSpacerHeightPx);
- mWebView.loadUrl(String.format("javascript:setMessageBodyVisible('%s', %s, %s);",
- mTemplates.getMessageDomId(item.getMessage()), item.isExpanded(), h));
+ mWebView.loadUrl(String.format("javascript:setMessageBodyVisible('%s', %s, %s, %s, %s);",
+ mTemplates.getMessageDomId(item.getMessage()), item.isExpanded(),
+ h, topHeight, bottomHeight));
mViewState.setExpansionState(item.getMessage(),
item.isExpanded() ? ExpansionState.EXPANDED : ExpansionState.COLLAPSED);
@@ -1411,12 +1433,21 @@
}
private void processNewOutgoingMessage(ConversationMessage msg) {
+ // make the last border no longer be the border
+ ((BorderItem) mAdapter.getItem(mAdapter.getCount() - 1)).setIsLastBorder(false);
+
mTemplates.reset();
// this method will add some items to mAdapter, but we deliberately want to avoid notifying
// adapter listeners (i.e. ConversationContainer) until onWebContentGeometryChange is next
// called, to prevent N+1 headers rendering with N message bodies.
- renderMessage(msg, true /* expanded */, msg.alwaysShowImages, false /* renderBorder */);
- renderBorder(true /* contiguous */, false /* firstBorder */);
+
+ // We can just call previousCollapsed false here since the border
+ // above the message we're about to render should always show
+ // (which it also will since the message being render is expanded).
+ renderMessage(msg, false /* previousCollapsed */, true /* expanded */,
+ msg.alwaysShowImages, false /* renderBorder */, false /* firstBorder */);
+ renderBorder(true /* contiguous */, true /* expanded */,
+ false /* firstBorder */, true /* lastBorder */);
mTempBodiesHtml = mTemplates.emit();
mViewState.setExpansionState(msg, ExpansionState.EXPANDED);