mirror of
https://github.com/nextcloud/talk-android
synced 2025-03-12 10:32:36 +00:00
Merge pull request #493 from nextcloud/improve-mentions
Improve mentions
This commit is contained in:
commit
364480ccf4
@ -143,8 +143,7 @@ public class MagicIncomingTextMessageViewHolder
|
|||||||
.nc_incoming_text_mention_others);
|
.nc_incoming_text_mention_others);
|
||||||
}
|
}
|
||||||
|
|
||||||
messageString = DisplayUtils.searchAndColor(messageText.getText().toString(),
|
messageString = DisplayUtils.searchAndColor(message.getText(), "@" + individualHashMap.get("name"), color);
|
||||||
messageString, "@" + individualHashMap.get("name"), color);
|
|
||||||
} else if (individualHashMap.get("type").equals("file")) {
|
} else if (individualHashMap.get("type").equals("file")) {
|
||||||
itemView.setOnClickListener(v -> {
|
itemView.setOnClickListener(v -> {
|
||||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(individualHashMap.get("link")));
|
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(individualHashMap.get("link")));
|
||||||
|
@ -90,8 +90,9 @@ public class MagicOutcomingTextMessageViewHolder extends MessageHolders.Outcomin
|
|||||||
Map<String, String> individualHashMap = message.getMessageParameters().get(key);
|
Map<String, String> individualHashMap = message.getMessageParameters().get(key);
|
||||||
if (individualHashMap.get("type").equals("user") || individualHashMap.get("type").equals("guest")) {
|
if (individualHashMap.get("type").equals("user") || individualHashMap.get("type").equals("guest")) {
|
||||||
if (!individualHashMap.get("id").equals(message.getActiveUserId())) {
|
if (!individualHashMap.get("id").equals(message.getActiveUserId())) {
|
||||||
messageString = DisplayUtils.searchAndColor(messageText.getText().toString(),
|
messageString =
|
||||||
messageString, "@" + individualHashMap.get("name"), NextcloudTalkApplication
|
DisplayUtils.searchAndColor(message.getText(),
|
||||||
|
"@" + individualHashMap.get("name"), NextcloudTalkApplication
|
||||||
.getSharedApplication().getResources().getColor(R.color.nc_outcoming_text_default));
|
.getSharedApplication().getResources().getColor(R.color.nc_outcoming_text_default));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +67,8 @@ public class MagicSystemMessageViewHolder extends MessageHolders.IncomingTextMes
|
|||||||
color = context.getResources().getColor(R.color.nc_incoming_text_mention_others);
|
color = context.getResources().getColor(R.color.nc_incoming_text_mention_others);
|
||||||
}
|
}
|
||||||
|
|
||||||
messageString = DisplayUtils.searchAndColor(message.getText(),
|
messageString =
|
||||||
messageString, "@" + individualHashMap.get("name"), color);
|
DisplayUtils.searchAndColor(message.getText(), "@" + individualHashMap.get("name"), color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,12 @@
|
|||||||
|
|
||||||
package com.nextcloud.talk.callbacks;
|
package com.nextcloud.talk.callbacks;
|
||||||
|
|
||||||
|
import android.graphics.Typeface;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.text.Spanned;
|
||||||
import com.nextcloud.talk.models.json.mention.Mention;
|
import com.nextcloud.talk.models.json.mention.Mention;
|
||||||
import com.nextcloud.talk.utils.MagicCharPolicy;
|
import com.nextcloud.talk.utils.MagicCharPolicy;
|
||||||
|
import com.nextcloud.talk.utils.text.Spans;
|
||||||
import com.otaliastudios.autocomplete.AutocompleteCallback;
|
import com.otaliastudios.autocomplete.AutocompleteCallback;
|
||||||
|
|
||||||
public class MentionAutocompleteCallback implements AutocompleteCallback<Mention> {
|
public class MentionAutocompleteCallback implements AutocompleteCallback<Mention> {
|
||||||
@ -30,10 +33,12 @@ public class MentionAutocompleteCallback implements AutocompleteCallback<Mention
|
|||||||
public boolean onPopupItemClicked(Editable editable, Mention item) {
|
public boolean onPopupItemClicked(Editable editable, Mention item) {
|
||||||
int[] range = MagicCharPolicy.getQueryRange(editable);
|
int[] range = MagicCharPolicy.getQueryRange(editable);
|
||||||
if (range == null) return false;
|
if (range == null) return false;
|
||||||
int start = range[0] + 1;
|
int start = range[0];
|
||||||
int end = range[1];
|
int end = range[1];
|
||||||
String replacement = item.getId() + " ";
|
String replacement = item.getLabel();
|
||||||
editable.replace(start, end, replacement);
|
editable.replace(start, end, replacement + " ");
|
||||||
|
Spans.MentionSpan mentionSpan = new Spans.MentionSpan(Typeface.BOLD, item.getId(), item.getLabel());
|
||||||
|
editable.setSpan(mentionSpan, start, start + item.getLabel().length() , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ import com.nextcloud.talk.utils.bundle.BundleKeys;
|
|||||||
import com.nextcloud.talk.utils.database.user.UserUtils;
|
import com.nextcloud.talk.utils.database.user.UserUtils;
|
||||||
import com.nextcloud.talk.utils.preferences.AppPreferences;
|
import com.nextcloud.talk.utils.preferences.AppPreferences;
|
||||||
import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder;
|
import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder;
|
||||||
|
import com.nextcloud.talk.utils.text.Spans;
|
||||||
import com.otaliastudios.autocomplete.Autocomplete;
|
import com.otaliastudios.autocomplete.Autocomplete;
|
||||||
import com.otaliastudios.autocomplete.AutocompleteCallback;
|
import com.otaliastudios.autocomplete.AutocompleteCallback;
|
||||||
import com.otaliastudios.autocomplete.AutocompletePresenter;
|
import com.otaliastudios.autocomplete.AutocompletePresenter;
|
||||||
@ -369,10 +370,23 @@ public class ChatController extends BaseController implements MessagesListAdapte
|
|||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
if (s.length() == 1000) {
|
if (s.length() == 1000) {
|
||||||
messageInput.setError(getResources().getString(R.string.nc_limit_hit));
|
messageInput.setError(Objects.requireNonNull(getResources()).getString(R.string.nc_limit_hit));
|
||||||
} else {
|
} else {
|
||||||
messageInput.setError(null);
|
messageInput.setError(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Editable editable = messageInput.getEditableText();
|
||||||
|
Spans.MentionSpan[] mentionSpans = editable.getSpans(0, messageInput.length(), Spans.MentionSpan.class);
|
||||||
|
Spans.MentionSpan mentionSpan;
|
||||||
|
for (int i = 0; i < mentionSpans.length; i++) {
|
||||||
|
mentionSpan = mentionSpans[i];
|
||||||
|
if (start >= editable.getSpanStart(mentionSpan) && start < editable.getSpanEnd(mentionSpan)) {
|
||||||
|
if (!editable.subSequence(editable.getSpanStart(mentionSpan),
|
||||||
|
editable.getSpanEnd(mentionSpan)).toString().trim().equals(mentionSpan.getLabel())) {
|
||||||
|
editable.removeSpan(mentionSpan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -381,11 +395,7 @@ public class ChatController extends BaseController implements MessagesListAdapte
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
messageInputView.setInputListener(input -> {
|
messageInputView.getButton().setOnClickListener(v -> submitMessage());
|
||||||
sendMessage(input);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
messageInputView.getButton().setContentDescription(getResources()
|
messageInputView.getButton().setContentDescription(getResources()
|
||||||
.getString(R.string.nc_description_send_message_button));
|
.getString(R.string.nc_description_send_message_button));
|
||||||
|
|
||||||
@ -664,6 +674,19 @@ public class ChatController extends BaseController implements MessagesListAdapte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void submitMessage() {
|
||||||
|
final Editable editable = messageInput.getEditableText();
|
||||||
|
Spans.MentionSpan mentionSpans[] = editable.getSpans(0, editable.length(), Spans.MentionSpan.class);
|
||||||
|
Spans.MentionSpan mentionSpan;
|
||||||
|
for (int i = 0; i < mentionSpans.length; i++) {
|
||||||
|
mentionSpan = mentionSpans[i];
|
||||||
|
editable.replace(editable.getSpanStart(mentionSpan), editable.getSpanEnd(mentionSpan), "@" + mentionSpan.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
messageInput.setText("");
|
||||||
|
sendMessage(editable);
|
||||||
|
}
|
||||||
|
|
||||||
private void sendMessage(CharSequence message) {
|
private void sendMessage(CharSequence message) {
|
||||||
|
|
||||||
ncApi.sendChatMessage(credentials, ApiUtils.getUrlForChat(conversationUser.getBaseUrl(), roomToken),
|
ncApi.sendChatMessage(credentials, ApiUtils.getUrlForChat(conversationUser.getBaseUrl(), roomToken),
|
||||||
|
@ -203,27 +203,34 @@ public class DisplayUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Spannable searchAndColor(String text, Spannable spannable, String searchText, @ColorInt int color) {
|
public static Spannable searchAndColor(String text, String searchText, @ColorInt int color) {
|
||||||
|
|
||||||
|
Spannable spannableString = new SpannableString(text);
|
||||||
|
|
||||||
if (TextUtils.isEmpty(text) || TextUtils.isEmpty(searchText)) {
|
if (TextUtils.isEmpty(text) || TextUtils.isEmpty(searchText)) {
|
||||||
return spannable;
|
return spannableString;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matcher m = Pattern.compile(searchText, Pattern.CASE_INSENSITIVE | Pattern.LITERAL)
|
Matcher m = Pattern.compile(searchText,
|
||||||
.matcher(text);
|
Pattern.CASE_INSENSITIVE | Pattern.LITERAL | Pattern.MULTILINE)
|
||||||
|
.matcher(spannableString);
|
||||||
|
|
||||||
|
|
||||||
int textSize = NextcloudTalkApplication.getSharedApplication().getResources().getDimensionPixelSize(R.dimen
|
int textSize = NextcloudTalkApplication.getSharedApplication().getResources().getDimensionPixelSize(R.dimen
|
||||||
.chat_text_size);
|
.chat_text_size);
|
||||||
|
|
||||||
|
int lastStartIndex = -1;
|
||||||
while (m.find()) {
|
while (m.find()) {
|
||||||
int start = text.indexOf(m.group());
|
int start = text.indexOf(m.group(), lastStartIndex);
|
||||||
int end = text.indexOf(m.group()) + m.group().length();
|
int end = start + m.group().length();
|
||||||
spannable.setSpan(new ForegroundColorSpan(color), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
lastStartIndex = end;
|
||||||
spannable.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
spannableString.setSpan(new ForegroundColorSpan(color), start, end,
|
||||||
spannable.setSpan(new AbsoluteSizeSpan(textSize), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
spannableString.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
spannableString.setSpan(new AbsoluteSizeSpan(textSize), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return spannable;
|
return spannableString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Drawable getMessageSelector(@ColorInt int normalColor, @ColorInt int selectedColor,
|
public static Drawable getMessageSelector(@ColorInt int normalColor, @ColorInt int selectedColor,
|
||||||
|
39
app/src/main/java/com/nextcloud/talk/utils/text/Spans.java
Normal file
39
app/src/main/java/com/nextcloud/talk/utils/text/Spans.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.utils.text;
|
||||||
|
|
||||||
|
import android.text.style.StyleSpan;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
public class Spans {
|
||||||
|
@Data
|
||||||
|
public static class MentionSpan extends StyleSpan {
|
||||||
|
String id;
|
||||||
|
String label;
|
||||||
|
|
||||||
|
public MentionSpan(int style, String id, String label) {
|
||||||
|
super(style);
|
||||||
|
this.id = id;
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user