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

Commit 2d4006e

Browse files
Sam1301kunall17
authored andcommitted
Add clickable spans for #stream-name.
1 parent 1c0b924 commit 2d4006e

File tree

3 files changed

+92
-6
lines changed

3 files changed

+92
-6
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import android.database.MergeCursor;
2222
import android.graphics.Bitmap;
2323
import android.graphics.PorterDuff;
24-
import android.graphics.Rect;
2524
import android.graphics.drawable.Drawable;
2625
import android.net.Uri;
2726
import android.os.Build;
@@ -52,13 +51,11 @@
5251
import android.text.TextWatcher;
5352
import android.util.Log;
5453
import android.util.TypedValue;
55-
import android.view.Gravity;
5654
import android.view.Menu;
5755
import android.view.MenuItem;
5856
import android.view.View;
5957
import android.view.ViewPropertyAnimator;
6058
import android.view.WindowManager;
61-
import android.view.Window;
6259
import android.view.animation.Interpolator;
6360
import android.view.inputmethod.InputMethodManager;
6461
import android.widget.AdapterView;
@@ -1301,7 +1298,7 @@ public void onClick(View v) {
13011298
*
13021299
* @param streamName stream name
13031300
*/
1304-
private void doNarrowToLastRead(String streamName) {
1301+
public void doNarrowToLastRead(String streamName) {
13051302
// get last message read in stream
13061303
Message message = Stream.getLastMessageRead(app, streamName);
13071304
if (message != null) {

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

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import com.zulip.android.R;
5555
import com.zulip.android.ZulipApp;
5656
import com.zulip.android.models.Person;
57+
import com.zulip.android.models.Stream;
5758

5859
import org.ccil.cowan.tagsoup.Parser;
5960
import org.xml.sax.Attributes;
@@ -87,6 +88,7 @@ public class CustomHtmlToSpannedConverter implements ContentHandler {
8788
private Html.ImageGetter mEmojiGetter;
8889
private String mBaseUri;
8990
private boolean isCode;
91+
private boolean isStreamLink;
9092

9193
public CustomHtmlToSpannedConverter(String source,
9294
Html.ImageGetter imageGetter, Html.TagHandler tagHandler,
@@ -271,6 +273,30 @@ private static void endSpan(SpannableStringBuilder text) {
271273
}
272274
}
273275

276+
private static void startStreamA(SpannableStringBuilder text, Attributes attributes) {
277+
/**
278+
example: <a class="stream" data-stream-id="4" href="/#narrow/stream/android">#android</a>
279+
*/
280+
String streamId = attributes.getValue("data-stream-id");
281+
282+
int len = text.length();
283+
text.setSpan(new Href(streamId), len, len, Spannable.SPAN_MARK_MARK);
284+
}
285+
286+
private static void endStreamA(SpannableStringBuilder text) {
287+
int len = text.length();
288+
Object obj = getLast(text, Href.class);
289+
int where = text.getSpanStart(obj);
290+
text.removeSpan(obj);
291+
if (where != len) {
292+
Href h = (Href) obj;
293+
if (h != null && h.mHref != null) {
294+
text.setSpan(new StreamSpan(h.mHref, 0xFF0088cc), where, len,
295+
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
296+
}
297+
}
298+
}
299+
274300
private static void startA(SpannableStringBuilder text,
275301
Attributes attributes, String baseUri) {
276302
String href = attributes.getValue("", "href");
@@ -515,7 +541,12 @@ private void handleStartTag(String tag, Attributes attributes) {
515541
} else if (tag.equalsIgnoreCase("tt")) {
516542
start(mSpannableStringBuilder, new Monospace());
517543
} else if (tag.equalsIgnoreCase("a")) {
518-
startA(mSpannableStringBuilder, attributes, mBaseUri);
544+
if ("stream".equalsIgnoreCase(attributes.getValue("class"))) {
545+
startStreamA(mSpannableStringBuilder, attributes);
546+
isStreamLink = true;
547+
} else {
548+
startA(mSpannableStringBuilder, attributes, mBaseUri);
549+
}
519550
} else if (tag.equalsIgnoreCase("span")
520551
&& "user-mention".equals(attributes.getValue("class"))) {
521552
startSpan(mSpannableStringBuilder, attributes);
@@ -594,7 +625,12 @@ private void handleEndTag(String tag) {
594625
end(mSpannableStringBuilder, Monospace.class, new TypefaceSpan(
595626
MONOSPACE));
596627
} else if (tag.equalsIgnoreCase("a")) {
597-
endA(mSpannableStringBuilder);
628+
if (isStreamLink) {
629+
endStreamA(mSpannableStringBuilder);
630+
isStreamLink = true;
631+
} else {
632+
endA(mSpannableStringBuilder);
633+
}
598634
} else if (tag.equalsIgnoreCase("span")) {
599635
endSpan(mSpannableStringBuilder);
600636
} else if (tag.equalsIgnoreCase("u")) {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.zulip.android.util;
2+
3+
import android.content.Context;
4+
import android.text.TextPaint;
5+
import android.text.style.ClickableSpan;
6+
import android.view.View;
7+
8+
import com.zulip.android.ZulipApp;
9+
import com.zulip.android.models.Stream;
10+
11+
/**
12+
* Custom ClickableSpan to support #stream-name click. The user is taken to the last message read
13+
* in the stream.
14+
*/
15+
16+
public class StreamSpan extends ClickableSpan {
17+
private String streamId;
18+
private int color;
19+
20+
public StreamSpan(String streamId, int color) {
21+
this.streamId = streamId;
22+
this.color = color;
23+
}
24+
25+
/**
26+
* Performs the click action associated with this span.
27+
*/
28+
@Override
29+
public void onClick(View widget) {
30+
Context context = widget.getContext().getApplicationContext();
31+
32+
// get stream name from streamId string
33+
String streamName = null;
34+
if (streamId != null) {
35+
Stream stream = Stream.getById(ZulipApp.get(), Integer.parseInt(streamId));
36+
if (stream != null) {
37+
streamName = stream.getName();
38+
}
39+
}
40+
41+
// go to last message read in the stream
42+
(((ZulipApp) context).getZulipActivity()).doNarrowToLastRead(streamName);
43+
}
44+
45+
/**
46+
* Makes the text underlined and in the link color.
47+
*/
48+
@Override
49+
public void updateDrawState(TextPaint ds) {
50+
ds.setColor(this.color);
51+
ds.setUnderlineText(false);
52+
}
53+
}

0 commit comments

Comments
 (0)