Skip to content
This repository was archived by the owner on Jul 25, 2024. It is now read-only.

Commit 3898a33

Browse files
kenodoggyniftynei
authored andcommitted
Issue #168 bugfix for links not being clickable, adds autoLink feature including web, phone, map and email
1 parent b47e223 commit 3898a33

File tree

3 files changed

+57
-23
lines changed

3 files changed

+57
-23
lines changed

app/src/main/java/com/zulip/android/activities/RecyclerMessageAdapter.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,14 @@
1111
import android.support.v7.app.AppCompatDelegate;
1212
import android.support.v7.widget.RecyclerView;
1313
import android.text.format.DateUtils;
14+
import android.text.method.LinkMovementMethod;
1415
import android.util.Log;
1516
import android.util.TypedValue;
1617
import android.view.LayoutInflater;
1718
import android.view.View;
1819
import android.view.ViewGroup;
1920

20-
import com.zulip.android.models.Person;
2121
import com.j256.ormlite.stmt.UpdateBuilder;
22-
import com.zulip.android.models.Stream;
23-
import com.zulip.android.networking.AsyncPointerUpdate;
24-
2522
import com.squareup.picasso.Picasso;
2623
import com.zulip.android.R;
2724
import com.zulip.android.ZulipApp;
@@ -362,6 +359,7 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
362359
MessageHolder messageHolder = ((MessageHolder) holder);
363360
final Message message = ((Message) items.get(position));
364361
messageHolder.contentView.setText(message.getFormattedContent(zulipApp));
362+
messageHolder.contentView.setMovementMethod(LinkMovementMethod.getInstance());
365363

366364
if (message.getType() == MessageType.STREAM_MESSAGE) {
367365
messageHolder.senderName.setText(message.getSender().getName());

app/src/main/java/com/zulip/android/models/Message.java

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,5 @@
11
package com.zulip.android.models;
22

3-
import java.io.IOException;
4-
import java.sql.SQLException;
5-
import java.util.ArrayList;
6-
import java.util.Arrays;
7-
import java.util.Date;
8-
import java.util.List;
9-
import java.util.Map;
10-
import java.util.concurrent.Callable;
11-
12-
import org.apache.commons.lang.builder.EqualsBuilder;
13-
import org.apache.commons.lang.builder.HashCodeBuilder;
14-
import org.ccil.cowan.tagsoup.HTMLSchema;
15-
import org.ccil.cowan.tagsoup.Parser;
16-
import org.json.JSONArray;
17-
import org.json.JSONException;
18-
import org.json.JSONObject;
19-
203
import android.content.Context;
214
import android.graphics.Color;
225
import android.graphics.Rect;
@@ -25,16 +8,36 @@
258
import android.text.Html;
269
import android.text.Spanned;
2710
import android.text.TextUtils;
11+
import android.text.util.Linkify;
2812
import android.util.Log;
2913

3014
import com.j256.ormlite.dao.RuntimeExceptionDao;
3115
import com.j256.ormlite.field.DatabaseField;
3216
import com.j256.ormlite.misc.TransactionManager;
3317
import com.j256.ormlite.stmt.DeleteBuilder;
3418
import com.j256.ormlite.table.DatabaseTable;
19+
import com.zulip.android.ZulipApp;
3520
import com.zulip.android.util.CustomHtmlToSpannedConverter;
3621
import com.zulip.android.util.ZLog;
37-
import com.zulip.android.ZulipApp;
22+
23+
import org.apache.commons.lang.builder.EqualsBuilder;
24+
import org.apache.commons.lang.builder.HashCodeBuilder;
25+
import org.ccil.cowan.tagsoup.HTMLSchema;
26+
import org.ccil.cowan.tagsoup.Parser;
27+
import org.json.JSONArray;
28+
import org.json.JSONException;
29+
import org.json.JSONObject;
30+
31+
import java.io.IOException;
32+
import java.sql.SQLException;
33+
import java.util.ArrayList;
34+
import java.util.Arrays;
35+
import java.util.Date;
36+
import java.util.List;
37+
import java.util.Map;
38+
import java.util.concurrent.Callable;
39+
40+
import static com.zulip.android.util.CustomHtmlToSpannedConverter.linkifySpanned;
3841

3942
@DatabaseTable(tableName = "messages")
4043
public class Message {
@@ -531,7 +534,8 @@ public Drawable getDrawable(String source) {
531534

532535
CustomHtmlToSpannedConverter converter = new CustomHtmlToSpannedConverter(
533536
source, null, null, parser, emojiGetter, app.getServerURI());
534-
return converter.convert();
537+
538+
return linkifySpanned(converter.convert(), Linkify.ALL);
535539
}
536540

537541
}

app/src/main/java/com/zulip/android/util/CustomHtmlToSpannedConverter.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import android.graphics.Paint;
2323
import android.graphics.Typeface;
2424
import android.graphics.drawable.Drawable;
25+
import android.support.annotation.NonNull;
2526
import android.text.Html;
2627
import android.text.Layout;
2728
import android.text.Spannable;
@@ -40,6 +41,8 @@
4041
import android.text.style.TypefaceSpan;
4142
import android.text.style.URLSpan;
4243
import android.text.style.UnderlineSpan;
44+
import android.text.util.Linkify;
45+
import android.util.Pair;
4346

4447
import org.ccil.cowan.tagsoup.Parser;
4548
import org.xml.sax.Attributes;
@@ -51,7 +54,9 @@
5154

5255
import java.io.IOException;
5356
import java.io.StringReader;
57+
import java.util.ArrayList;
5458
import java.util.HashMap;
59+
import java.util.List;
5560

5661
public class CustomHtmlToSpannedConverter implements ContentHandler {
5762

@@ -687,4 +692,31 @@ private static int convertValueToInt(CharSequence charSeq,
687692

688693
return Integer.parseInt(nm.substring(index), base) * sign;
689694
}
695+
696+
/**
697+
* Parses Spanned text for existing html links and reapplies them.
698+
* @see <a href="https://developer.android.com/reference/android/text/util/Linkify.html">Linkify</a>
699+
*
700+
* @param spann
701+
* @param mask bitmask to define which kinds of links will be searched and applied (e.g. <a href="https://developer.android.com/reference/android/text/util/Linkify.html#ALL">Linkify.ALL</a>)
702+
* @return
703+
*/
704+
public static Spanned linkifySpanned(@NonNull final Spanned spann, final int mask) {
705+
URLSpan[] existingSpans = spann.getSpans(0, spann.length(), URLSpan.class);
706+
List<Pair<Integer, Integer>> links = new ArrayList<>();
707+
708+
for (URLSpan urlSpan : existingSpans) {
709+
links.add(new Pair<>(spann.getSpanStart(urlSpan), spann.getSpanEnd(urlSpan)));
710+
}
711+
712+
Linkify.addLinks((Spannable) spann, mask);
713+
714+
// add the links back in
715+
for (int i = 0; i < existingSpans.length; i++) {
716+
((Spannable) spann).setSpan(existingSpans[i], links.get(i).first, links.get(i).second, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
717+
}
718+
719+
return spann;
720+
}
721+
690722
}

0 commit comments

Comments
 (0)