Replaced the regex gunk in the composer with something more readable and more reliable.
Also, put in a fix for a crash related to failing while loading the vector image for the media picker button.
This commit is contained in:
parent
22a2a31afe
commit
f14973a6d4
6 changed files with 54 additions and 46 deletions
|
@ -87,7 +87,6 @@ public class ComposeActivity extends AppCompatActivity {
|
|||
private static final int STATUS_MEDIA_SIZE_LIMIT = 4000000; // 4MB
|
||||
private static final int MEDIA_PICK_RESULT = 1;
|
||||
private static final int PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;
|
||||
private static final Pattern mentionPattern = Pattern.compile("\\B@[^\\s@]+@?[^\\s@]+");
|
||||
|
||||
private String inReplyToId;
|
||||
private String domain;
|
||||
|
@ -175,9 +174,37 @@ public class ComposeActivity extends AppCompatActivity {
|
|||
Snackbar.make(findViewById(R.id.activity_compose), stringId, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private static class Interval {
|
||||
public int start;
|
||||
public int end;
|
||||
private static int findStartOfMention(String string, int fromIndex) {
|
||||
final int length = string.length();
|
||||
while (fromIndex < length) {
|
||||
int at = string.indexOf('@', fromIndex);
|
||||
if (at < 0) {
|
||||
break;
|
||||
} else if (at == 0 || at >= 1 && Character.isWhitespace(string.codePointBefore(at))) {
|
||||
return at;
|
||||
} else {
|
||||
fromIndex = at + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int findEndOfMention(String string, int fromIndex) {
|
||||
int atCount = 0;
|
||||
final int length = string.length();
|
||||
for (int i = fromIndex; i < length; ) {
|
||||
int codepoint = string.codePointAt(i);
|
||||
if (Character.isWhitespace(codepoint)) {
|
||||
return i;
|
||||
} else if (codepoint == '@') {
|
||||
atCount += 1;
|
||||
if (atCount > 2) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
i += Character.charCount(codepoint);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
private static void colourMentions(Spannable text, int colour) {
|
||||
|
@ -187,44 +214,20 @@ public class ComposeActivity extends AppCompatActivity {
|
|||
for (int i = oldSpans.length - 1; i >= 0; i--) {
|
||||
text.removeSpan(oldSpans[i]);
|
||||
}
|
||||
// Match a list of new colour spans.
|
||||
List<Interval> intervals = new ArrayList<>();
|
||||
Matcher matcher = mentionPattern.matcher(text);
|
||||
while (matcher.find()) {
|
||||
Interval interval = new Interval();
|
||||
interval.start = matcher.start();
|
||||
interval.end = matcher.end();
|
||||
intervals.add(interval);
|
||||
}
|
||||
// Make sure intervals don't overlap.
|
||||
Collections.sort(intervals, new Comparator<Interval>() {
|
||||
@Override
|
||||
public int compare(Interval a, Interval b) {
|
||||
return a.start - b.start;
|
||||
// Colour the mentions.
|
||||
String string = text.toString();
|
||||
int start;
|
||||
int end = 0;
|
||||
while (end < n) {
|
||||
start = findStartOfMention(string, end);
|
||||
if (start < 0 || start >= n) {
|
||||
break;
|
||||
}
|
||||
});
|
||||
for (int i = 0, j = 0; i < intervals.size() - 1; i++, j++) {
|
||||
if (j != 0) {
|
||||
Interval a = intervals.get(j - 1);
|
||||
Interval b = intervals.get(i);
|
||||
if (a.start <= b.end) {
|
||||
while (j != 0 && a.start <= b.end) {
|
||||
a = intervals.get(j - 1);
|
||||
b = intervals.get(i);
|
||||
a.end = Math.max(a.end, b.end);
|
||||
a.start = Math.min(a.start, b.start);
|
||||
j--;
|
||||
}
|
||||
} else {
|
||||
intervals.set(j, b);
|
||||
}
|
||||
} else {
|
||||
intervals.set(j, intervals.get(i));
|
||||
end = findEndOfMention(string, start);
|
||||
if (end < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Finally, set the spans.
|
||||
for (Interval interval : intervals) {
|
||||
text.setSpan(new ForegroundColorSpan(colour), interval.start, interval.end,
|
||||
text.setSpan(new ForegroundColorSpan(colour), start, end,
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
@ -508,10 +511,12 @@ public class ComposeActivity extends AppCompatActivity {
|
|||
|
||||
private void enableMediaPicking() {
|
||||
mediaPick.setEnabled(true);
|
||||
mediaPick.setImageResource(R.drawable.ic_media);
|
||||
}
|
||||
|
||||
private void disableMediaPicking() {
|
||||
mediaPick.setEnabled(false);
|
||||
mediaPick.setImageResource(R.drawable.ic_media_disabled);
|
||||
}
|
||||
|
||||
private void addMediaToQueue(QueuedMedia.Type type, Bitmap preview, Uri uri, long mediaSize) {
|
||||
|
|
5
app/src/main/res/color/media_button_dark.xml
Normal file
5
app/src/main/res/color/media_button_dark.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="#8F8F8F" android:state_enabled="false" />
|
||||
<item android:color="#FFFFFF" />
|
||||
</selector>
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_enabled="true" android:drawable="@drawable/ic_media" />
|
||||
<item android:state_enabled="false" android:drawable="@drawable/ic_media_disabled" />
|
||||
</selector>
|
|
@ -14,8 +14,9 @@
|
|||
<ImageButton
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
app:srcCompat="@drawable/media_selector"
|
||||
app:srcCompat="@drawable/ic_media"
|
||||
style="?attr/image_button_style"
|
||||
android:tint="?attr/compose_media_button_tint"
|
||||
android:id="@+id/compose_photo_pick"
|
||||
android:layout_marginLeft="8dp" />
|
||||
|
||||
|
|
|
@ -21,5 +21,6 @@
|
|||
<attr name="status_divider_color" format="reference|color" />
|
||||
<attr name="tab_page_margin_color" format="reference|color" />
|
||||
<attr name="account_header_background_color" format="reference|color" />
|
||||
<attr name="compose_media_button_tint" format="reference|color" />
|
||||
|
||||
</resources>
|
|
@ -29,6 +29,7 @@
|
|||
<item name="status_divider_color">@color/status_divider_dark</item>
|
||||
<item name="tab_page_margin_color">@color/tab_page_margin_dark</item>
|
||||
<item name="account_header_background_color">@color/account_header_background_dark</item>
|
||||
<item name="compose_media_button_tint">@color/media_button_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.ImageButton.Dark" parent="@style/Widget.AppCompat.Button.Borderless.Colored">
|
||||
|
|
Loading…
Reference in a new issue