Hashtags are now also highlighted in the composer, similar to mentions.
This commit is contained in:
parent
f14973a6d4
commit
79b3d83368
1 changed files with 67 additions and 18 deletions
|
@ -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();
|
||||||
|
for (int i = fromIndex; i < length; i++) {
|
||||||
|
char c = string.charAt(i);
|
||||||
|
for (int j = 0; j < chars.length; j++) {
|
||||||
|
if (chars[j] == c) {
|
||||||
|
result.charIndex = j;
|
||||||
|
result.stringIndex = i;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FindCharsResult findStart(String string, int fromIndex, char[] chars) {
|
||||||
final int length = string.length();
|
final int length = string.length();
|
||||||
while (fromIndex < length) {
|
while (fromIndex < length) {
|
||||||
int at = string.indexOf('@', fromIndex);
|
FindCharsResult found = findChars(string, fromIndex, chars);
|
||||||
if (at < 0) {
|
int i = found.stringIndex;
|
||||||
|
if (i < 0) {
|
||||||
break;
|
break;
|
||||||
} else if (at == 0 || at >= 1 && Character.isWhitespace(string.codePointBefore(at))) {
|
} else if (i == 0 || i >= 1 && Character.isWhitespace(string.codePointBefore(i))) {
|
||||||
return at;
|
return found;
|
||||||
} else {
|
} else {
|
||||||
fromIndex = at + 1;
|
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;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
if (found.charIndex == 0) {
|
||||||
|
end = findEndOfHashtag(string, start);
|
||||||
|
} else if (found.charIndex == 1) {
|
||||||
end = findEndOfMention(string, start);
|
end = findEndOfMention(string, start);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
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);
|
||||||
|
|
Loading…
Reference in a new issue