mirror of
https://github.com/pierre42100/ComunicAndroid
synced 2024-11-23 13:59:29 +00:00
Parse URLs in conversation messages
This commit is contained in:
parent
5b46e559af
commit
50ccebfc91
@ -95,6 +95,16 @@ public class StringsUtils {
|
||||
return !TextUtils.isEmpty(mail) && Patterns.EMAIL_ADDRESS.matcher(mail).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a specified string is an URL or not
|
||||
*
|
||||
* @param string The string to check
|
||||
* @return TRUE if the string is an URL / FALSE else
|
||||
*/
|
||||
public static boolean isURL(CharSequence string){
|
||||
return !TextUtils.isEmpty(string) && Patterns.WEB_URL.matcher(string).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the SHA-1 summary of a given string
|
||||
*
|
||||
|
@ -15,6 +15,7 @@ import org.communiquons.android.comunic.client.data.models.ConversationMessage;
|
||||
import org.communiquons.android.comunic.client.data.models.UserInfo;
|
||||
import org.communiquons.android.comunic.client.data.utils.StringsUtils;
|
||||
import org.communiquons.android.comunic.client.ui.listeners.OnConversationMessageActionsListener;
|
||||
import org.communiquons.android.comunic.client.ui.views.ContentTextView;
|
||||
import org.communiquons.android.comunic.client.ui.views.EnlargeableWebImageView;
|
||||
import org.communiquons.android.comunic.client.ui.views.WebUserAccountImage;
|
||||
|
||||
@ -122,7 +123,7 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter {
|
||||
private class BaseMessageHolder extends RecyclerView.ViewHolder
|
||||
implements View.OnLongClickListener{
|
||||
|
||||
private TextView mMessage;
|
||||
ContentTextView mMessage;
|
||||
private TextView mSentDate;
|
||||
private EnlargeableWebImageView mImage;
|
||||
|
||||
@ -133,7 +134,7 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter {
|
||||
mImage = itemView.findViewById(R.id.messageImage);
|
||||
mSentDate = itemView.findViewById(R.id.text_message_time);
|
||||
|
||||
itemView.setOnLongClickListener(this);
|
||||
mMessage.setOnLongClickListener(this);
|
||||
mImage.setOnLongClickListener(this);
|
||||
}
|
||||
|
||||
@ -156,7 +157,7 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter {
|
||||
void bind(int pos){
|
||||
ConversationMessage message = mList.get(pos);
|
||||
|
||||
mMessage.setText(message.getContent());
|
||||
mMessage.setParsedText(message.getContent());
|
||||
mMessage.setVisibility(mMessage.getText().length() > 0 ? View.VISIBLE : View.GONE);
|
||||
|
||||
mImage.setVisibility(message.hasImage() ? View.VISIBLE : View.GONE);
|
||||
@ -193,6 +194,8 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter {
|
||||
|
||||
SentMessageHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
|
||||
mMessage.setLinksColor(R.color.conversation_user_links_color);
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,6 +212,8 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter {
|
||||
|
||||
mUserAccountImage = itemView.findViewById(R.id.account_image);
|
||||
mUserName = itemView.findViewById(R.id.user_name);
|
||||
|
||||
mMessage.setLinksColor(R.color.conversation_otheruser_links_color);
|
||||
}
|
||||
|
||||
void setUserInfoVisibility(boolean visible){
|
||||
|
@ -31,13 +31,23 @@ abstract class BaseFrameLayoutView extends FrameLayout {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get hosting activity
|
||||
*
|
||||
* @return Hosting activity, if found, null else
|
||||
*/
|
||||
protected Activity getActivity(){
|
||||
Context context = getContext();
|
||||
return GetActivityFromContext(getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an activity from context
|
||||
*
|
||||
* @param context The context to parse
|
||||
* @return The activity
|
||||
*/
|
||||
static Activity GetActivityFromContext(Context context){
|
||||
|
||||
while(context instanceof ContextWrapper){
|
||||
if(context instanceof Activity)
|
||||
|
@ -0,0 +1,126 @@
|
||||
package org.communiquons.android.comunic.client.ui.views;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import org.communiquons.android.comunic.client.data.utils.StringsUtils;
|
||||
import org.communiquons.android.comunic.client.ui.utils.UiUtils;
|
||||
|
||||
/**
|
||||
* TextView extension which parses the content passed to the
|
||||
* view in order to make links live
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
public class ContentTextView extends android.support.v7.widget.AppCompatTextView {
|
||||
|
||||
/**
|
||||
* Debug tag
|
||||
*/
|
||||
private static final String TAG = ContentTextView.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* The color of detected links
|
||||
*/
|
||||
private int mLinksColor = Color.BLUE;
|
||||
|
||||
public ContentTextView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ContentTextView(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ContentTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
|
||||
protected Activity getActivity(){
|
||||
return BaseFrameLayoutView.GetActivityFromContext(getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of selected links
|
||||
*
|
||||
* @param res_id The ID of the target color
|
||||
*/
|
||||
public void setLinksColor(int res_id){
|
||||
this.mLinksColor = UiUtils.getColor(getContext(), res_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set na new text, with links parsed
|
||||
*
|
||||
* @param text The text to parse
|
||||
*/
|
||||
public void setParsedText(String text) {
|
||||
super.setText(text);
|
||||
|
||||
//Parse text
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder(text);
|
||||
|
||||
String[] parts = text.split("\\s+");
|
||||
int pos = 0;
|
||||
for (String part : parts) {
|
||||
|
||||
//Mark it as URL
|
||||
if (StringsUtils.isURL(part)) {
|
||||
|
||||
ClickableSpan clickableSpan = new URLClickableSpan(part);
|
||||
ssb.setSpan(clickableSpan, pos, pos + part.length(),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
}
|
||||
|
||||
pos += part.length() + 1;
|
||||
|
||||
}
|
||||
|
||||
setText(ssb);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Base ClickableSpan class
|
||||
*/
|
||||
private abstract class BaseClickableSpan extends ClickableSpan {
|
||||
|
||||
@Override
|
||||
public void updateDrawState(TextPaint ds) {
|
||||
super.updateDrawState(ds);
|
||||
ds.setUnderlineText(false);
|
||||
ds.setColor(mLinksColor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clickable span class for URL
|
||||
*/
|
||||
private class URLClickableSpan extends BaseClickableSpan {
|
||||
|
||||
private String mURL;
|
||||
|
||||
private URLClickableSpan(String url){
|
||||
super();
|
||||
mURL = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View widget) {
|
||||
getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(mURL)));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
@ -39,7 +38,7 @@
|
||||
app:layout_constraintTop_toTopOf="@id/account_image"
|
||||
tools:text="John Doe" />
|
||||
|
||||
<TextView
|
||||
<org.communiquons.android.comunic.client.ui.views.ContentTextView
|
||||
android:id="@+id/message_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@ -62,12 +61,12 @@
|
||||
android:layout_height="98dp"
|
||||
android:layout_marginStart="60dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:scaleType="fitStart"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/constraintLayout2"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
app:srcCompat="@drawable/img_placeholder"
|
||||
android:scaleType="fitStart"/>
|
||||
app:srcCompat="@drawable/img_placeholder" />
|
||||
|
||||
|
||||
<TextView
|
||||
|
@ -1,18 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="16dp">
|
||||
|
||||
<TextView
|
||||
<org.communiquons.android.comunic.client.ui.views.ContentTextView
|
||||
android:id="@+id/message_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@drawable/conversation_message_currentuser_bg"
|
||||
android:maxWidth="240dp"
|
||||
android:padding="8dp"
|
||||
@ -45,10 +44,10 @@
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="@dimen/conversation_message_time_padding_top"
|
||||
android:text="11:40"
|
||||
android:textSize="10sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="11:40" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
@ -22,8 +22,10 @@
|
||||
<!-- Conversation messages -->
|
||||
<color name="conversation_user_messages_background">#3F51B5</color>
|
||||
<color name="conversation_user_messages_textColor">#FFFFFF</color>
|
||||
<color name="conversation_user_links_color">#c5cae9</color>
|
||||
<color name="conversation_otheruser_messages_background">#D8D8D8</color>
|
||||
<color name="conversation_otheruser_messages_textColor">#000000</color>
|
||||
<color name="conversation_otheruser_links_color">@color/conversation_user_messages_background</color>
|
||||
|
||||
<!-- Conversations footer -->
|
||||
<color name="conversation_footer_bg">#8c9eff</color>
|
||||
|
Loading…
Reference in New Issue
Block a user