Commit 1c2e9e44 authored by Leonardo Aramaki's avatar Leonardo Aramaki

Implement new UX to messages reply

parent 2ecf4674
...@@ -37,7 +37,7 @@ public interface RoomContract { ...@@ -37,7 +37,7 @@ public interface RoomContract {
void manualLoadImages(); void manualLoadImages();
void onReply(String message); void onReply(String markdown, Message message);
void onCopy(String message); void onCopy(String message);
......
...@@ -649,8 +649,8 @@ public class RoomFragment extends AbstractChatRoomFragment implements ...@@ -649,8 +649,8 @@ public class RoomFragment extends AbstractChatRoomFragment implements
} }
@Override @Override
public void onReply(String message) { public void onReply(String markdown, Message message) {
messageFormManager.setEditMessage(message); messageFormManager.setReply(markdown, message);
} }
@Override @Override
...@@ -665,11 +665,11 @@ public class RoomFragment extends AbstractChatRoomFragment implements ...@@ -665,11 +665,11 @@ public class RoomFragment extends AbstractChatRoomFragment implements
public void showMessageActions(Message message) { public void showMessageActions(Message message) {
Activity context = getActivity(); Activity context = getActivity();
if (context != null && context instanceof MainActivity) { if (context != null && context instanceof MainActivity) {
MessagePopup.with(message) MessagePopup.take(message)
.setReplyAction(presenter::replyMessage) .setReplyAction(presenter::replyMessage)
.setEditAction(this::onEditMessage) .setEditAction(this::onEditMessage)
.setCopyAction(msg -> onCopy(message.getMessage())) .setCopyAction(msg -> onCopy(message.getMessage()))
.show(context); .showWith(context);
} }
} }
......
...@@ -127,13 +127,13 @@ public class RoomPresenter extends BasePresenter<RoomContract.View> ...@@ -127,13 +127,13 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
public void replyMessage(Message message) { public void replyMessage(Message message) {
this.absoluteUrlHelper.getRocketChatAbsoluteUrl() this.absoluteUrlHelper.getRocketChatAbsoluteUrl()
.cache() .cache()
.observeOn(Schedulers.io()) .subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.subscribeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe( .subscribe(
serverUrl -> { serverUrl -> {
if (serverUrl.isPresent()) { if (serverUrl.isPresent()) {
String baseUrl = serverUrl.get().getBaseUrl(); String baseUrl = serverUrl.get().getBaseUrl();
view.onReply(buildReplyMessage(baseUrl, message)); view.onReply(buildReplyMarkDown(baseUrl, message), message);
} }
}, },
Logger::report Logger::report
...@@ -145,7 +145,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View> ...@@ -145,7 +145,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
view.onCopy(message.getMessage()); view.onCopy(message.getMessage());
} }
private String buildReplyMessage(String baseUrl, Message message) { private String buildReplyMarkDown(String baseUrl, Message message) {
if (currentRoom == null || message.getUser() == null) { if (currentRoom == null || message.getUser() == null) {
return ""; return "";
} }
......
package chat.rocket.android.layouthelper.chatroom package chat.rocket.android.layouthelper.chatroom
import android.view.View
import chat.rocket.android.widget.message.MessageFormLayout import chat.rocket.android.widget.message.MessageFormLayout
import chat.rocket.core.models.Message
class MessageFormManager(private val messageFormLayout: MessageFormLayout, val callback: MessageFormLayout.ExtraActionSelectionClickListener) { class MessageFormManager(private val messageFormLayout: MessageFormLayout, val callback: MessageFormLayout.ExtraActionSelectionClickListener) {
private var sendMessageCallback: SendMessageCallback? = null private var sendMessageCallback: SendMessageCallback? = null
private var replyMarkDown: String = ""
init { init {
messageFormLayout.setExtraActionSelectionClickListener(callback) messageFormLayout.setExtraActionSelectionClickListener(callback)
...@@ -31,8 +34,19 @@ class MessageFormManager(private val messageFormLayout: MessageFormLayout, val c ...@@ -31,8 +34,19 @@ class MessageFormManager(private val messageFormLayout: MessageFormLayout, val c
messageFormLayout.isEnabled = enable messageFormLayout.isEnabled = enable
} }
fun setReply(replyMarkDown: String, message: Message) {
this.replyMarkDown = replyMarkDown
messageFormLayout.setReplyContent(message)
messageFormLayout.setReplyCancelListener({
this.replyMarkDown = ""
messageFormLayout.clearReplyContent()
})
}
private fun sendMessage(message: String) { private fun sendMessage(message: String) {
sendMessageCallback?.onSubmitText(message) val finalMessage = if (replyMarkDown.isNotEmpty()) "$replyMarkDown $message" else message
replyMarkDown = ""
sendMessageCallback?.onSubmitText(finalMessage)
} }
interface SendMessageCallback { interface SendMessageCallback {
......
...@@ -112,7 +112,7 @@ public class MessagePopup { ...@@ -112,7 +112,7 @@ public class MessagePopup {
singleton.defaultActions.add(COPY_ACTION_INFO); singleton.defaultActions.add(COPY_ACTION_INFO);
} }
public static MessagePopup with(Message message) { public static MessagePopup take(Message message) {
if (singleton == null) { if (singleton == null) {
synchronized (MessagePopup.class) { synchronized (MessagePopup.class) {
if (singleton == null) { if (singleton == null) {
...@@ -163,7 +163,7 @@ public class MessagePopup { ...@@ -163,7 +163,7 @@ public class MessagePopup {
return singleton; return singleton;
} }
public void show(Context context) { public void showWith(Context context) {
showAvailableActionsOnly(context); showAvailableActionsOnly(context);
} }
......
...@@ -4,6 +4,7 @@ import android.annotation.TargetApi; ...@@ -4,6 +4,7 @@ import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v13.view.inputmethod.InputContentInfoCompat; import android.support.v13.view.inputmethod.InputContentInfoCompat;
import android.text.Editable; import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
...@@ -15,10 +16,14 @@ import android.view.ViewGroup; ...@@ -15,10 +16,14 @@ import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import chat.rocket.android.widget.R; import chat.rocket.android.widget.R;
import chat.rocket.android.widget.helper.DebouncingOnClickListener; import chat.rocket.android.widget.helper.DebouncingOnClickListener;
import chat.rocket.core.models.Message;
public class MessageFormLayout extends LinearLayout { public class MessageFormLayout extends LinearLayout {
...@@ -27,6 +32,11 @@ public class MessageFormLayout extends LinearLayout { ...@@ -27,6 +32,11 @@ public class MessageFormLayout extends LinearLayout {
private ImageButton attachButton; private ImageButton attachButton;
private ImageButton sendButton; private ImageButton sendButton;
private RelativeLayout replyBar;
private ImageView replyCancelButton;
private TextView replyMessageText;
private TextView replyUsernameText;
private ExtraActionSelectionClickListener extraActionSelectionClickListener; private ExtraActionSelectionClickListener extraActionSelectionClickListener;
private SubmitTextListener submitTextListener; private SubmitTextListener submitTextListener;
private ImageKeyboardEditText.OnCommitContentListener listener; private ImageKeyboardEditText.OnCommitContentListener listener;
...@@ -65,6 +75,11 @@ public class MessageFormLayout extends LinearLayout { ...@@ -65,6 +75,11 @@ public class MessageFormLayout extends LinearLayout {
} }
}); });
replyCancelButton = composer.findViewById(R.id.reply_cancel);
replyMessageText = composer.findViewById(R.id.reply_message);
replyUsernameText = composer.findViewById(R.id.reply_username);
replyBar = composer.findViewById(R.id.reply_bar);
sendButton = composer.findViewById(R.id.button_send); sendButton = composer.findViewById(R.id.button_send);
sendButton.setOnClickListener(new DebouncingOnClickListener() { sendButton.setOnClickListener(new DebouncingOnClickListener() {
...@@ -73,6 +88,7 @@ public class MessageFormLayout extends LinearLayout { ...@@ -73,6 +88,7 @@ public class MessageFormLayout extends LinearLayout {
String messageText = getText(); String messageText = getText();
if (messageText.length() > 0 && submitTextListener != null) { if (messageText.length() > 0 && submitTextListener != null) {
submitTextListener.onSubmitText(messageText); submitTextListener.onSubmitText(messageText);
clearReplyContent();
} }
} }
}); });
...@@ -118,6 +134,16 @@ public class MessageFormLayout extends LinearLayout { ...@@ -118,6 +134,16 @@ public class MessageFormLayout extends LinearLayout {
addView(composer); addView(composer);
} }
public void clearReplyContent() {
replyBar.setVisibility(View.GONE);
replyMessageText.setText("");
replyUsernameText.setText("");
}
public void setReplyCancelListener(OnClickListener onClickListener) {
replyCancelButton.setOnClickListener(onClickListener);
}
public EditText getEditText() { public EditText getEditText() {
return (EditText) composer.findViewById(R.id.editor); return (EditText) composer.findViewById(R.id.editor);
} }
...@@ -154,10 +180,7 @@ public class MessageFormLayout extends LinearLayout { ...@@ -154,10 +180,7 @@ public class MessageFormLayout extends LinearLayout {
if (text.length() > 0) { if (text.length() > 0) {
editor.setSelection(text.length()); editor.setSelection(text.length());
InputMethodManager inputMethodManager = (InputMethodManager) editor.getContext() requestFocusAndShowKeyboard();
.getSystemService(Context.INPUT_METHOD_SERVICE);
editor.requestFocus();
inputMethodManager.showSoftInput(editor, 0);
} }
} }
}); });
...@@ -173,6 +196,29 @@ public class MessageFormLayout extends LinearLayout { ...@@ -173,6 +196,29 @@ public class MessageFormLayout extends LinearLayout {
this.listener = listener; this.listener = listener;
} }
public void setReplyContent(@NonNull Message message) {
String text = message.getMessage();
if (!TextUtils.isEmpty(text)) {
replyMessageText.setText(text);
replyUsernameText.setText(message.getUser().getUsername());
replyBar.setVisibility(View.VISIBLE);
requestFocusAndShowKeyboard();
}
}
private void requestFocusAndShowKeyboard() {
final EditText editor = getEditor();
editor.post(new Runnable() {
@Override
public void run() {
InputMethodManager inputMethodManager = (InputMethodManager) editor.getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
editor.requestFocus();
inputMethodManager.showSoftInput(editor, 0);
}
});
}
private void animateHide(final View view) { private void animateHide(final View view) {
view.animate().scaleX(0).scaleY(0).setDuration(150).withEndAction(new Runnable() { view.animate().scaleX(0).scaleY(0).setDuration(150).withEndAction(new Runnable() {
@Override @Override
......
<!-- drawable/close.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
</vector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?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:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="48dp" android:background="@drawable/top_shadow"
android:background="@drawable/top_shadow" android:minHeight="48dp"
tools:context="chat.rocket.android.widget.message.MessageFormLayout"> tools:context="chat.rocket.android.widget.message.MessageFormLayout">
<chat.rocket.android.widget.message.ImageKeyboardEditText <RelativeLayout
android:id="@+id/editor" android:id="@+id/reply_bar"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="16dp" android:layout_marginBottom="8dp"
android:layout_marginStart="16dp" android:layout_marginEnd="16dp"
android:inputType="textCapSentences|textMultiLine" android:layout_marginLeft="16dp"
android:hint="@string/message_composer_message_hint" android:layout_marginRight="16dp"
android:textSize="14sp" android:layout_marginStart="16dp"
android:minLines="1" android:layout_marginTop="8dp"
android:maxLines="4" android:visibility="gone"
android:background="@null" app:layout_constraintBottom_toTopOf="@+id/keyboard_container"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintRight_toLeftOf="@+id/container" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/> tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp"
<FrameLayout tools:visibility="visible">
android:id="@+id/container"
android:layout_width="wrap_content" <android.support.v7.widget.AppCompatImageView
android:layout_height="wrap_content" android:id="@+id/reply_cancel"
android:layout_marginLeft="16dp" android:layout_width="24dp"
android:layout_marginStart="16dp" android:layout_height="24dp"
android:layout_marginRight="16dp" android:layout_centerVertical="true"
android:layout_marginEnd="16dp" android:layout_alignParentEnd="true"
app:layout_constraintTop_toTopOf="@+id/editor" android:layout_alignParentRight="true"
app:layout_constraintRight_toRightOf="parent" android:adjustViewBounds="true"
app:layout_constraintLeft_toRightOf="@+id/editor" app:srcCompat="@drawable/ic_close"
app:layout_constraintBottom_toBottomOf="@+id/editor"> app:tint="@color/color_icon_composer" />
<ImageButton <TextView
android:id="@+id/button_attach" android:id="@+id/reply_username"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:tint="@color/color_icon_composer" android:layout_alignBaseline="@id/reply_username"
app:srcCompat="@drawable/ic_attach_file_black_24dp" android:layout_toLeftOf="@+id/reply_cancel"
android:background="?attr/selectableItemBackgroundBorderless"/> android:layout_toStartOf="@id/reply_cancel"
android:ellipsize="end"
<ImageButton android:maxLines="1"
android:id="@+id/button_send" android:textColor="@color/color_accent"
android:layout_width="wrap_content" android:textStyle="bold"
android:layout_height="wrap_content" tools:text="jane.doe" />
android:tint="@color/color_accent"
app:srcCompat="@drawable/ic_send_black_24dp" <TextView
android:background="?attr/selectableItemBackgroundBorderless"/> android:id="@+id/reply_message"
</FrameLayout> android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/reply_username"
android:layout_toLeftOf="@+id/reply_cancel"
android:layout_toStartOf="@id/reply_cancel"
android:ellipsize="end"
android:maxLines="1"
tools:text="Mensagemaaaaaaaaaaaaaaaaaddddddddddddddddddddddddddddddddsdsdsdsdsdsdsdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" />
</RelativeLayout>
<android.support.constraint.ConstraintLayout
android:id="@+id/keyboard_container"
android:layout_width="0dp"
android:layout_height="48dp"
android:background="@drawable/top_shadow"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/reply_bar">
<chat.rocket.android.widget.message.ImageKeyboardEditText
android:id="@+id/editor"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:background="@null"
android:hint="@string/message_composer_message_hint"
android:inputType="textCapSentences|textMultiLine"
android:maxLines="4"
android:minLines="1"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/container"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="@+id/editor"
app:layout_constraintLeft_toRightOf="@+id/editor"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/editor">
<ImageButton
android:id="@+id/button_attach"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:tint="@color/color_icon_composer"
app:srcCompat="@drawable/ic_attach_file_black_24dp" />
<ImageButton
android:id="@+id/button_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:tint="@color/color_accent"
app:srcCompat="@drawable/ic_send_black_24dp" />
</FrameLayout>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment