@@ -48,6 +48,8 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
4848
4949 private final int commentHorizontalPadding ;
5050 private final int commentVerticalPadding ;
51+
52+ private final Paint paintAtContentSize ;
5153 private final float ellipsisWidthPx ;
5254
5355 private final RelativeLayout itemRoot ;
@@ -76,9 +78,9 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
7678 commentVerticalPadding = (int ) infoItemBuilder .getContext ()
7779 .getResources ().getDimension (R .dimen .comments_vertical_padding );
7880
79- final Paint paint = new Paint ();
80- paint .setTextSize (itemContentView .getTextSize ());
81- ellipsisWidthPx = paint .measureText (ELLIPSIS );
81+ paintAtContentSize = new Paint ();
82+ paintAtContentSize .setTextSize (itemContentView .getTextSize ());
83+ ellipsisWidthPx = paintAtContentSize .measureText (ELLIPSIS );
8284 }
8385
8486 public CommentsMiniInfoItemHolder (final InfoItemBuilder infoItemBuilder ,
@@ -201,18 +203,40 @@ private void determineMovementMethod() {
201203 }
202204
203205 private void ellipsize () {
206+ itemContentView .setMaxLines (COMMENT_EXPANDED_LINES );
204207 linkifyCommentContentView (v -> {
205208 boolean hasEllipsis = false ;
206209
207210 if (itemContentView .getLineCount () > COMMENT_DEFAULT_LINES ) {
208- final int endOfLastLine = itemContentView
209- .getLayout ()
210- .getLineEnd (COMMENT_DEFAULT_LINES - 1 );
211- int end = itemContentView .getText ().toString ().lastIndexOf (' ' , endOfLastLine - 2 );
212- if (end == -1 ) {
213- end = Math .max (endOfLastLine - 2 , 0 );
211+ // Note that converting to String removes spans (i.e. links), but that's something
212+ // we actually want since when the text is ellipsized we want all clicks on the
213+ // comment to expand the comment, not to open links.
214+ final String text = itemContentView .getText ().toString ();
215+
216+ final Layout layout = itemContentView .getLayout ();
217+ final float lineWidth = layout .getLineWidth (COMMENT_DEFAULT_LINES - 1 );
218+ final float layoutWidth = layout .getWidth ();
219+ final int lineStart = layout .getLineStart (COMMENT_DEFAULT_LINES - 1 );
220+ final int lineEnd = layout .getLineEnd (COMMENT_DEFAULT_LINES - 1 );
221+
222+ // remove characters up until there is enough space for the ellipsis
223+ // (also summing 2 more pixels, just to be sure to avoid float rounding errors)
224+ int end = lineEnd ;
225+ float removedCharactersWidth = 0.0f ;
226+ while (lineWidth - removedCharactersWidth + ellipsisWidthPx + 2.0f > layoutWidth
227+ && end >= lineStart ) {
228+ end -= 1 ;
229+ // recalculate each time to account for ligatures or other similar things
230+ removedCharactersWidth = paintAtContentSize .measureText (
231+ text .substring (end , lineEnd ));
214232 }
215- final String newVal = itemContentView .getText ().subSequence (0 , end ) + " …" ;
233+
234+ // remove trailing spaces and newlines
235+ while (end > 0 && Character .isWhitespace (text .charAt (end - 1 ))) {
236+ end -= 1 ;
237+ }
238+
239+ final String newVal = text .substring (0 , end ) + ELLIPSIS ;
216240 itemContentView .setText (newVal );
217241 hasEllipsis = true ;
218242 }
0 commit comments