Skip to content
This repository has been archived by the owner on Feb 16, 2024. It is now read-only.

Added Clickable Links to narrow for user! #100

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions app/src/main/java/com/zulip/android/ZulipApp.java
Expand Up @@ -24,6 +24,7 @@
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.RuntimeExceptionDao;
import com.j256.ormlite.misc.TransactionManager;
import com.zulip.android.activities.ZulipActivity;
import com.zulip.android.database.DatabaseHelper;
import com.zulip.android.models.Emoji;
import com.zulip.android.models.Message;
Expand Down Expand Up @@ -59,6 +60,15 @@ public class ZulipApp extends Application {
private DatabaseHelper databaseHelper;
private Set<String> mutedTopics;
private static final String MUTED_TOPIC_KEY = "mutedTopics";
private ZulipActivity zulipActivity;

public ZulipActivity getZulipActivity() {
return zulipActivity;
}

public void setZulipActivity(ZulipActivity zulipActivity) {
this.zulipActivity = zulipActivity;
}

/**
* Handler to manage batching of unread messages
Expand Down
Expand Up @@ -151,6 +151,7 @@ public class ZulipActivity extends AppCompatActivity implements
private SimpleCursorAdapter streamActvAdapter;
private SimpleCursorAdapter subjectActvAdapter;
private SimpleCursorAdapter emailActvAdapter;
private AppBarLayout appBarLayout;

private BroadcastReceiver onGcmMessage = new BroadcastReceiver() {
public void onReceive(Context contenxt, Intent intent) {
Expand Down Expand Up @@ -289,6 +290,8 @@ protected void onCreate(Bundle savedInstanceState) {
messageEt = (AutoCompleteTextView) findViewById(R.id.message_et);
textView = (TextView) findViewById(R.id.textView);
sendBtn = (ImageView) findViewById(R.id.send_btn);
appBarLayout = (AppBarLayout) findViewById(R.id.appBarLayout);
app.setZulipActivity(this);
togglePrivateStreamBtn = (ImageView) findViewById(R.id.togglePrivateStream_btn);
mutedTopics = new ArrayList<>();
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
Expand Down Expand Up @@ -1192,6 +1195,7 @@ public void doNarrow(NarrowFilter filter) {
// Push to the back stack if we are not already narrowed
pushListFragment(narrowedList, NARROW);
narrowedList.onReadyToDisplay(true);
showView(appBarLayout);
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/zulip/android/models/Message.java
Expand Up @@ -530,7 +530,7 @@ public Drawable getDrawable(String source) {
};

CustomHtmlToSpannedConverter converter = new CustomHtmlToSpannedConverter(
source, null, null, parser, emojiGetter, app.getServerURI());
source, null, null, parser, emojiGetter, app.getServerURI(), context);
return converter.convert();
}

Expand Down
7 changes: 6 additions & 1 deletion app/src/main/java/com/zulip/android/models/Person.java
Expand Up @@ -127,7 +127,7 @@ public int hashCode() {
.toHashCode();
}

private static Person getByEmail(ZulipApp app, String email) {
public static Person getByEmail(ZulipApp app, String email) {
try {
Dao<Person, Integer> dao = app.getDatabaseHelper().getDao(
Person.class);
Expand Down Expand Up @@ -206,6 +206,11 @@ public static Person getById(ZulipApp app, int id) {
return dao.queryForId(id);
}

public static List<Person> getAllPeople(ZulipApp app) throws SQLException {
RuntimeExceptionDao<Person, Object> dao = app.getDao(Person.class);
return dao.queryBuilder().where().eq(Person.ISBOT_FIELD, false).query();
}

public static void sortByPresence(ZulipApp app, List<Person> people) {
final Map<String, Presence> presenceCopy = new HashMap<>(
app.presences);
Expand Down
Expand Up @@ -16,12 +16,14 @@

package com.zulip.android.util;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.text.Html;
import android.text.Layout;
import android.text.Spannable;
Expand All @@ -41,6 +43,9 @@
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;

import com.zulip.android.R;
import com.zulip.android.ZulipApp;

import org.ccil.cowan.tagsoup.Parser;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
Expand All @@ -67,17 +72,20 @@ public class CustomHtmlToSpannedConverter implements ContentHandler {
private Html.TagHandler mTagHandler;
private Html.ImageGetter mEmojiGetter;
private String mBaseUri;

private static int userMentionColor;
private static int userMentionSelfColor;
public CustomHtmlToSpannedConverter(String source,
Html.ImageGetter imageGetter, Html.TagHandler tagHandler,
Parser parser, Html.ImageGetter emojiGetter, String baseUri) {
Parser parser, Html.ImageGetter emojiGetter, String baseUri, Context context) {
mSource = source;
mSpannableStringBuilder = new SpannableStringBuilder();
mImageGetter = imageGetter;
mTagHandler = tagHandler;
mReader = parser;
mEmojiGetter = emojiGetter;
mBaseUri = baseUri;
userMentionColor = ContextCompat.getColor(context, R.color.dark_red);
userMentionSelfColor = ContextCompat.getColor(context, R.color.dark_blue);
}

public Spanned convert() {
Expand Down Expand Up @@ -150,6 +158,9 @@ private void handleStartTag(String tag, Attributes attributes) {
start(mSpannableStringBuilder, new Monospace());
} else if (tag.equalsIgnoreCase("a")) {
startA(mSpannableStringBuilder, attributes, mBaseUri);
} else if (tag.equalsIgnoreCase("span")
&& attributes.getValue("class").equals("user-mention")) {
startSpan(mSpannableStringBuilder, attributes);
} else if (tag.equalsIgnoreCase("u")) {
start(mSpannableStringBuilder, new Underline());
} else if (tag.equalsIgnoreCase("sup")) {
Expand Down Expand Up @@ -247,6 +258,8 @@ private void handleEndTag(String tag) {
MONOSPACE));
} else if (tag.equalsIgnoreCase("a")) {
endA(mSpannableStringBuilder);
} else if (tag.equalsIgnoreCase("span")) {
endSpan(mSpannableStringBuilder);
} else if (tag.equalsIgnoreCase("u")) {
end(mSpannableStringBuilder, Underline.class, new UnderlineSpan());
} else if (tag.equalsIgnoreCase("sup")) {
Expand Down Expand Up @@ -408,6 +421,29 @@ private static void endFont(SpannableStringBuilder text) {
}
}

private static void startSpan(SpannableStringBuilder text, Attributes attributes) {
String email = attributes.getValue("data-user-email");
int len = text.length();
text.setSpan(new Href(email), len, len, Spannable.SPAN_MARK_MARK);
}

private static void endSpan(SpannableStringBuilder text) {
int len = text.length();
Object obj = getLast(text, Href.class);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
if (where != len) {
Href h = (Href) obj;
if (h != null && h.mHref != null) {
if (ZulipApp.get().getEmail().equals(h.mHref)) {
text.setSpan(new ForegroundColorSpan(userMentionSelfColor), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
text.setSpan(new ProfileSpan(h.mHref, userMentionColor), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
}

private static void startA(SpannableStringBuilder text,
Attributes attributes, String baseUri) {
String href = attributes.getValue("", "href");
Expand Down
49 changes: 49 additions & 0 deletions app/src/main/java/com/zulip/android/util/ProfileSpan.java
@@ -0,0 +1,49 @@
package com.zulip.android.util;

import android.content.Context;
import android.text.TextPaint;
import android.text.style.ClickableSpan;
import android.view.View;

import com.zulip.android.ZulipApp;
import com.zulip.android.filters.NarrowFilterPM;
import com.zulip.android.models.Person;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ProfileSpan extends ClickableSpan {
private String email;
private int userMentionColor;

public ProfileSpan(String email, int color) {
this.email = email;
userMentionColor = color;
}

@Override
public void onClick(View widget) {
Context context = widget.getContext().getApplicationContext();
List<Person> people = new ArrayList<Person>();
if (email.equals("*")) { //This is for "@all"
try {
people = Person.getAllPeople(ZulipApp.get());
} catch (SQLException e) {
ZLog.logException(e);
return;
}
} else {
for (String email : this.email.split(",")) {
people.add(Person.getByEmail(ZulipApp.get(), email));
}
people.add(ZulipApp.get().getYou());
}
(((ZulipApp) context).getZulipActivity()).doNarrow(new NarrowFilterPM(people));
}

@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(userMentionColor);
}
}
Expand Up @@ -2,6 +2,7 @@

import android.app.Activity;
import android.support.v7.widget.RecyclerView;
import android.text.method.LinkMovementMethod;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.View;
Expand Down Expand Up @@ -31,6 +32,7 @@ public MessageHolder(final View itemView) {
senderName = (TextView) itemView.findViewById(R.id.senderName);
timestamp = (TextView) itemView.findViewById(R.id.timestamp);
contentView = (TextView) itemView.findViewById(R.id.contentView);
contentView.setMovementMethod(LinkMovementMethod.getInstance());
leftBar = itemView.findViewById(R.id.leftBar);
messageTile = (RelativeLayout) itemView.findViewById(R.id.messageTile);
contentView.setOnClickListener(this);
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/colors.xml
Expand Up @@ -17,4 +17,6 @@
<color name="stream_background">#ffff</color>
<color name="loadingBackground">#eeeeee</color>
<color name="indigo_material_500">#3F51B5</color>
<color name="dark_red">#d14444</color>
<color name="dark_blue">#303F9F</color>
</resources>