Merge "If conversation list cursor is not loaded, defer mark unread until it's loaded." into jb-ub-mail-ur8
diff --git a/assets/script.js b/assets/script.js
index 6ea24e8..37c266e 100644
--- a/assets/script.js
+++ b/assets/script.js
@@ -487,23 +487,29 @@
msgDivTop = getTotalOffset(msgBodyDiv).top;
- scaledOriginX = focusX;// / initialScale;
- scaledOriginY = (focusY - msgDivTop);// / initialScale;
+ // TODO: correct only for no initial translation
+ // FIXME: wrong for initialScale > 1.0
+ scaledOriginX = focusX / initialScale;
+ scaledOriginY = (focusY - msgDivTop) / initialScale;
- translateX = scaledOriginX * (initialScale - 1.0) / initialScale;
- translateY = scaledOriginY * (initialScale - 1.0) / initialScale;
+ // TODO: is this still needed?
+ translateX = 0;
+ translateY = 0;
gScaleInfo = {
div: msgBodyDiv,
- divTop: msgDivTop,
initialScale: initialScale,
- initialX: focusX,
- initialY: focusY,
+ initialScreenX: screenX,
+ initialScreenY: screenY,
+ originX: scaledOriginX,
+ originY: scaledOriginY,
translateX: translateX,
translateY: translateY,
initialH: getCachedValue(msgBodyDiv, "offsetHeight", "data-initial-height"),
minScale: Math.min(document.body.offsetWidth / msgBodyDiv.scrollWidth, 1.0),
- currScale: initialScale
+ currScale: initialScale,
+ currTranslateX: 0,
+ currTranslateY: 0
};
origin = scaledOriginX + "px " + scaledOriginY + "px";
@@ -530,19 +536,31 @@
scale = gScaleInfo.currScale;
msgBodyDiv.style.webkitTransformOrigin = "0 0";
// clear any translate
- msgBodyDiv.style.webkitTransform = "scale3d(" + scale + "," + scale + ",1)";
// switching to a 2D transform here re-renders the fonts more clearly, but introduces
// texture upload lag to any subsequent scale operation
- //msgBodyDiv.style.webkitTransform = "scale(" + gScaleInfo.currScale + ")";
+ // TODO: conditionalize this based on device GPU performance and/or body size/complexity?
+ if (true) {
+ msgBodyDiv.style.webkitTransform = "scale(" + gScaleInfo.currScale + ")";
+ } else {
+ msgBodyDiv.style.webkitTransform = "scale3d(" + scale + "," + scale + ",1)";
+ }
h = gScaleInfo.initialH * scale;
// console.log("onScaleEnd set h=" + h);
msgBodyDiv.style.height = h + "px";
+
+ // Use saved translateX/Y rather than calculating from screenX/Y because screenX/Y values
+ // from onScaleEnd only track focus of remaining pointers, which is not useful and leads
+ // to a perceived jump.
+ var deltaScrollX = (scale - 1) * gScaleInfo.originX - gScaleInfo.currTranslateX;
+ var deltaScrollY = (scale - 1) * gScaleInfo.originY - gScaleInfo.currTranslateY;
+// console.log("JS adjusting scroll by x/y=" + deltaScrollX + "/" + deltaScrollY);
+ window.scrollBy(deltaScrollX, deltaScrollY);
+
msgBodyDiv.classList.remove("zooming-focused");
msgBodyDiv.setAttribute("data-initial-scale", scale);
}
function onScale(relativeScale, screenX, screenY) {
- var focusX, focusY;
var scale;
var translateX, translateY;
var transform;
@@ -550,21 +568,22 @@
if (!gScaleInfo) {
return;
}
- focusX = screenX + document.body.scrollLeft;
- focusY = screenY + document.body.scrollTop;
scale = Math.max(gScaleInfo.initialScale * relativeScale, gScaleInfo.minScale);
if (scale > 4.0) {
scale = 4.0;
}
+ translateX = screenX - gScaleInfo.initialScreenX;
+ translateY = screenY - gScaleInfo.initialScreenY;
+ // TODO: clamp translation to prevent going beyond body edges
gScaleInfo.currScale = scale;
- translateX = focusX - gScaleInfo.initialX;
- translateY = focusY - gScaleInfo.initialY;
+ gScaleInfo.currTranslateX = translateX;
+ gScaleInfo.currTranslateY = translateY;
transform = "translate3d(" + translateX + "px," + translateY + "px,0) scale3d("
+ scale + "," + scale + ",1) translate3d(" + gScaleInfo.translateX + "px,"
+ gScaleInfo.translateY + "px,0)";
gScaleInfo.div.style.webkitTransform = transform;
-// console.log("JS got scale=" + relativeScale + " x/y=" + screenX + "/" + screenY
+// console.log("JS got scale=" + scale + " x/y=" + screenX + "/" + screenY
// + " transform='" + transform + "'");
}
diff --git a/res/drawable-hdpi/ic_contact_picture.png b/res/drawable-hdpi/ic_contact_picture.png
deleted file mode 100644
index 2eef7b5..0000000
--- a/res/drawable-hdpi/ic_contact_picture.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_contact_picture_180_holo_dark.png b/res/drawable-hdpi/ic_contact_picture_180_holo_dark.png
deleted file mode 100644
index a17da61..0000000
--- a/res/drawable-hdpi/ic_contact_picture_180_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_contact_picture_180_holo_light.png b/res/drawable-hdpi/ic_contact_picture_180_holo_light.png
deleted file mode 100644
index 38e4c30..0000000
--- a/res/drawable-hdpi/ic_contact_picture_180_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_contact_picture_holo_dark.png b/res/drawable-hdpi/ic_contact_picture_holo_dark.png
deleted file mode 100644
index 314fa00..0000000
--- a/res/drawable-hdpi/ic_contact_picture_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_contact_picture.png b/res/drawable-mdpi/ic_contact_picture.png
deleted file mode 100644
index 6c7cb61..0000000
--- a/res/drawable-mdpi/ic_contact_picture.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_contact_picture_180_holo_dark.png b/res/drawable-mdpi/ic_contact_picture_180_holo_dark.png
deleted file mode 100644
index acba333..0000000
--- a/res/drawable-mdpi/ic_contact_picture_180_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_contact_picture_180_holo_light.png b/res/drawable-mdpi/ic_contact_picture_180_holo_light.png
deleted file mode 100644
index 0b52683..0000000
--- a/res/drawable-mdpi/ic_contact_picture_180_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_contact_picture_holo_dark.png b/res/drawable-mdpi/ic_contact_picture_holo_dark.png
deleted file mode 100644
index 6876777..0000000
--- a/res/drawable-mdpi/ic_contact_picture_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_contact_picture.png b/res/drawable-xhdpi/ic_contact_picture.png
deleted file mode 100644
index 1a2bfde..0000000
--- a/res/drawable-xhdpi/ic_contact_picture.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_contact_picture_180_holo_dark.png b/res/drawable-xhdpi/ic_contact_picture_180_holo_dark.png
deleted file mode 100644
index c4c001e..0000000
--- a/res/drawable-xhdpi/ic_contact_picture_180_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_contact_picture_180_holo_light.png b/res/drawable-xhdpi/ic_contact_picture_180_holo_light.png
deleted file mode 100644
index f6fd172..0000000
--- a/res/drawable-xhdpi/ic_contact_picture_180_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_contact_picture_holo_dark.png b/res/drawable-xhdpi/ic_contact_picture_holo_dark.png
deleted file mode 100644
index ddf797f..0000000
--- a/res/drawable-xhdpi/ic_contact_picture_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 3425332..58c6af5 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 5736f1f..6589f8d 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 142e90a..211d2c6 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 25c2f60..2aaa2ee 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index f65f926..038a698 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index bac23fe..118f9f4 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 266f150..e3a0d99 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 441a84e..82d330d 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index dc6b6d0..d9fc3f8 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -159,7 +159,7 @@
</plurals>
<string name="sending" msgid="8214361929125649771">"Senden..."</string>
<string name="send_failed" msgid="750908595144529579">"Nicht gesendet"</string>
- <string name="me" msgid="6480762904022198669">"Ich"</string>
+ <string name="me" msgid="6480762904022198669">"Mich"</string>
<string name="show_all_folders" msgid="3281420732307737553">"Alle Ordner anzeigen"</string>
<plurals name="confirm_delete_conversation">
<item quantity="one" msgid="3731948757247905508">"Diese Konversation löschen?"</item>
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 1f98e7e..3e2dd3b 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index b4b66ee..0a416c8 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 7071556..fc31f4f 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index a619c6c..1fdb09b 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 0e1916d..f8ba65e 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 43c3476..003af78 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 9c4977d..775184f 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 2789824..b88157c 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index b1f777e..24e6488 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 497fe8d..e65bfc4 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index cfc7455..acfb7c9 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index e3522b0..68c0188 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 28b4929..ba83a3a 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index b0bab2e..e438719 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 11fb71c..41af5d4 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index db069ed..97700a4 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 896de33..caeea2a 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index ad9b18e..a4296fc 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index eddc95a..8e301ee 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 08fbb8f..c4723d6 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 7ee00c9..5e8b86a 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -246,7 +246,7 @@
<string name="cc_heading" msgid="8116221732072085180">"Cc:"</string>
<string name="bcc_heading" msgid="5528824453033598299">"Bcc:"</string>
<string name="show_images" msgid="1875700481186331432">"Afbeeldingen weergeven"</string>
- <string name="always_show_images" msgid="5966408990164581801">"Foto\'s van deze afzender altijd tonen"</string>
+ <string name="always_show_images" msgid="5966408990164581801">"Afbeeldingen van deze afzender altijd tonen"</string>
<string name="always_show_images_toast" msgid="6218061921546973716">"Foto\'s van deze afzender worden automatisch weergegeven."</string>
<string name="address_display_format" msgid="3581303608028992576">"<xliff:g id="NAME">%1$s</xliff:g> <xliff:g id="EMAIL">%2$s</xliff:g>"</string>
<string name="address_display_format_with_via_domain" msgid="2316262813990842490">"<xliff:g id="NAME">%1$s</xliff:g> <xliff:g id="EMAIL">%2$s</xliff:g> via <xliff:g id="VIA_DOMAIN">%3$s</xliff:g>"</string>
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 6dafe30..3b0b285 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -360,4 +360,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index dc7d235..d83f8c6 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index c0469e4..e1dcc64 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 10d5526..c1edf37 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -567,4 +567,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index a959ef7..bda89e3 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index e2ae037..7f7b3ec 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 52ffa92..b69719e 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 3001253..461d4d9 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 63a6a75..d2b5296 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 263f05f..b5ac4fd 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 5dac64a..8146224 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-sw600dp/dimen.xml b/res/values-sw600dp/dimen.xml
index 61d6cb3..237bfc0 100644
--- a/res/values-sw600dp/dimen.xml
+++ b/res/values-sw600dp/dimen.xml
@@ -43,7 +43,6 @@
<dimen name="attachment_tile_min_size">180dp</dimen>
<dimen name="attachment_tile_max_size">254dp</dimen>
<dimen name="wait_padding">32dp</dimen>
- <dimen name="folders_left_padding">8dip</dimen>
<dimen name="compose_area_left_padding">80dip</dimen>
<dimen name="compose_area_right_padding">80dip</dimen>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 0741bf7..606c471 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 61bd70a..bcede38 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index fa0c3da..338065a 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index da4b0ee..5f1329b 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 9c9b45c..c16dd39 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index f9b38bb..3bee401 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 65c5129..da9776b 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index f46a126..14a6b1a 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -362,4 +362,5 @@
<string name="veiled_address" msgid="1209670815434513191"></string>
<string name="veiled_alternate_text" msgid="7370933826442034211"></string>
<string name="veiled_alternate_text_unknown_person" msgid="5132515097905273819"></string>
+ <string name="veiled_summary_unknown_person" msgid="4030928895738205054"></string>
</resources>
diff --git a/res/values/animation_constants.xml b/res/values/animation_constants.xml
index 6daab6f..09c53c5 100644
--- a/res/values/animation_constants.xml
+++ b/res/values/animation_constants.xml
@@ -38,5 +38,6 @@
<dimen name="min_swipe">10dip</dimen>
<dimen name="min_vert">10dip</dimen>
<dimen name="min_lock">20dip</dimen>
- <integer name="dismiss_all_leavebehinds_delay">350</integer>
+ <integer name="dismiss_all_leavebehinds_short_delay">175</integer>
+ <integer name="dismiss_all_leavebehinds_long_delay">350</integer>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 6b39b80..b615b17 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -77,4 +77,8 @@
<color name="animating_item_background_color">#7F0099cc</color>
<color name="notification_template_icon_low_bg">#0cffffff</color>
+
+ <color name="letter_tile_color">#d8d8d8</color>
+ <color name="letter_tile_font_color">#ffffff</color>
+ <color name="tile_divider_color">#ffffff</color>
</resources>
diff --git a/res/values/dimen.xml b/res/values/dimen.xml
index e06b669..7bbf99f 100644
--- a/res/values/dimen.xml
+++ b/res/values/dimen.xml
@@ -49,7 +49,7 @@
<dimen name="move_slop">4dip</dimen>
<dimen name="standard_scaled_dimen">100sp</dimen>
<dimen name="folder_cell_width">8dip</dimen>
- <dimen name="folders_left_padding">16dip</dimen>
+ <dimen name="folders_left_padding">4dip</dimen>
<dimen name="triangle_width">15dip</dimen>
<dimen name="conversation_page_gutter">16dp</dimen>
<dimen name="conversation_message_content_margin_side">16dp</dimen>
@@ -112,7 +112,8 @@
<dimen name="senders_textview_top_padding">-4dp</dimen>
<dimen name="senders_textview_height">30dp</dimen>
<integer name="chips_max_lines">2</integer>
- <dimen name="tile_letter_font_size">32sp</dimen>
- <dimen name="tile_letter_padding_bottom">12dp</dimen>
- <dimen name="tile_letter_padding_left">13dp</dimen>
+ <dimen name="tile_letter_font_size">33dp</dimen>
+ <dimen name="tile_letter_font_size_med">16dp</dimen>
+ <dimen name="tile_letter_font_size_small">16dp</dimen>
+ <dimen name="tile_divider_width">1dp</dimen>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 648f6fe..8b50f2f 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -550,6 +550,15 @@
<item name="android:textSize">@dimen/senders_font_size</item>
</style>
+ <style name="NotificationSendersUnreadTextAppearance">
+ <item name="android:textSize">@dimen/senders_font_size</item>
+ <item name="android:textStyle">bold</item>
+ </style>
+
+ <style name="NotificationSendersReadTextAppearance">
+ <item name="android:textSize">@dimen/senders_font_size</item>
+ </style>
+
<style name="MessageInfoUnreadTextAppearance">
<item name="android:textSize">@dimen/senders_font_size</item>
<item name="android:textColor">@color/message_info_text_color</item>
diff --git a/src/com/android/mail/browse/AttachmentActionHandler.java b/src/com/android/mail/browse/AttachmentActionHandler.java
index 5f89272..7c24dda 100644
--- a/src/com/android/mail/browse/AttachmentActionHandler.java
+++ b/src/com/android/mail/browse/AttachmentActionHandler.java
@@ -84,32 +84,25 @@
}
}
- public void showAndDownloadAttachments() {
- final List<Attachment> attachments = mView.getAttachments();
-
- for (final Attachment attachment : attachments) {
- if (!attachment.isPresentLocally()) {
- startDownloadingAttachment(attachment, AttachmentDestination.CACHE,
- UIProvider.AttachmentRendition.BEST);
- }
- }
-
- mView.viewAttachment();
- }
-
public void startDownloadingAttachment(int destination) {
- startDownloadingAttachment(destination, UIProvider.AttachmentRendition.BEST);
+ startDownloadingAttachment(destination, UIProvider.AttachmentRendition.BEST, 0, false);
}
- public void startDownloadingAttachment(int destination, int rendition) {
- startDownloadingAttachment(mAttachment, destination, rendition);
+ public void startDownloadingAttachment(
+ int destination, int rendition, int additionalPriority, boolean delayDownload) {
+ startDownloadingAttachment(
+ mAttachment, destination, rendition, additionalPriority, delayDownload);
}
- private void startDownloadingAttachment(Attachment attachment, int destination, int rendition) {
+ private void startDownloadingAttachment(
+ Attachment attachment, int destination, int rendition, int additionalPriority,
+ boolean delayDownload) {
final ContentValues params = new ContentValues(2);
params.put(AttachmentColumns.STATE, AttachmentState.DOWNLOADING);
params.put(AttachmentColumns.DESTINATION, destination);
params.put(AttachmentContentValueKeys.RENDITION, rendition);
+ params.put(AttachmentContentValueKeys.ADDITIONAL_PRIORITY, additionalPriority);
+ params.put(AttachmentContentValueKeys.DELAY_DOWNLOAD, delayDownload);
mCommandHandler.sendCommand(attachment.uri, params);
}
diff --git a/src/com/android/mail/browse/AttachmentViewInterface.java b/src/com/android/mail/browse/AttachmentViewInterface.java
index bf15ba6..d56bdf4 100644
--- a/src/com/android/mail/browse/AttachmentViewInterface.java
+++ b/src/com/android/mail/browse/AttachmentViewInterface.java
@@ -42,9 +42,4 @@
* Called in {@link AttachmentActionHandler#updateStatus}.
*/
public void onUpdateStatus();
-
- /**
- * Returns the list of attachments of which this view is a part.
- */
- public List<Attachment> getAttachments();
}
diff --git a/src/com/android/mail/browse/ConversationItemView.java b/src/com/android/mail/browse/ConversationItemView.java
index 3687606..71dceda 100644
--- a/src/com/android/mail/browse/ConversationItemView.java
+++ b/src/com/android/mail/browse/ConversationItemView.java
@@ -63,6 +63,7 @@
import com.android.mail.perf.Timer;
import com.android.mail.photomanager.ContactPhotoManager;
import com.android.mail.photomanager.LetterTileProvider;
+import com.android.mail.preferences.MailPrefs;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Folder;
import com.android.mail.providers.UIProvider;
@@ -73,6 +74,7 @@
import com.android.mail.ui.DividedImageCanvas;
import com.android.mail.ui.DividedImageCanvas.InvalidateCallback;
+import com.android.mail.ui.EllipsizedMultilineTextView;
import com.android.mail.ui.FolderDisplayer;
import com.android.mail.ui.SwipeableItemView;
import com.android.mail.ui.SwipeableListView;
@@ -171,10 +173,11 @@
private String mAccount;
private ControllableActivity mActivity;
private int mBackgroundOverride = -1;
- private TextView mSubjectTextView;
+ private EllipsizedMultilineTextView mSubjectTextView;
private TextView mSendersTextView;
private TextView mDateTextView;
private DividedImageCanvas mContactImagesHolder;
+ private boolean mConvListPhotosEnabled;
private static int sFoldersLeftPadding;
private static TextAppearanceSpan sDateTextAppearance;
private static TextAppearanceSpan sSubjectTextUnreadSpan;
@@ -403,9 +406,10 @@
sContactPhotoManager = ContactPhotoManager.createContactPhotoManager(context);
}
- mSubjectTextView = new TextView(mContext);
+ mSubjectTextView = new EllipsizedMultilineTextView(mContext);
mSubjectTextView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
+ mSubjectTextView.setMaxLines(2);
mSendersTextView = new TextView(mContext);
mSendersTextView.setMaxLines(1);
mSendersTextView.setEllipsize(TextUtils.TruncateAt.END);
@@ -453,6 +457,8 @@
mSelectedConversationSet = set;
mDisplayedFolder = folder;
mCheckboxesEnabled = !checkboxesDisabled;
+ mConvListPhotosEnabled = MailPrefs.get(activity.getActivityContext())
+ .areConvListPhotosEnabled();
mStarEnabled = folder != null && !folder.isTrash();
mSwipeEnabled = swipeEnabled;
mPriorityMarkersEnabled = priorityArrowEnabled;
@@ -513,7 +519,7 @@
ConversationItemViewCoordinates.refreshConversationHeights(mContext);
}
mCoordinates = ConversationItemViewCoordinates.forWidth(mContext, mViewWidth, mMode,
- mHeader.standardScaledDimen, mCheckboxesEnabled);
+ mHeader.standardScaledDimen, mConvListPhotosEnabled);
calculateTextsAndBitmaps();
calculateCoordinates();
@@ -567,7 +573,7 @@
if (mSelectedConversationSet != null) {
mChecked = mSelectedConversationSet.contains(mHeader.conversation);
}
- mHeader.checkboxVisible = mCheckboxesEnabled;
+ mHeader.checkboxVisible = mCheckboxesEnabled && !mConvListPhotosEnabled;
final boolean isUnread = mHeader.unread;
updateBackground(isUnread);
@@ -645,7 +651,7 @@
}
private void loadSenderImages() {
- if (!mCheckboxesEnabled && mHeader.displayableSenderEmails != null
+ if (mConvListPhotosEnabled && mHeader.displayableSenderEmails != null
&& mHeader.displayableSenderEmails.size() > 0) {
mContactImagesHolder.setDimensions(mCoordinates.contactImagesWidth,
mCoordinates.contactImagesHeight);
@@ -679,56 +685,57 @@
}
}
- private void createSubject(boolean isUnread, boolean activated) {
- String subject = filterTag(mHeader.conversation.subject);
+ private void createSubject(final boolean isUnread, boolean activated) {
+ final String subject = filterTag(mHeader.conversation.subject);
final String snippet = mHeader.conversation.getSnippet();
- int maxWidth = -1;
+
+ SpannableStringBuilder subjectText = new SpannableStringBuilder(
+ Conversation.getSubjectAndSnippetForDisplay(mContext, subject, snippet));
+ int subjectTextLength = Math.min(subjectText.length(), subject.length());
+ if (!TextUtils.isEmpty(subject)) {
+ subjectText.setSpan(TextAppearanceSpan.wrap(isUnread ?
+ sSubjectTextUnreadSpan : sSubjectTextReadSpan), 0, subjectTextLength,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ if (!TextUtils.isEmpty(snippet)) {
+ final int startOffset = subjectTextLength;
+ // Start after the end of the subject text; since the subject may be
+ // "" or null, this could start at the 0th character in the
+ // subectText string
+ if (startOffset < subjectText.length()) {
+ subjectText.setSpan(ForegroundColorSpan.wrap(isUnread ?
+ sSnippetTextUnreadSpan : sSnippetTextReadSpan), startOffset,
+ subjectText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ }
+ layoutSubject(subjectText);
+ }
+
+
+ private void layoutSubject(SpannableStringBuilder subjectText) {
+ int secondLineMaxWidth = EllipsizedMultilineTextView.ALL_AVAILABLE;
if (!ConversationItemViewCoordinates.isWideMode(mMode) && mCoordinates.showFolders
&& mHeader.folderDisplayer != null
&& mHeader.folderDisplayer.hasVisibleFolders()) {
- sPaint.setTextSize(mHeader.unread ? sSubjectTextUnreadSpan.getTextSize()
- : sSubjectTextReadSpan.getTextSize());
- sPaint.setTypeface(mHeader.unread ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT);
- maxWidth = (mSendersWidth * 2)
- - ConversationItemViewCoordinates.getFoldersWidth(mContext, mMode)
- - sFoldersLeftPadding;
+ secondLineMaxWidth = mCoordinates.subjectWidth
+ - Math.min(ConversationItemViewCoordinates.getFoldersWidth(mContext, mMode),
+ mHeader.folderDisplayer.measureFolders(mMode))
+ - sFoldersLeftPadding;
}
- SpannableStringBuilder subjectText = Conversation.getSubjectAndSnippetForDisplay(mContext,
- subject, snippet, maxWidth, sPaint);
- int subjectTextLength = Math.min(subjectText.length(), subject.length());
- if (!TextUtils.isEmpty(subject)) {
- subjectText.setSpan(TextAppearanceSpan.wrap(isUnread ?
- sSubjectTextUnreadSpan : sSubjectTextReadSpan), 0, subjectTextLength,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- if (!TextUtils.isEmpty(snippet)) {
- final int startOffset = subjectTextLength;
- // Start after the end of the subject text; since the subject may be
- // "" or null, this could start at the 0th character in the
- // subectText string
- if (startOffset < subjectText.length()) {
- subjectText.setSpan(ForegroundColorSpan.wrap(isUnread ?
- sSnippetTextUnreadSpan : sSnippetTextReadSpan), startOffset,
- subjectText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- }
- layoutSubject(subjectText);
- }
-
- private void layoutSubject(SpannableStringBuilder subjectText) {
- TextView subjectLayout = mSubjectTextView;
+ EllipsizedMultilineTextView subjectLayout = mSubjectTextView;
int subjectWidth = mCoordinates.subjectWidth;
- int subjectHeight = (int) (subjectLayout.getLineHeight() * 2 + sPaint.descent());
+ int subjectHeight = (int) (subjectLayout.getLineHeight() * 2 + subjectLayout.getPaint()
+ .descent());
if (isActivated() && showActivatedText()) {
subjectText.setSpan(sActivatedTextSpan, 0, subjectText.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
subjectText.removeSpan(sActivatedTextSpan);
}
- subjectLayout.setText(subjectText, TextView.BufferType.SPANNABLE);
subjectLayout.measure(MeasureSpec.makeMeasureSpec(subjectWidth, MeasureSpec.EXACTLY),
subjectHeight);
subjectLayout.layout(0, 0, subjectWidth, subjectHeight);
+ subjectLayout.setText(subjectText, secondLineMaxWidth);
}
/**
@@ -1020,13 +1027,13 @@
@Override
protected void onDraw(Canvas canvas) {
// Check mark.
- if (mHeader.checkboxVisible) {
- Bitmap checkmark = mChecked ? CHECKMARK_ON : CHECKMARK_OFF;
- canvas.drawBitmap(checkmark, mCoordinates.checkmarkX, mCoordinates.checkmarkY, sPaint);
- } else {
+ if (mConvListPhotosEnabled) {
canvas.save();
drawContactImages(canvas);
canvas.restore();
+ } else if (mHeader.checkboxVisible) {
+ Bitmap checkmark = mChecked ? CHECKMARK_ON : CHECKMARK_OFF;
+ canvas.drawBitmap(checkmark, mCoordinates.checkmarkX, mCoordinates.checkmarkY, sPaint);
}
// Personal Level.
@@ -1141,7 +1148,7 @@
private void drawSenders(Canvas canvas) {
int left;
- if (!mCheckboxesEnabled && mCoordinates.inlinePersonalLevel) {
+ if (mConvListPhotosEnabled && mCoordinates.inlinePersonalLevel) {
if (mCoordinates.showPersonalLevel && mHeader.personalLevelBitmap != null) {
left = mCoordinates.sendersX;
} else {
diff --git a/src/com/android/mail/browse/ConversationItemViewCoordinates.java b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
index aca8f43..dfce5d8 100644
--- a/src/com/android/mail/browse/ConversationItemViewCoordinates.java
+++ b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
@@ -168,8 +168,8 @@
/**
* Returns the layout id to be inflated in this mode.
*/
- private static int getLayoutId(int mode, boolean checkboxesEnabled) {
- if (checkboxesEnabled) {
+ private static int getLayoutId(int mode, boolean convListPhotosEnabled) {
+ if (!convListPhotosEnabled) {
switch (mode) {
case WIDE_MODE:
return R.layout.conversation_item_view_wide;
@@ -339,17 +339,17 @@
* the view width.
*/
public static ConversationItemViewCoordinates forWidth(Context context, int width, int mode,
- int standardScaledDimen, boolean checkboxesEnabled) {
+ int standardScaledDimen, boolean convListPhotosEnabled) {
ConversationItemViewCoordinates coordinates = sCache.get(Objects.hashCode(width, mode,
- checkboxesEnabled));
+ convListPhotosEnabled));
if (coordinates == null) {
coordinates = new ConversationItemViewCoordinates();
- sCache.put(Objects.hashCode(width, mode, checkboxesEnabled), coordinates);
+ sCache.put(Objects.hashCode(width, mode, convListPhotosEnabled), coordinates);
// Layout the appropriate view.
int height = getHeight(context, mode);
- View view = LayoutInflater.from(context).inflate(getLayoutId(mode, checkboxesEnabled),
- null);
+ View view = LayoutInflater.from(context).inflate(
+ getLayoutId(mode, convListPhotosEnabled), null);
int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
Resources res = context.getResources();
@@ -442,7 +442,7 @@
coordinates.paperclipY = getY(paperclip);
// Contact images view
- if (!checkboxesEnabled) {
+ if (convListPhotosEnabled) {
View contactImagesView = view.findViewById(R.id.contact_image);
if (contactImagesView != null) {
coordinates.contactImagesWidth = contactImagesView.getWidth();
diff --git a/src/com/android/mail/browse/ConversationWebView.java b/src/com/android/mail/browse/ConversationWebView.java
index f17ca3c..0f9d855 100644
--- a/src/com/android/mail/browse/ConversationWebView.java
+++ b/src/com/android/mail/browse/ConversationWebView.java
@@ -162,6 +162,7 @@
* POINTER_UP/POINTER_CANCEL.
*/
private boolean mHandlingTouch;
+ private boolean mIgnoringTouch;
private static final String LOG_TAG = LogTag.getLogTag();
@@ -263,14 +264,21 @@
case MotionEvent.ACTION_POINTER_DOWN:
LogUtils.d(LOG_TAG, "WebView disabling intercepts: POINTER_DOWN");
requestDisallowInterceptTouchEvent(true);
+ if (mScaleDetector != null) {
+ mIgnoringTouch = true;
+ final MotionEvent fakeCancel = MotionEvent.obtain(ev);
+ fakeCancel.setAction(MotionEvent.ACTION_CANCEL);
+ super.onTouchEvent(fakeCancel);
+ }
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
mHandlingTouch = false;
+ mIgnoringTouch = false;
break;
}
- final boolean handled = super.onTouchEvent(ev);
+ final boolean handled = mIgnoringTouch || super.onTouchEvent(ev);
if (mScaleDetector != null) {
mScaleDetector.onTouchEvent(ev);
diff --git a/src/com/android/mail/browse/MessageAttachmentBar.java b/src/com/android/mail/browse/MessageAttachmentBar.java
index da0e9bc..628d867 100644
--- a/src/com/android/mail/browse/MessageAttachmentBar.java
+++ b/src/com/android/mail/browse/MessageAttachmentBar.java
@@ -350,9 +350,4 @@
}
mSubTitle.setText(sb.toString());
}
-
- @Override
- public List<Attachment> getAttachments() {
- return null;
- }
}
diff --git a/src/com/android/mail/browse/MessageAttachmentTile.java b/src/com/android/mail/browse/MessageAttachmentTile.java
index d6f19c3..7d204bd 100644
--- a/src/com/android/mail/browse/MessageAttachmentTile.java
+++ b/src/com/android/mail/browse/MessageAttachmentTile.java
@@ -28,7 +28,7 @@
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
-import android.widget.ProgressBar;
+import android.view.ViewParent;
import com.android.ex.photo.Intents;
import com.android.ex.photo.Intents.PhotoViewIntentBuilder;
@@ -45,7 +45,8 @@
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
-import java.util.List;
+import java.util.Comparator;
+import java.util.PriorityQueue;
/**
* View for a single attachment in conversation view. Shows download status and allows launching
@@ -60,7 +61,6 @@
private View mTextContainer;
private final AttachmentActionHandler mActionHandler;
- private ProgressBar mProgress;
private static final String LOG_TAG = LogTag.getLogTag();
@@ -107,7 +107,6 @@
super.onFinishInflate();
mTextContainer = findViewById(R.id.attachment_tile_text_container);
- mProgress = (ProgressBar) findViewById(R.id.attachment_progress);
setOnClickListener(this);
}
@@ -118,11 +117,39 @@
}
private boolean onClick(int res, View v) {
- mActionHandler.showAndDownloadAttachments();
-
+ showAndDownloadAttachments();
return true;
}
+ private void showAndDownloadAttachments() {
+ AttachmentTileGrid tileGrid = ((AttachmentTileGrid) getParent());
+ int childCount = tileGrid.getChildCount();
+
+ PriorityQueue<MessageAttachmentTile> queue = new PriorityQueue<MessageAttachmentTile>(
+ childCount, new ViewIndexDistanceComparator(mPhotoIndex));
+ for (int i = 0; i < childCount; i++) {
+ MessageAttachmentTile tile = (MessageAttachmentTile) tileGrid.getChildAt(i);
+ queue.add(tile);
+ }
+
+ // we want our downloads to have higher priority than the highest background downloads
+ int maxAdditionalPriority = childCount;
+ for (int i = 0; i < childCount; i++) {
+ // higher priority tiles are returned first
+ MessageAttachmentTile tile = queue.remove();
+ tile.downloadAttachment(maxAdditionalPriority - i, i != 0);
+ }
+
+ viewAttachment();
+ }
+
+ public void downloadAttachment(int additionalPriority, boolean delayDownload) {
+ if (!mAttachment.isPresentLocally()) {
+ mActionHandler.startDownloadingAttachment(AttachmentDestination.CACHE,
+ UIProvider.AttachmentRendition.BEST, additionalPriority, delayDownload);
+ }
+ }
+
@Override
public void viewAttachment() {
if (ImageUtils.isImageMimeType(Utils.normalizeMimeType(mAttachment.contentType))) {
@@ -152,14 +179,7 @@
@Override
public void updateProgress(boolean showDeterminateProgress) {
- if (mAttachment.isDownloading()) {
- mProgress.setMax(mAttachment.size);
- mProgress.setProgress(mAttachment.downloadedSize);
- mProgress.setIndeterminate(!showDeterminateProgress);
- mProgress.setVisibility(VISIBLE);
- } else {
- mProgress.setVisibility(GONE);
- }
+ // do not show progress for image tiles
}
@Override
@@ -179,14 +199,45 @@
}
@Override
- public List<Attachment> getAttachments() {
- return ((AttachmentTileGrid) getParent()).getAttachments();
- }
-
- @Override
public void thumbnailLoadFailed() {
super.thumbnailLoadFailed();
mActionHandler.startDownloadingAttachment(
- AttachmentDestination.CACHE, AttachmentRendition.SIMPLE);
+ AttachmentDestination.CACHE, AttachmentRendition.SIMPLE, 0, false);
+ }
+
+ /**
+ * Given two child views, figure out whose index is closest to the specified
+ * index. (generated by markwei)
+ */
+ public static class ViewIndexDistanceComparator implements Comparator<View>{
+ final private int mIndex;
+ /**
+ * @param index Compare based on each view's distance to this index
+ */
+ public ViewIndexDistanceComparator(int index) {
+ mIndex = index;
+ }
+
+ @Override
+ public int compare(View lhs, View rhs) {
+ ViewParent parent = lhs.getParent();
+ if (parent == rhs.getParent()) {
+ if (parent instanceof ViewGroup) {
+ ViewGroup p = (ViewGroup) parent;
+ int lhsIndex = p.indexOfChild(lhs);
+ int rhsIndex = p.indexOfChild(rhs);
+ int lhsDistance = Math.abs(mIndex - lhsIndex);
+ int rhsDistance = Math.abs(mIndex - rhsIndex);
+ // prefer shorter distance since they are the next ones to be swiped to
+ int result = lhsDistance - rhsDistance;
+ if (result == 0) {
+ // prefer higher index since they are to the right in the photoviewer
+ return rhsIndex - lhsIndex;
+ }
+ return result;
+ }
+ }
+ return 0;
+ }
}
}
diff --git a/src/com/android/mail/browse/SendersView.java b/src/com/android/mail/browse/SendersView.java
index 8a1f4c0..b6870a9 100644
--- a/src/com/android/mail/browse/SendersView.java
+++ b/src/com/android/mail/browse/SendersView.java
@@ -194,14 +194,27 @@
ArrayList<String> displayableSenderNames, ArrayList<String> displayableSenderEmails,
String account) {
getSenderResources(context);
+ format(context, conversationInfo, messageInfo, maxChars, styledSenders,
+ displayableSenderNames, displayableSenderEmails, account,
+ sUnreadStyleSpan, sReadStyleSpan);
+ }
+
+ public static void format(Context context, ConversationInfo conversationInfo,
+ String messageInfo, int maxChars, ArrayList<SpannableString> styledSenders,
+ ArrayList<String> displayableSenderNames, ArrayList<String> displayableSenderEmails,
+ String account, final TextAppearanceSpan notificationUnreadStyleSpan,
+ final CharacterStyle notificationReadStyleSpan) {
+ getSenderResources(context);
handlePriority(context, maxChars, messageInfo, conversationInfo, styledSenders,
- displayableSenderNames, displayableSenderEmails, account);
+ displayableSenderNames, displayableSenderEmails, account,
+ notificationUnreadStyleSpan, notificationReadStyleSpan);
}
public static void handlePriority(Context context, int maxChars, String messageInfoString,
ConversationInfo conversationInfo, ArrayList<SpannableString> styledSenders,
ArrayList<String> displayableSenderNames, ArrayList<String> displayableSenderEmails,
- String account) {
+ String account, final TextAppearanceSpan unreadStyleSpan,
+ final CharacterStyle readStyleSpan) {
boolean shouldAddPhotos = displayableSenderEmails != null;
int maxPriorityToInclude = -1; // inclusive
int numCharsUsed = messageInfoString.length(); // draft, number drafts,
@@ -263,7 +276,8 @@
Math.max(nameString.length() - numCharsToRemovePerWord, 0));
}
final int priority = currentMessage.priority;
- style = !currentMessage.read ? getUnreadStyleSpan() : getReadStyleSpan();
+ style = !currentMessage.read ? getWrappedStyleSpan(unreadStyleSpan)
+ : getWrappedStyleSpan(readStyleSpan);
if (priority <= maxPriorityToInclude) {
spannableDisplay = new SpannableString(nameString);
// Don't duplicate senders; leave the first instance, unless the
@@ -333,12 +347,8 @@
}
}
- private static CharacterStyle getUnreadStyleSpan() {
- return CharacterStyle.wrap(sUnreadStyleSpan);
- }
-
- private static CharacterStyle getReadStyleSpan() {
- return CharacterStyle.wrap(sReadStyleSpan);
+ private static CharacterStyle getWrappedStyleSpan(final CharacterStyle characterStyle) {
+ return CharacterStyle.wrap(characterStyle);
}
static String getMe(Context context) {
@@ -353,7 +363,7 @@
}
private static void formatDefault(ConversationItemViewModel header, String sendersString,
- Context context) {
+ Context context, final CharacterStyle readStyleSpan) {
getSenderResources(context);
// Clear any existing sender fragments; we must re-make all of them.
header.senderFragments.clear();
@@ -371,15 +381,23 @@
namesOnly[i] = display;
}
}
- generateSenderFragments(header, namesOnly);
+ generateSenderFragments(header, namesOnly, readStyleSpan);
}
- private static void generateSenderFragments(ConversationItemViewModel header, String[] names) {
+ private static void generateSenderFragments(ConversationItemViewModel header, String[] names,
+ final CharacterStyle readStyleSpan) {
header.sendersText = TextUtils.join(Address.ADDRESS_DELIMETER + " ", names);
- header.addSenderFragment(0, header.sendersText.length(), getReadStyleSpan(), true);
+ header.addSenderFragment(0, header.sendersText.length(), getWrappedStyleSpan(readStyleSpan),
+ true);
}
public static void formatSenders(ConversationItemViewModel header, Context context) {
- formatDefault(header, header.conversation.senders, context);
+ getSenderResources(context);
+ formatSenders(header, context, sReadStyleSpan);
+ }
+
+ public static void formatSenders(ConversationItemViewModel header, Context context,
+ final CharacterStyle readStyleSpan) {
+ formatDefault(header, header.conversation.senders, context, readStyleSpan);
}
}
diff --git a/src/com/android/mail/photo/MailPhotoViewActivity.java b/src/com/android/mail/photo/MailPhotoViewActivity.java
index 47fe32d..7d597e1 100644
--- a/src/com/android/mail/photo/MailPhotoViewActivity.java
+++ b/src/com/android/mail/photo/MailPhotoViewActivity.java
@@ -193,21 +193,21 @@
@Override
public void onFragmentVisible(PhotoViewFragment fragment) {
super.onFragmentVisible(fragment);
-
- final Attachment attachment = getCurrentAttachment();
- updateProgressAndEmptyViews(fragment, attachment);
}
+ @Override
+ public void onCursorChanged(PhotoViewFragment fragment, Cursor cursor) {
+ super.onCursorChanged(fragment, cursor);
+ updateProgressAndEmptyViews(fragment, new Attachment(cursor));
+ }
/**
* Updates the empty views of the fragment based upon the current
* state of the attachment.
* @param fragment the current fragment
- * @param attachment the current {@link Attachment}
*/
private void updateProgressAndEmptyViews(
- PhotoViewFragment fragment, final Attachment attachment) {
-
+ final PhotoViewFragment fragment, final Attachment attachment) {
final ProgressBarWrapper progressBar = fragment.getPhotoProgressBar();
final TextView emptyText = fragment.getEmptyText();
final ImageView retryButton = fragment.getRetryButton();
@@ -230,7 +230,6 @@
@Override
public void onClick(View view) {
downloadAttachment();
- progressBar.setVisibility(View.VISIBLE);
}
});
progressBar.setVisibility(View.GONE);
@@ -330,7 +329,6 @@
/**
* Helper method to get the currently visible attachment.
- * @return
*/
protected Attachment getCurrentAttachment() {
final Cursor cursor = getCursorAtProperPosition();
diff --git a/src/com/android/mail/photomanager/LetterTileProvider.java b/src/com/android/mail/photomanager/LetterTileProvider.java
index 5fba23c..415ae9b 100644
--- a/src/com/android/mail/photomanager/LetterTileProvider.java
+++ b/src/com/android/mail/photomanager/LetterTileProvider.java
@@ -25,6 +25,8 @@
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Paint.Align;
+import android.graphics.Rect;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.TextUtils;
@@ -47,19 +49,22 @@
public class LetterTileProvider extends DefaultImageProvider {
private Bitmap mDefaultBitmap;
private final LruCache<Integer, Bitmap> mTileBitmapCache;
- private static int sTilePaddingBottom;
- private static int sTilePaddingLeft;
+ private static Typeface sSansSerifLight;
+ private static Rect sBounds;
private static int sTileLetterFontSize = -1;
+ private static int sTileLetterFontSizeSmall;
+ private static int sTileColor;
+ private static int sTileFontColor;
private static TextPaint sPaint = new TextPaint();
private static int DEFAULT_AVATAR_DRAWABLE = R.drawable.ic_contact_picture;
- private static final Pattern ALPHABET = Pattern.compile("^[a-zA-Z]+$");
+ private static final Pattern ALPHABET = Pattern.compile("^[a-zA-Z0-9]+$");
public LetterTileProvider() {
super();
final float cacheSizeAdjustment =
(MemoryUtils.getTotalMemorySize() >= MemoryUtils.LARGE_RAM_THRESHOLD) ?
- 1.0f : 0.5f;
- final int bitmapCacheSize = (int) (cacheSizeAdjustment * 26);
+ 1.0f : 0.5f;
+ final int bitmapCacheSize = (int) (cacheSizeAdjustment * 36);
mTileBitmapCache = new LruCache<Integer, Bitmap>(bitmapCacheSize);
}
@@ -67,37 +72,38 @@
public void applyDefaultImage(String displayName, String address, DividedImageCanvas view,
int extent) {
Bitmap bitmap = null;
- // TODO: show just the default gray contact photo for now
- if (false) {
- final String display = !TextUtils.isEmpty(displayName) ? displayName : address;
- final String firstChar = display.substring(0, 1);
- // If its a valid english alphabet letter...
- if (isLetter(firstChar)) {
- final String first = firstChar.toUpperCase();
- DividedImageCanvas.Dimensions d = view.getDesiredDimensions(address);
- int hash = Objects.hashCode(first, d);
- bitmap = mTileBitmapCache.get(hash);
- if (bitmap == null) {
- // Create bitmap based on the first char
- bitmap = Bitmap.createBitmap(d.width, d.height, Bitmap.Config.ARGB_8888);
- sPaint.setColor(Color.BLACK);
- if (sTileLetterFontSize == -1) {
- final Resources res = view.getContext().getResources();
- sTileLetterFontSize = res
- .getDimensionPixelSize(R.dimen.tile_letter_font_size);
- sTilePaddingBottom = res
- .getDimensionPixelSize(R.dimen.tile_letter_padding_bottom);
- sTilePaddingLeft = res
- .getDimensionPixelSize(R.dimen.tile_letter_padding_left);
- }
- sPaint.setTextSize(sTileLetterFontSize * d.scale);
- sPaint.setTypeface(Typeface.DEFAULT);
- Canvas c = new Canvas(bitmap);
- c.drawColor(Color.GRAY);
- c.drawText(first, d.scale * sTilePaddingLeft, d.height
- - (sTilePaddingBottom * d.scale), sPaint);
- mTileBitmapCache.put(hash, bitmap);
+ final String display = !TextUtils.isEmpty(displayName) ? displayName : address;
+ final String firstChar = display.substring(0, 1);
+ // If its a valid english alphabet letter...
+ if (isLetter(firstChar)) {
+ final String first = firstChar.toUpperCase();
+ DividedImageCanvas.Dimensions d = view.getDesiredDimensions(address);
+ int hash = Objects.hashCode(first, d);
+ bitmap = mTileBitmapCache.get(hash);
+ if (bitmap == null) {
+ // Create bitmap based on the first char
+ bitmap = Bitmap.createBitmap(d.width, d.height, Bitmap.Config.ARGB_8888);
+ sPaint.setColor(Color.BLACK);
+ if (sTileLetterFontSize == -1) {
+ final Resources res = view.getContext().getResources();
+ sTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size);
+ sTileLetterFontSizeSmall = res
+ .getDimensionPixelSize(R.dimen.tile_letter_font_size_small);
+ sTileColor = res.getColor(R.color.letter_tile_color);
+ sTileFontColor = res.getColor(R.color.letter_tile_font_color);
+ sSansSerifLight = Typeface.create("sans-serif-light", Typeface.NORMAL);
+ sBounds = new Rect();
}
+ Canvas c = new Canvas(bitmap);
+ c.drawColor(sTileColor);
+ sPaint.setTextSize(getFontSize(d.scale));
+ sPaint.setTypeface(sSansSerifLight);
+ sPaint.setColor(sTileFontColor);
+ sPaint.setTextAlign(Align.CENTER);
+ sPaint.setAntiAlias(true);
+ sPaint.getTextBounds(first, 0, first.length(), sBounds);
+ c.drawText(first, 0+d.width/2, 0+d.height/2+(sBounds.bottom-sBounds.top)/2, sPaint);
+ mTileBitmapCache.put(hash, bitmap);
}
} else {
if (mDefaultBitmap == null) {
@@ -111,6 +117,14 @@
view.addDivisionImage(bitmap, address);
}
+ private int getFontSize(float scale) {
+ if (scale == DividedImageCanvas.ONE) {
+ return sTileLetterFontSize;
+ } else {
+ return sTileLetterFontSizeSmall;
+ }
+ }
+
private boolean isLetter(String letter) {
Matcher m = ALPHABET.matcher(letter);
return m.matches();
diff --git a/src/com/android/mail/preferences/MailPrefs.java b/src/com/android/mail/preferences/MailPrefs.java
index 2f60c4e..1aa8ac0 100644
--- a/src/com/android/mail/preferences/MailPrefs.java
+++ b/src/com/android/mail/preferences/MailPrefs.java
@@ -45,6 +45,7 @@
// Hidden preference to indicate what version a "What's New" dialog was last shown for.
private static final String WHATS_NEW_LAST_SHOWN_VERSION = "whats-new-last-shown-version";
+ public static final String ENABLE_CONVLIST_PHOTOS = "enable-convlist-photos";
public static MailPrefs get(Context c) {
if (sInstance == null) {
@@ -61,6 +62,13 @@
return PREFS_NAME;
}
+ /**
+ * Set the value of a shared preference of type boolean.
+ */
+ public void setSharedBooleanPreference(String pref, boolean value) {
+ mPrefs.edit().putBoolean(pref, value).apply();
+ }
+
public boolean isWidgetConfigured(int appWidgetId) {
return mPrefs.contains(WIDGET_ACCOUNT_PREFIX + appWidgetId);
}
@@ -76,6 +84,14 @@
return mPrefs.getString(WIDGET_ACCOUNT_PREFIX + appWidgetId, null);
}
+ /**
+ * Get whether to show the experimental inline contact photos in the
+ * conversation list.
+ */
+ public boolean areConvListPhotosEnabled() {
+ return mPrefs.getBoolean(ENABLE_CONVLIST_PHOTOS, false);
+ }
+
private static String createWidgetPreferenceValue(Account account, Folder folder) {
return account.uri.toString() +
ACCOUNT_FOLDER_PREFERENCE_SEPARATOR + folder.uri.toString();
diff --git a/src/com/android/mail/providers/Attachment.java b/src/com/android/mail/providers/Attachment.java
index abd6347..707619a 100644
--- a/src/com/android/mail/providers/Attachment.java
+++ b/src/com/android/mail/providers/Attachment.java
@@ -269,7 +269,7 @@
public boolean shouldShowProgress() {
return state == AttachmentState.DOWNLOADING
- && size > 0 && downloadedSize > 0 && downloadedSize < size;
+ && size > 0 && downloadedSize > 0 && downloadedSize <= size;
}
public boolean isDownloadFailed() {
diff --git a/src/com/android/mail/providers/Conversation.java b/src/com/android/mail/providers/Conversation.java
index 1554927..27121d8 100644
--- a/src/com/android/mail/providers/Conversation.java
+++ b/src/com/android/mail/providers/Conversation.java
@@ -23,9 +23,7 @@
import android.os.Parcelable;
import android.provider.BaseColumns;
import android.text.SpannableStringBuilder;
-import android.text.TextPaint;
import android.text.TextUtils;
-import android.text.TextUtils.TruncateAt;
import com.android.mail.R;
import com.android.mail.providers.UIProvider.ConversationColumns;
@@ -531,27 +529,14 @@
* @param context
* @param filteredSubject
* @param snippet
- * @param maxChars Supply max characters the returned string can have, or -1
- * if there is no limit
*/
- public static SpannableStringBuilder getSubjectAndSnippetForDisplay(Context context,
- String filteredSubject, String snippet, int avail, TextPaint paint) {
+ public static String getSubjectAndSnippetForDisplay(Context context,
+ String filteredSubject, String snippet) {
if (sSubjectAndSnippet == null) {
sSubjectAndSnippet = context.getString(R.string.subject_and_snippet);
}
- String subjectText = (!TextUtils.isEmpty(snippet)) ?
+ return (!TextUtils.isEmpty(snippet)) ?
String.format(sSubjectAndSnippet, filteredSubject, snippet)
: filteredSubject;
- SpannableStringBuilder builder = new SpannableStringBuilder();
- if (avail != -1) {
- CharSequence ellipsizedText = TextUtils.ellipsize(subjectText, paint, avail,
- TruncateAt.END);
- if (!TextUtils.isEmpty(ellipsizedText)) {
- builder.append(ellipsizedText, 0, ellipsizedText.length() - 1);
- }
- } else {
- builder.append(subjectText);
- }
- return builder;
}
}
diff --git a/src/com/android/mail/providers/MailAppProvider.java b/src/com/android/mail/providers/MailAppProvider.java
index 798c446..587170d 100644
--- a/src/com/android/mail/providers/MailAppProvider.java
+++ b/src/com/android/mail/providers/MailAppProvider.java
@@ -295,8 +295,8 @@
case UIProvider.ACCOUNT_SETTINGS_REPLY_BEHAVIOR_COLUMN:
builder.add(Integer.valueOf(account.settings.replyBehavior));
break;
- case UIProvider.ACCOUNT_SETTINGS_SHOW_CHECKBOXES_COLUMN:
- builder.add(Integer.valueOf(account.settings.showCheckboxes ? 1 : 0));
+ case UIProvider.ACCOUNT_SETTINGS_HIDE_CHECKBOXES_COLUMN:
+ builder.add(Integer.valueOf(account.settings.hideCheckboxes ? 1 : 0));
break;
case UIProvider.ACCOUNT_SETTINGS_CONFIRM_DELETE_COLUMN:
builder.add(Integer.valueOf(account.settings.confirmDelete ? 1 : 0));
diff --git a/src/com/android/mail/providers/Settings.java b/src/com/android/mail/providers/Settings.java
index d37bab1..b77a19d 100644
--- a/src/com/android/mail/providers/Settings.java
+++ b/src/com/android/mail/providers/Settings.java
@@ -66,7 +66,7 @@
public final int messageTextSize;
public final int snapHeaders;
public final int replyBehavior;
- public final boolean showCheckboxes;
+ public final boolean hideCheckboxes;
public final boolean confirmDelete;
public final boolean confirmArchive;
public final boolean confirmSend;
@@ -101,7 +101,7 @@
messageTextSize = MessageTextSize.NORMAL;
snapHeaders = SnapHeaderValue.ALWAYS;
replyBehavior = DefaultReplyBehavior.REPLY;
- showCheckboxes = false;
+ hideCheckboxes = false;
confirmDelete = false;
confirmArchive = false;
confirmSend = false;
@@ -122,7 +122,7 @@
messageTextSize = inParcel.readInt();
snapHeaders = inParcel.readInt();
replyBehavior = inParcel.readInt();
- showCheckboxes = inParcel.readInt() != 0;
+ hideCheckboxes = inParcel.readInt() != 0;
confirmDelete = inParcel.readInt() != 0;
confirmArchive = inParcel.readInt() != 0;
confirmSend = inParcel.readInt() != 0;
@@ -143,7 +143,7 @@
messageTextSize = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_MESSAGE_TEXT_SIZE_COLUMN);
snapHeaders = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_SNAP_HEADERS_COLUMN);
replyBehavior = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_REPLY_BEHAVIOR_COLUMN);
- showCheckboxes = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_SHOW_CHECKBOXES_COLUMN) != 0;
+ hideCheckboxes = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_HIDE_CHECKBOXES_COLUMN) != 0;
confirmDelete = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_CONFIRM_DELETE_COLUMN) != 0;
confirmArchive = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_CONFIRM_ARCHIVE_COLUMN) != 0;
confirmSend = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_CONFIRM_SEND_COLUMN) != 0;
@@ -173,8 +173,8 @@
sDefault.snapHeaders);
replyBehavior = json.optInt(AccountColumns.SettingsColumns.REPLY_BEHAVIOR,
sDefault.replyBehavior);
- showCheckboxes = json.optBoolean(AccountColumns.SettingsColumns.SHOW_CHECKBOXES,
- sDefault.showCheckboxes);
+ hideCheckboxes = json.optBoolean(AccountColumns.SettingsColumns.HIDE_CHECKBOXES,
+ sDefault.hideCheckboxes);
confirmDelete = json.optBoolean(AccountColumns.SettingsColumns.CONFIRM_DELETE,
sDefault.confirmDelete);
confirmArchive = json.optBoolean(AccountColumns.SettingsColumns.CONFIRM_ARCHIVE,
@@ -228,7 +228,7 @@
json.put(AccountColumns.SettingsColumns.MESSAGE_TEXT_SIZE, messageTextSize);
json.put(AccountColumns.SettingsColumns.SNAP_HEADERS, snapHeaders);
json.put(AccountColumns.SettingsColumns.REPLY_BEHAVIOR, replyBehavior);
- json.put(AccountColumns.SettingsColumns.SHOW_CHECKBOXES, showCheckboxes);
+ json.put(AccountColumns.SettingsColumns.HIDE_CHECKBOXES, hideCheckboxes);
json.put(AccountColumns.SettingsColumns.CONFIRM_DELETE, confirmDelete);
json.put(AccountColumns.SettingsColumns.CONFIRM_ARCHIVE, confirmArchive);
json.put(AccountColumns.SettingsColumns.CONFIRM_SEND, confirmSend);
@@ -298,7 +298,7 @@
dest.writeInt(messageTextSize);
dest.writeInt(snapHeaders);
dest.writeInt(replyBehavior);
- dest.writeInt(showCheckboxes ? 1 : 0);
+ dest.writeInt(hideCheckboxes ? 1 : 0);
dest.writeInt(confirmDelete ? 1 : 0);
dest.writeInt(confirmArchive? 1 : 0);
dest.writeInt(confirmSend? 1 : 0);
@@ -391,7 +391,7 @@
&& messageTextSize == that.messageTextSize
&& snapHeaders == that.snapHeaders
&& replyBehavior == that.replyBehavior
- && showCheckboxes == that.showCheckboxes
+ && hideCheckboxes == that.hideCheckboxes
&& confirmDelete == that.confirmDelete
&& confirmArchive == that.confirmArchive
&& confirmSend == that.confirmSend
@@ -420,7 +420,7 @@
private final int calculateHashCode() {
return super.hashCode()
^ Objects.hashCode(signature, mAutoAdvance, mTransientAutoAdvance, messageTextSize,
- snapHeaders, replyBehavior, showCheckboxes, confirmDelete, confirmArchive,
+ snapHeaders, replyBehavior, hideCheckboxes, confirmDelete, confirmArchive,
confirmSend, defaultInbox, forceReplyFromDefault, maxAttachmentSize, swipe,
priorityArrowsEnabled, setupIntentUri, conversationViewMode,
veiledAddressPattern);
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index 5e6b189..25da659 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -157,7 +157,7 @@
.put(AccountColumns.SettingsColumns.MESSAGE_TEXT_SIZE, Integer.class)
.put(AccountColumns.SettingsColumns.SNAP_HEADERS, Integer.class)
.put(AccountColumns.SettingsColumns.REPLY_BEHAVIOR, Integer.class)
- .put(AccountColumns.SettingsColumns.SHOW_CHECKBOXES, Integer.class)
+ .put(AccountColumns.SettingsColumns.HIDE_CHECKBOXES, Integer.class)
.put(AccountColumns.SettingsColumns.CONFIRM_DELETE, Integer.class)
.put(AccountColumns.SettingsColumns.CONFIRM_ARCHIVE, Integer.class)
.put(AccountColumns.SettingsColumns.CONFIRM_SEND, Integer.class)
@@ -209,7 +209,7 @@
public static final int ACCOUNT_SETTINGS_MESSAGE_TEXT_SIZE_COLUMN = 28;
public static final int ACCOUNT_SETTINGS_SNAP_HEADERS_COLUMN = 29;
public static final int ACCOUNT_SETTINGS_REPLY_BEHAVIOR_COLUMN = 30;
- public static final int ACCOUNT_SETTINGS_SHOW_CHECKBOXES_COLUMN = 31;
+ public static final int ACCOUNT_SETTINGS_HIDE_CHECKBOXES_COLUMN = 31;
public static final int ACCOUNT_SETTINGS_CONFIRM_DELETE_COLUMN = 32;
public static final int ACCOUNT_SETTINGS_CONFIRM_ARCHIVE_COLUMN = 33;
public static final int ACCOUNT_SETTINGS_CONFIRM_SEND_COLUMN = 34;
@@ -534,9 +534,9 @@
/**
* Integer column containing the user's specified checkbox preference. A
- * non zero value means to show checkboxes.
+ * non zero value means to hide checkboxes.
*/
- public static final String SHOW_CHECKBOXES = "show_checkboxes";
+ public static final String HIDE_CHECKBOXES = "hide_checkboxes";
/**
* Integer column containing the user's specified confirm delete preference value.
@@ -644,8 +644,8 @@
.put(AccountColumns.SettingsColumns.SNAP_HEADERS,ACCOUNT_SETTINGS_SNAP_HEADERS_COLUMN)
.put(AccountColumns.SettingsColumns.REPLY_BEHAVIOR,
ACCOUNT_SETTINGS_REPLY_BEHAVIOR_COLUMN)
- .put(AccountColumns.SettingsColumns.SHOW_CHECKBOXES,
- ACCOUNT_SETTINGS_SHOW_CHECKBOXES_COLUMN)
+ .put(AccountColumns.SettingsColumns.HIDE_CHECKBOXES,
+ ACCOUNT_SETTINGS_HIDE_CHECKBOXES_COLUMN)
.put(AccountColumns.SettingsColumns.CONFIRM_DELETE,
ACCOUNT_SETTINGS_CONFIRM_DELETE_COLUMN)
.put(AccountColumns.SettingsColumns.CONFIRM_ARCHIVE,
@@ -1908,6 +1908,8 @@
public static final class AttachmentContentValueKeys {
public static final String RENDITION = "rendition";
+ public static final String ADDITIONAL_PRIORITY = "additionalPriority";
+ public static final String DELAY_DOWNLOAD = "delayDownload";
}
/**
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index 617ce5a..1adc85d 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -1825,7 +1825,7 @@
if (mCurrentConversation != null) {
mActionBarView.setCurrentConversation(mCurrentConversation);
- getSubjectDisplayChanger().setSubject(mCurrentConversation.subject);
+ mActionBarView.setSubject(mCurrentConversation.subject);
mActivity.invalidateOptionsMenu();
}
}
diff --git a/src/com/android/mail/ui/AbstractConversationViewFragment.java b/src/com/android/mail/ui/AbstractConversationViewFragment.java
index 4d2728c..fd51d2f 100644
--- a/src/com/android/mail/ui/AbstractConversationViewFragment.java
+++ b/src/com/android/mail/ui/AbstractConversationViewFragment.java
@@ -21,20 +21,13 @@
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
import android.app.Fragment;
import android.app.LoaderManager;
import android.content.ActivityNotFoundException;
-import android.content.ContentResolver;
-import android.content.ContentValues;
import android.content.Context;
import android.content.CursorLoader;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.Loader;
-import android.content.DialogInterface.OnClickListener;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -70,7 +63,6 @@
import com.android.mail.providers.Folder;
import com.android.mail.providers.ListParams;
import com.android.mail.providers.UIProvider;
-import com.android.mail.providers.UIProvider.AccountColumns;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
diff --git a/src/com/android/mail/ui/ActivityController.java b/src/com/android/mail/ui/ActivityController.java
index d9190bc..ae64a47 100644
--- a/src/com/android/mail/ui/ActivityController.java
+++ b/src/com/android/mail/ui/ActivityController.java
@@ -298,9 +298,4 @@
* Called when Accessibility is enabled or disabled.
*/
void onAccessibilityStateChanged();
-
- /**
- * Detect if there are any animations occuring in the conversation list.
- */
- boolean isAnimating();
}
diff --git a/src/com/android/mail/ui/AnimatedAdapter.java b/src/com/android/mail/ui/AnimatedAdapter.java
index 2b0d020..d456783 100644
--- a/src/com/android/mail/ui/AnimatedAdapter.java
+++ b/src/com/android/mail/ui/AnimatedAdapter.java
@@ -53,7 +53,8 @@
public class AnimatedAdapter extends SimpleCursorAdapter implements
android.animation.Animator.AnimatorListener {
- private static int sDismissAllDelay = -1;
+ private static int sDismissAllShortDelay = -1;
+ private static int sDismissAllLongDelay = -1;
private static final String LAST_DELETING_ITEMS = "last_deleting_items";
private static final String LEAVE_BEHIND_ITEM_DATA = "leave_behind_item_data";
private static final String LEAVE_BEHIND_ITEM_ID = "leave_behind_item_id";
@@ -124,6 +125,7 @@
* Used only for debugging.
*/
private static final String LOG_TAG = LogTag.getLogTag();
+ private static final int INCREASE_WAIT_COUNT = 2;
public AnimatedAdapter(Context context, int textViewResourceId, ConversationCursor cursor,
ConversationSelectionSet batch,
@@ -136,9 +138,13 @@
mShowFooter = false;
mListView = listView;
mHandler = new Handler();
- if (sDismissAllDelay == -1) {
- sDismissAllDelay =
- context.getResources().getInteger(R.integer.dismiss_all_leavebehinds_delay);
+ if (sDismissAllShortDelay == -1) {
+ sDismissAllShortDelay =
+ context.getResources()
+ .getInteger(R.integer.dismiss_all_leavebehinds_short_delay);
+ sDismissAllLongDelay =
+ context.getResources()
+ .getInteger(R.integer.dismiss_all_leavebehinds_long_delay);
}
}
@@ -148,7 +154,11 @@
}
public void startDismissCounter() {
- mHandler.postDelayed(mCountDown, sDismissAllDelay);
+ if (mLeaveBehindItems.size() > INCREASE_WAIT_COUNT) {
+ mHandler.postDelayed(mCountDown, sDismissAllLongDelay);
+ } else {
+ mHandler.postDelayed(mCountDown, sDismissAllShortDelay);
+ }
}
public final void destroy() {
@@ -201,7 +211,7 @@
view = new SwipeableConversationItemView(context, mAccount.name);
}
view.bind(conv, mActivity, mBatchConversations, mFolder,
- mAccount != null ? !mAccount.settings.showCheckboxes : false, mSwipeEnabled,
+ mAccount != null ? mAccount.settings.hideCheckboxes : false, mSwipeEnabled,
mPriorityMarkersEnabled, this);
return view;
}
@@ -321,7 +331,18 @@
if (isPositionLeaveBehind(conv)) {
LeaveBehindItem fadeIn = getLeaveBehindItem(conv);
if (conv.id == mLastLeaveBehind) {
- fadeIn.startFadeInTextAnimation(true /* delay start */);
+ // If it looks like the person is doing a lot of rapid
+ // swipes, wait patiently before animating
+ if (mLeaveBehindItems.size() > INCREASE_WAIT_COUNT) {
+ if (fadeIn.isAnimating()) {
+ fadeIn.increaseFadeInDelay(sDismissAllLongDelay);
+ } else {
+ fadeIn.startFadeInTextAnimation(sDismissAllLongDelay);
+ }
+ } else {
+ // Otherwise, assume they are just doing 1 and wait less time
+ fadeIn.startFadeInTextAnimation(sDismissAllShortDelay /* delay start */);
+ }
}
return fadeIn;
}
@@ -387,6 +408,7 @@
item = i.next().getValue();
Conversation conv = item.getData();
if (mLastLeaveBehind == -1 || conv.id != mLastLeaveBehind) {
+ item.cancelFadeInTextAnimation();
item.makeInert();
}
}
@@ -519,7 +541,7 @@
return;
}
((SwipeableConversationItemView) view).bind(cursor, mActivity, mBatchConversations, mFolder,
- mAccount != null ? !mAccount.settings.showCheckboxes : false,
+ mAccount != null ? mAccount.settings.hideCheckboxes : false,
mSwipeEnabled, mPriorityMarkersEnabled, this);
}
@@ -529,7 +551,7 @@
position, null, parent);
view.reset();
view.bind(conversation, mActivity, mBatchConversations, mFolder,
- mAccount != null ? !mAccount.settings.showCheckboxes : false, mSwipeEnabled,
+ mAccount != null ? mAccount.settings.hideCheckboxes : false, mSwipeEnabled,
mPriorityMarkersEnabled, this);
mAnimatingViews.put(conversation.id, view);
return view;
@@ -614,10 +636,12 @@
if (!hasFadeLeaveBehinds()) {
// Cancel any existing animations on the remaining leave behind
// item and start fading in text immediately.
- cancelLeaveBehindFadeInAnimation();
LeaveBehindItem item = getLastLeaveBehindItem();
if (item != null) {
- item.startFadeInTextAnimation(false /* delay start */);
+ boolean cancelled = item.cancelFadeInTextAnimationIfNotStarted();
+ if (cancelled) {
+ item.startFadeInTextAnimation(0 /* delay start */);
+ }
}
}
// The view types have changed, since the animating views are gone.
@@ -773,4 +797,4 @@
item.cancelFadeOutText();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/mail/ui/ConversationListFragment.java b/src/com/android/mail/ui/ConversationListFragment.java
index 12f31fa..e497d42 100644
--- a/src/com/android/mail/ui/ConversationListFragment.java
+++ b/src/com/android/mail/ui/ConversationListFragment.java
@@ -435,7 +435,7 @@
if (!(view instanceof ToggleableItem)) {
return;
}
- if (!mAccount.settings.showCheckboxes && !mSelectedSet.isEmpty()) {
+ if (mAccount.settings.hideCheckboxes && !mSelectedSet.isEmpty()) {
ToggleableItem v = (ToggleableItem) view;
v.toggleCheckMarkOrBeginDrag();
} else {
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index 5c50b52..e4d1785 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -1338,6 +1338,7 @@
mConversation = conv;
if (headerView != null) {
headerView.onConversationUpdated(conv);
+ headerView.setSubject(conv.subject);
}
}
diff --git a/src/com/android/mail/ui/DividedImageCanvas.java b/src/com/android/mail/ui/DividedImageCanvas.java
index f8795b2..9b6e782 100644
--- a/src/com/android/mail/ui/DividedImageCanvas.java
+++ b/src/com/android/mail/ui/DividedImageCanvas.java
@@ -17,12 +17,14 @@
package com.android.mail.ui;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
+import com.android.mail.R;
import com.android.mail.photomanager.BitmapUtil;
import com.google.common.base.Objects;
@@ -51,17 +53,24 @@
private final InvalidateCallback mCallback;
private final ArrayList<Bitmap> mDivisionImages = new ArrayList<Bitmap>(MAX_DIVISIONS);
+
private static final Paint sPaint = new Paint();
private static final Rect sSrc = new Rect();
private static final Rect sDest = new Rect();
- private static final float ONE = 1.0f;
+ public static final float ONE = 1.0f;
- private static final float HALF = 0.5f;
+ public static final float HALF = 0.5f;
+
+ public static final float QUARTER = 0.25f;
+
+ private static int sDividerLineWidth = -1;
+ private static int sDividerColor;
public DividedImageCanvas(Context context, InvalidateCallback callback) {
mContext = context;
mCallback = callback;
+ setupDividerLines();
}
/**
@@ -160,25 +169,25 @@
case 2:
w = mWidth / 2;
h = mHeight;
- scale = ONE;
+ scale = HALF;
break;
case 3:
switch (pos) {
case 0:
w = mWidth / 2;
h = mHeight;
- scale = ONE;
+ scale = HALF;
break;
default:
w = mWidth / 2;
h = mHeight / 2;
- scale = HALF;
+ scale = QUARTER;
}
break;
case 4:
w = mWidth / 2;
h = mHeight / 2;
- scale = HALF;
+ scale = QUARTER;
break;
}
}
@@ -223,11 +232,14 @@
break;
}
complete = mDivisionImages.get(0) != null && mDivisionImages.get(1) != null;
+ if (complete) {
+ // Draw dividers
+ drawVerticalDivider(width, height);
+ }
break;
case 3:
// Draw 3 bitmaps: the first takes up all vertical
- // space,
- // the 2nd and 3rd are stacked in the second vertical
+ // space, the 2nd and 3rd are stacked in the second vertical
// position.
switch (pos) {
case 0:
@@ -243,6 +255,11 @@
}
complete = mDivisionImages.get(0) != null && mDivisionImages.get(1) != null
&& mDivisionImages.get(2) != null;
+ if (complete) {
+ // Draw dividers
+ drawVerticalDivider(width, height);
+ drawHorizontalDivider(width / 2, height / 2, width, height / 2);
+ }
break;
default:
// Draw all 4 bitmaps in a grid
@@ -263,6 +280,11 @@
}
complete = mDivisionImages.get(0) != null && mDivisionImages.get(1) != null
&& mDivisionImages.get(2) != null && mDivisionImages.get(3) != null;
+ if (complete) {
+ // Draw dividers
+ drawVerticalDivider(width, height);
+ drawHorizontalDivider(0, height / 2, width, height / 2);
+ }
break;
}
// Create the new image bitmap.
@@ -272,6 +294,31 @@
}
}
+ private void setupDividerLines() {
+ if (sDividerLineWidth == -1) {
+ Resources res = getContext().getResources();
+ sDividerLineWidth = res
+ .getDimensionPixelSize(R.dimen.tile_divider_width);
+ sDividerColor = res.getColor(R.color.tile_divider_color);
+ }
+ }
+
+ private void setupPaint() {
+ sPaint.setStrokeWidth(sDividerLineWidth);
+ sPaint.setColor(sDividerColor);
+ }
+
+ private void drawVerticalDivider(int width, int height) {
+ int x1 = width / 2, y1 = 0, x2 = width/2, y2 = height;
+ setupPaint();
+ mCanvas.drawLine(x1, y1, x2, y2, sPaint);
+ }
+
+ private void drawHorizontalDivider(int x1, int y1, int x2, int y2) {
+ setupPaint();
+ mCanvas.drawLine(x1, y1, x2, y2, sPaint);
+ }
+
/**
* Draw the contents of the DividedImageCanvas to the supplied canvas.
*/
diff --git a/src/com/android/mail/ui/EllipsizedMultilineTextView.java b/src/com/android/mail/ui/EllipsizedMultilineTextView.java
new file mode 100644
index 0000000..0f83f27
--- /dev/null
+++ b/src/com/android/mail/ui/EllipsizedMultilineTextView.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * 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.
+ */
+
+package com.android.mail.ui;
+
+import android.content.Context;
+import android.text.Layout;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+/**
+ * A special MultiLine TextView that will apply ellipsize logic to only the last
+ * line of text, such that the last line may be shorter than any previous lines.
+ */
+public class EllipsizedMultilineTextView extends TextView {
+
+ public static final int ALL_AVAILABLE = -1;
+ private int mMaxLines;
+ private int mLastWSpec;
+ private int mLastHSpec;
+
+ public EllipsizedMultilineTextView(Context context) {
+ this(context, null);
+ }
+
+ public EllipsizedMultilineTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void setMaxLines(int maxlines) {
+ super.setMaxLines(maxlines);
+ mMaxLines = maxlines;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ mLastWSpec = widthMeasureSpec;
+ mLastHSpec = heightMeasureSpec;
+ }
+
+ /**
+ * Ellipsize just the last line of text in this view and set the text to the
+ * new ellipsized value.
+ * @param text Text to set and ellipsize
+ * @param avail available width in pixels for the last line
+ * @param paint Paint that has the proper properties set to measure the text
+ * for this view
+ */
+ public void setText(final CharSequence text, int avail) {
+ if (text == null || text.length() == 0) {
+ return;
+ }
+
+ setEllipsize(null);
+ setText(text, TextView.BufferType.SPANNABLE);
+
+ if (avail == ALL_AVAILABLE) {
+ return;
+ }
+ Layout layout = getLayout();
+
+ if (layout == null) {
+ measure(mLastWSpec, mLastHSpec);
+ layout = getLayout();
+ }
+
+ if (layout == null) {
+ // Bail
+ return;
+ }
+
+ CharSequence remainder;
+ SpannableStringBuilder builder = new SpannableStringBuilder();
+ int lineCount = layout.getLineCount();
+ if (lineCount <= mMaxLines) {
+ remainder = null;
+ } else {
+ remainder = TextUtils.ellipsize(
+ text.subSequence(layout.getLineStart(mMaxLines - 1), text.length()),
+ getPaint(), avail, TextUtils.TruncateAt.END);
+ }
+
+ builder.append(text, 0, layout.getLineStart(mMaxLines - 1));
+ if (!TextUtils.isEmpty(remainder)) {
+ builder.append(remainder);
+ }
+ setText(builder, TextView.BufferType.SPANNABLE);
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/mail/ui/LeaveBehindItem.java b/src/com/android/mail/ui/LeaveBehindItem.java
index ddf6bb0..f80a17f 100644
--- a/src/com/android/mail/ui/LeaveBehindItem.java
+++ b/src/com/android/mail/ui/LeaveBehindItem.java
@@ -47,7 +47,6 @@
public int position;
private static int sShrinkAnimationDuration = -1;
private static int sFadeInAnimationDuration = -1;
- private static int sDismissAllLeaveBehindsDelay = -1;
private static float sScrollSlop;
private static float OPAQUE = 1.0f;
private static float INVISIBLE = 0.0f;
@@ -67,8 +66,6 @@
sShrinkAnimationDuration = res.getInteger(R.integer.shrink_animation_duration);
sFadeInAnimationDuration = res.getInteger(R.integer.fade_in_animation_duration);
sScrollSlop = res.getInteger(R.integer.leaveBehindSwipeScrollSlop);
- sDismissAllLeaveBehindsDelay = res
- .getInteger(R.integer.dismiss_all_leavebehinds_delay);
}
}
@@ -193,7 +190,7 @@
* Kick off the animation to fade in the leave behind text.
* @param delay Whether to delay the start of the animation or not.
*/
- public void startFadeInTextAnimation(boolean delay) {
+ public void startFadeInTextAnimation(int delay) {
// If this thing isn't already fully visible AND its not already animating...
if (!mFadingInText && mSwipeableContent.getAlpha() != OPAQUE) {
mFadingInText = true;
@@ -201,8 +198,8 @@
final float end = OPAQUE;
mFadeIn = ObjectAnimator.ofFloat(mSwipeableContent, "alpha", start, end);
mSwipeableContent.setAlpha(INVISIBLE);
- if (delay) {
- mFadeIn.setStartDelay(sDismissAllLeaveBehindsDelay);
+ if (delay != 0) {
+ mFadeIn.setStartDelay(delay);
}
mFadeIn.setInterpolator(new DecelerateInterpolator(OPAQUE));
mFadeIn.setDuration(sFadeInAnimationDuration / 2);
@@ -210,6 +207,27 @@
}
}
+ /**
+ * Increase the overall time before fading in a the text description this view.
+ * @param newDelay Amount of total delay the user should see
+ */
+ public void increaseFadeInDelay(int newDelay) {
+ // If this thing isn't already fully visible AND its not already animating...
+ if (!mFadingInText && mSwipeableContent.getAlpha() != OPAQUE) {
+ mFadingInText = true;
+ long delay = mFadeIn.getStartDelay();
+ if (newDelay == delay || mFadeIn.isRunning()) {
+ return;
+ }
+ mFadeIn.cancel();
+ mFadeIn.setStartDelay(newDelay - delay);
+ mFadeIn.start();
+ }
+ }
+
+ /**
+ * Cancel fading in the text description for this view.
+ */
public void cancelFadeInTextAnimation() {
if (mFadeIn != null) {
mFadingInText = false;
@@ -217,6 +235,20 @@
}
}
+ /**
+ * Cancel fading in the text description for this view only if it the
+ * animation hasn't already started.
+ * @return whether the animation was cancelled
+ */
+ public boolean cancelFadeInTextAnimationIfNotStarted() {
+ // The animation was started, so don't cancel and restart it.
+ if (mFadeIn != null && !mFadeIn.isRunning()) {
+ cancelFadeInTextAnimation();
+ return true;
+ }
+ return false;
+ }
+
public void setData(Conversation conversation) {
mData = conversation;
}
@@ -258,4 +290,8 @@
public void cancelFadeOutText() {
mSwipeableContent.setAlpha(OPAQUE);
}
+
+ public boolean isAnimating() {
+ return this.mFadingInText;
+ }
}
\ No newline at end of file
diff --git a/src/com/android/mail/ui/SecureConversationViewFragment.java b/src/com/android/mail/ui/SecureConversationViewFragment.java
index a731761..58d3f3c 100644
--- a/src/com/android/mail/ui/SecureConversationViewFragment.java
+++ b/src/com/android/mail/ui/SecureConversationViewFragment.java
@@ -184,13 +184,10 @@
if (mActivity == null) {
return;
}
- final SubjectDisplayChanger sdc = mActivity.getSubjectDisplayChanger();
- if (sdc != null) {
- sdc.setSubject(mConversation.subject);
+ if (isUserVisible()) {
+ mScrollView.scrollTo(0, 0);
+ onConversationSeen();
}
- mConversationHeaderView.setSubject(mConversation.subject);
- this.mScrollView.scrollTo(0, 0);
- onConversationSeen();
}
@Override
@@ -225,7 +222,7 @@
*/
private void renderMessageBodies(MessageCursor messageCursor,
boolean enableContentReadySignal) {
- StringBuilder convHtml = new StringBuilder();
+ final StringBuilder convHtml = new StringBuilder();
String content;
if (messageCursor.moveToFirst()) {
content = messageCursor.getString(UIProvider.MESSAGE_BODY_HTML_COLUMN);
@@ -260,6 +257,7 @@
final ConversationViewHeader headerView = mConversationHeaderView;
if (headerView != null) {
headerView.onConversationUpdated(conv);
+ headerView.setSubject(conv.subject);
}
}
diff --git a/src/com/android/mail/ui/SubjectDisplayChanger.java b/src/com/android/mail/ui/SubjectDisplayChanger.java
index 5f76f16..29ccef5 100644
--- a/src/com/android/mail/ui/SubjectDisplayChanger.java
+++ b/src/com/android/mail/ui/SubjectDisplayChanger.java
@@ -23,14 +23,11 @@
* {@link #setSubject(String)}). They can also measure the view and determine how much of the
* subject string was not shown due to screen constraints ({@link #getUnshownSubject(String)}).
*/
-// Called ConversationSubjectDisplayer in Gmail.
public interface SubjectDisplayChanger {
/**
- * Set the subject of the conversation view to the subject given.
+ * Set the subject of the action bar to the subject given.
* @param subject the subject string
*/
- // This had the signature setSubject(ConversationInfo info, String subject) in Gmail, but info
- // was not being used anywhere.
void setSubject(String subject);
/**
diff --git a/src/com/android/mail/ui/TwoPaneController.java b/src/com/android/mail/ui/TwoPaneController.java
index 1965ab5..77f9f67 100644
--- a/src/com/android/mail/ui/TwoPaneController.java
+++ b/src/com/android/mail/ui/TwoPaneController.java
@@ -313,10 +313,15 @@
@Override
public void setCurrentConversation(Conversation conversation) {
- long oldId = mCurrentConversation != null ? mCurrentConversation.id : -1;
- long newId = conversation != null ? conversation.id : -1;
- boolean different = oldId != newId;
+ // Order is important! We want to calculate different *before* the superclass changes
+ // mCurrentConversation, so before super.setCurrentConversation().
+ final long oldId = mCurrentConversation != null ? mCurrentConversation.id : -1;
+ final long newId = conversation != null ? conversation.id : -1;
+ final boolean different = oldId != newId;
+
+ // This call might change mCurrentConversation.
super.setCurrentConversation(conversation);
+
final ConversationListFragment convList = getConversationListFragment();
if (convList != null && conversation != null) {
convList.setSelected(conversation.position, different);
diff --git a/src/com/android/mail/utils/LogUtils.java b/src/com/android/mail/utils/LogUtils.java
index fb875af..9ec466b 100644
--- a/src/com/android/mail/utils/LogUtils.java
+++ b/src/com/android/mail/utils/LogUtils.java
@@ -69,6 +69,10 @@
*/
@VisibleForTesting
static void setDebugLoggingEnabledForTests(boolean enabled) {
+ setDebugLoggingEnabledForTestsInternal(enabled);
+ }
+
+ protected static void setDebugLoggingEnabledForTestsInternal(boolean enabled) {
sDebugLoggingEnabledForTests = Boolean.valueOf(enabled);
}
diff --git a/src/com/android/mail/widget/WidgetConversationViewBuilder.java b/src/com/android/mail/widget/WidgetConversationViewBuilder.java
index a3e25b7..6c30570 100644
--- a/src/com/android/mail/widget/WidgetConversationViewBuilder.java
+++ b/src/com/android/mail/widget/WidgetConversationViewBuilder.java
@@ -158,8 +158,8 @@
// Add style to subject
int subjectColor = isUnread ? SUBJECT_TEXT_COLOR_UNREAD : SUBJECT_TEXT_COLOR_READ;
- SpannableStringBuilder subjectAndSnippet = Conversation.getSubjectAndSnippetForDisplay(
- mContext, filteredSubject, snippet, -1, null);
+ SpannableStringBuilder subjectAndSnippet = new SpannableStringBuilder(
+ Conversation.getSubjectAndSnippetForDisplay(mContext, filteredSubject, snippet));
if (isUnread) {
subjectAndSnippet.setSpan(new StyleSpan(Typeface.BOLD), 0, filteredSubject.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);