|
|
@ -87,7 +87,6 @@ public class ComposeActivity extends AppCompatActivity { |
|
|
|
private static final int STATUS_MEDIA_SIZE_LIMIT = 4000000; // 4MB
|
|
|
|
private static final int STATUS_MEDIA_SIZE_LIMIT = 4000000; // 4MB
|
|
|
|
private static final int MEDIA_PICK_RESULT = 1; |
|
|
|
private static final int MEDIA_PICK_RESULT = 1; |
|
|
|
private static final int PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 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 inReplyToId; |
|
|
|
private String domain; |
|
|
|
private String domain; |
|
|
@ -175,9 +174,37 @@ 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 class Interval { |
|
|
|
private static int findStartOfMention(String string, int fromIndex) { |
|
|
|
public int start; |
|
|
|
final int length = string.length(); |
|
|
|
public int end; |
|
|
|
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) { |
|
|
|
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--) { |
|
|
|
for (int i = oldSpans.length - 1; i >= 0; i--) { |
|
|
|
text.removeSpan(oldSpans[i]); |
|
|
|
text.removeSpan(oldSpans[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
// Match a list of new colour spans.
|
|
|
|
// Colour the mentions.
|
|
|
|
List<Interval> intervals = new ArrayList<>(); |
|
|
|
String string = text.toString(); |
|
|
|
Matcher matcher = mentionPattern.matcher(text); |
|
|
|
int start; |
|
|
|
while (matcher.find()) { |
|
|
|
int end = 0; |
|
|
|
Interval interval = new Interval(); |
|
|
|
while (end < n) { |
|
|
|
interval.start = matcher.start(); |
|
|
|
start = findStartOfMention(string, end); |
|
|
|
interval.end = matcher.end(); |
|
|
|
if (start < 0 || start >= n) { |
|
|
|
intervals.add(interval); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
// 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; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
end = findEndOfMention(string, start); |
|
|
|
for (int i = 0, j = 0; i < intervals.size() - 1; i++, j++) { |
|
|
|
if (end < 0) { |
|
|
|
if (j != 0) { |
|
|
|
break; |
|
|
|
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)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
text.setSpan(new ForegroundColorSpan(colour), start, end, |
|
|
|
// Finally, set the spans.
|
|
|
|
|
|
|
|
for (Interval interval : intervals) { |
|
|
|
|
|
|
|
text.setSpan(new ForegroundColorSpan(colour), interval.start, interval.end, |
|
|
|
|
|
|
|
Spanned.SPAN_INCLUSIVE_EXCLUSIVE); |
|
|
|
Spanned.SPAN_INCLUSIVE_EXCLUSIVE); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -508,10 +511,12 @@ public class ComposeActivity extends AppCompatActivity { |
|
|
|
|
|
|
|
|
|
|
|
private void enableMediaPicking() { |
|
|
|
private void enableMediaPicking() { |
|
|
|
mediaPick.setEnabled(true); |
|
|
|
mediaPick.setEnabled(true); |
|
|
|
|
|
|
|
mediaPick.setImageResource(R.drawable.ic_media); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void disableMediaPicking() { |
|
|
|
private void disableMediaPicking() { |
|
|
|
mediaPick.setEnabled(false); |
|
|
|
mediaPick.setEnabled(false); |
|
|
|
|
|
|
|
mediaPick.setImageResource(R.drawable.ic_media_disabled); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void addMediaToQueue(QueuedMedia.Type type, Bitmap preview, Uri uri, long mediaSize) { |
|
|
|
private void addMediaToQueue(QueuedMedia.Type type, Bitmap preview, Uri uri, long mediaSize) { |
|
|
|