Hashtags are now also highlighted in the composer, similar to mentions.

This commit is contained in:
Vavassor 2017-02-13 22:39:48 -05:00
parent f14973a6d4
commit 79b3d83368
1 changed files with 67 additions and 18 deletions

View File

@ -174,31 +174,72 @@ public class ComposeActivity extends AppCompatActivity {
Snackbar.make(findViewById(R.id.activity_compose), stringId, Snackbar.LENGTH_LONG).show(); Snackbar.make(findViewById(R.id.activity_compose), stringId, Snackbar.LENGTH_LONG).show();
} }
private static int findStartOfMention(String string, int fromIndex) { private static class FindCharsResult {
public int charIndex;
public int stringIndex;
public FindCharsResult() {
charIndex = -1;
stringIndex = -1;
}
}
private static FindCharsResult findChars(String string, int fromIndex, char[] chars) {
FindCharsResult result = new FindCharsResult();
final int length = string.length(); final int length = string.length();
while (fromIndex < length) { for (int i = fromIndex; i < length; i++) {
int at = string.indexOf('@', fromIndex); char c = string.charAt(i);
if (at < 0) { for (int j = 0; j < chars.length; j++) {
break; if (chars[j] == c) {
} else if (at == 0 || at >= 1 && Character.isWhitespace(string.codePointBefore(at))) { result.charIndex = j;
return at; result.stringIndex = i;
} else { return result;
fromIndex = at + 1; }
} }
} }
return -1; return result;
}
private static FindCharsResult findStart(String string, int fromIndex, char[] chars) {
final int length = string.length();
while (fromIndex < length) {
FindCharsResult found = findChars(string, fromIndex, chars);
int i = found.stringIndex;
if (i < 0) {
break;
} else if (i == 0 || i >= 1 && Character.isWhitespace(string.codePointBefore(i))) {
return found;
} else {
fromIndex = i + 1;
}
}
return new FindCharsResult();
}
private static int findEndOfHashtag(String string, int fromIndex) {
final int length = string.length();
for (int i = fromIndex + 1; i < length;) {
int codepoint = string.codePointAt(i);
if (Character.isWhitespace(codepoint)) {
return i;
} else if (codepoint == '#') {
return -1;
}
i += Character.charCount(codepoint);
}
return length;
} }
private static int findEndOfMention(String string, int fromIndex) { private static int findEndOfMention(String string, int fromIndex) {
int atCount = 0; int atCount = 0;
final int length = string.length(); final int length = string.length();
for (int i = fromIndex; i < length; ) { for (int i = fromIndex + 1; i < length;) {
int codepoint = string.codePointAt(i); int codepoint = string.codePointAt(i);
if (Character.isWhitespace(codepoint)) { if (Character.isWhitespace(codepoint)) {
return i; return i;
} else if (codepoint == '@') { } else if (codepoint == '@') {
atCount += 1; atCount += 1;
if (atCount > 2) { if (atCount >= 2) {
return -1; return -1;
} }
} }
@ -207,23 +248,31 @@ public class ComposeActivity extends AppCompatActivity {
return length; return length;
} }
private static void colourMentions(Spannable text, int colour) { private static void highlightSpans(Spannable text, int colour) {
// Strip all existing colour spans. // Strip all existing colour spans.
int n = text.length(); int n = text.length();
ForegroundColorSpan[] oldSpans = text.getSpans(0, n, ForegroundColorSpan.class); ForegroundColorSpan[] oldSpans = text.getSpans(0, n, ForegroundColorSpan.class);
for (int i = oldSpans.length - 1; i >= 0; i--) { for (int i = oldSpans.length - 1; i >= 0; i--) {
text.removeSpan(oldSpans[i]); text.removeSpan(oldSpans[i]);
} }
// Colour the mentions. // Colour the mentions and hashtags.
String string = text.toString(); String string = text.toString();
int start; int start;
int end = 0; int end = 0;
while (end < n) { while (end < n) {
start = findStartOfMention(string, end); char[] chars = { '#', '@' };
if (start < 0 || start >= n) { FindCharsResult found = findStart(string, end, chars);
start = found.stringIndex;
if (start < 0) {
break;
}
if (found.charIndex == 0) {
end = findEndOfHashtag(string, start);
} else if (found.charIndex == 1) {
end = findEndOfMention(string, start);
} else {
break; break;
} }
end = findEndOfMention(string, start);
if (end < 0) { if (end < 0) {
break; break;
} }
@ -264,7 +313,7 @@ public class ComposeActivity extends AppCompatActivity {
@Override @Override
public void afterTextChanged(Editable editable) { public void afterTextChanged(Editable editable) {
colourMentions(editable, mentionColour); highlightSpans(editable, mentionColour);
} }
}; };
textEditor.addTextChangedListener(textEditorWatcher); textEditor.addTextChangedListener(textEditorWatcher);