Changes mention and tag highlighting in the composer to use Mastodon's regex. Closes #145 Also, does some haphazard cleanup.
This commit is contained in:
parent
6b0ae5be95
commit
5d621cecda
7 changed files with 83 additions and 60 deletions
|
@ -244,7 +244,6 @@ public class AccountActivity extends BaseActivity {
|
|||
String subtitle = String.format(getString(R.string.status_username_format),
|
||||
account.username);
|
||||
getSupportActionBar().setSubtitle(subtitle);
|
||||
|
||||
}
|
||||
|
||||
boolean useCustomTabs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
|
|
|
@ -170,7 +170,8 @@ public class EditProfileActivity extends BaseActivity {
|
|||
Account me = response.body();
|
||||
priorDisplayName = me.getDisplayName();
|
||||
priorNote = me.note.toString();
|
||||
CircularImageView avatar = (CircularImageView) findViewById(R.id.edit_profile_avatar_preview);
|
||||
CircularImageView avatar =
|
||||
(CircularImageView) findViewById(R.id.edit_profile_avatar_preview);
|
||||
ImageView header = (ImageView) findViewById(R.id.edit_profile_header_preview);
|
||||
|
||||
displayNameEditText.setText(priorDisplayName);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package com.keylesspalace.tusky.json;
|
||||
|
||||
import android.text.Spanned;
|
||||
import android.text.SpannedString;
|
||||
|
||||
import com.emojione.Emojione;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
|
@ -28,7 +29,13 @@ import java.lang.reflect.Type;
|
|||
|
||||
public class SpannedTypeAdapter implements JsonDeserializer<Spanned> {
|
||||
@Override
|
||||
public Spanned deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
return HtmlUtils.fromHtml(Emojione.shortnameToUnicode(json.getAsString(), false));
|
||||
public Spanned deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
String string = json.getAsString();
|
||||
if (string != null) {
|
||||
return HtmlUtils.fromHtml(Emojione.shortnameToUnicode(string, false));
|
||||
} else {
|
||||
return new SpannedString("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,7 +190,10 @@ public interface MastodonApi {
|
|||
|
||||
@FormUrlEncoded
|
||||
@POST("api/v1/reports")
|
||||
Call<ResponseBody> report(@Field("account_id") String accountId, @Field("status_ids[]") List<String> statusIds, @Field("comment") String comment);
|
||||
Call<ResponseBody> report(
|
||||
@Field("account_id") String accountId,
|
||||
@Field("status_ids[]") List<String> statusIds,
|
||||
@Field("comment") String comment);
|
||||
|
||||
@GET("api/v1/search")
|
||||
Call<SearchResults> search(@Query("q") String q, @Query("resolve") Boolean resolve);
|
||||
|
|
|
@ -47,8 +47,8 @@ public class LinkHelper {
|
|||
}
|
||||
|
||||
public static void setClickableText(TextView view, Spanned content,
|
||||
@Nullable Status.Mention[] mentions, boolean useCustomTabs,
|
||||
final LinkListener listener) {
|
||||
@Nullable Status.Mention[] mentions, boolean useCustomTabs,
|
||||
final LinkListener listener) {
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder(content);
|
||||
URLSpan[] urlSpans = content.getSpans(0, content.length(), URLSpan.class);
|
||||
for (URLSpan span : urlSpans) {
|
||||
|
|
|
@ -41,7 +41,7 @@ import com.squareup.picasso.Target;
|
|||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
public class NotificationMaker {
|
||||
class NotificationMaker {
|
||||
|
||||
public static final String TAG = "NotificationMaker";
|
||||
|
||||
|
@ -89,10 +89,12 @@ public class NotificationMaker {
|
|||
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
|
||||
stackBuilder.addParentStack(MainActivity.class);
|
||||
stackBuilder.addNextIntent(resultIntent);
|
||||
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
Intent deleteIntent = new Intent(context, NotificationClearBroadcastReceiver.class);
|
||||
PendingIntent deletePendingIntent = PendingIntent.getBroadcast(context, 0, deleteIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
PendingIntent deletePendingIntent = PendingIntent.getBroadcast(context, 0, deleteIntent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
|
||||
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
|
||||
.setSmallIcon(R.drawable.ic_notify)
|
||||
|
@ -104,15 +106,16 @@ public class NotificationMaker {
|
|||
builder.setContentTitle(titleForType(context, body))
|
||||
.setContentText(truncateWithEllipses(bodyForType(body), 40));
|
||||
|
||||
Target mTarget = new Target() {
|
||||
Target target = new Target() {
|
||||
@Override
|
||||
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
|
||||
builder.setLargeIcon(bitmap);
|
||||
|
||||
setupPreferences(preferences, builder);
|
||||
|
||||
((NotificationManager) (context.getSystemService(Context.NOTIFICATION_SERVICE)))
|
||||
.notify(notifyId, builder.build());
|
||||
NotificationManager notificationManager = (NotificationManager)
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(notifyId, builder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -126,12 +129,15 @@ public class NotificationMaker {
|
|||
.load(body.account.avatar)
|
||||
.placeholder(R.drawable.avatar_default)
|
||||
.transform(new RoundedTransformation(7, 0))
|
||||
.into(mTarget);
|
||||
.into(target);
|
||||
} else {
|
||||
setupPreferences(preferences, builder);
|
||||
try {
|
||||
builder.setContentTitle(String.format(context.getString(R.string.notification_title_summary), currentNotifications.length()))
|
||||
.setContentText(truncateWithEllipses(joinNames(context, currentNotifications), 40));
|
||||
String format = context.getString(R.string.notification_title_summary);
|
||||
String title = String.format(format, currentNotifications.length());
|
||||
String text = truncateWithEllipses(joinNames(context, currentNotifications), 40);
|
||||
builder.setContentTitle(title)
|
||||
.setContentText(text);
|
||||
} catch (JSONException e) {
|
||||
Log.d(TAG, Log.getStackTraceString(e));
|
||||
}
|
||||
|
@ -142,26 +148,23 @@ public class NotificationMaker {
|
|||
builder.setCategory(android.app.Notification.CATEGORY_SOCIAL);
|
||||
}
|
||||
|
||||
((NotificationManager) (context.getSystemService(Context.NOTIFICATION_SERVICE)))
|
||||
.notify(notifyId, builder.build());
|
||||
NotificationManager notificationManager =
|
||||
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(notifyId, builder.build());
|
||||
}
|
||||
|
||||
private static boolean filterNotification(SharedPreferences preferences,
|
||||
Notification notification) {
|
||||
Notification notification) {
|
||||
switch (notification.type) {
|
||||
default:
|
||||
case MENTION: {
|
||||
case MENTION:
|
||||
return preferences.getBoolean("notificationFilterMentions", true);
|
||||
}
|
||||
case FOLLOW: {
|
||||
case FOLLOW:
|
||||
return preferences.getBoolean("notificationFilterFollows", true);
|
||||
}
|
||||
case REBLOG: {
|
||||
case REBLOG:
|
||||
return preferences.getBoolean("notificationFilterReblogs", true);
|
||||
}
|
||||
case FAVOURITE: {
|
||||
case FAVOURITE:
|
||||
return preferences.getBoolean("notificationFilterFavourites", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,7 +177,7 @@ public class NotificationMaker {
|
|||
}
|
||||
|
||||
private static void setupPreferences(SharedPreferences preferences,
|
||||
NotificationCompat.Builder builder) {
|
||||
NotificationCompat.Builder builder) {
|
||||
if (preferences.getBoolean("notificationAlertSound", true)) {
|
||||
builder.setSound(Settings.System.DEFAULT_NOTIFICATION_URI);
|
||||
}
|
||||
|
@ -191,11 +194,14 @@ public class NotificationMaker {
|
|||
@Nullable
|
||||
private static String joinNames(Context context, JSONArray array) throws JSONException {
|
||||
if (array.length() > 3) {
|
||||
return String.format(context.getString(R.string.notification_summary_large), array.get(0), array.get(1), array.get(2), array.length() - 3);
|
||||
return String.format(context.getString(R.string.notification_summary_large),
|
||||
array.get(0), array.get(1), array.get(2), array.length() - 3);
|
||||
} else if (array.length() == 3) {
|
||||
return String.format(context.getString(R.string.notification_summary_medium), array.get(0), array.get(1), array.get(2));
|
||||
return String.format(context.getString(R.string.notification_summary_medium),
|
||||
array.get(0), array.get(1), array.get(2));
|
||||
} else if (array.length() == 2) {
|
||||
return String.format(context.getString(R.string.notification_summary_small), array.get(0), array.get(1));
|
||||
return String.format(context.getString(R.string.notification_summary_small),
|
||||
array.get(0), array.get(1));
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -205,13 +211,17 @@ public class NotificationMaker {
|
|||
private static String titleForType(Context context, Notification notification) {
|
||||
switch (notification.type) {
|
||||
case MENTION:
|
||||
return String.format(context.getString(R.string.notification_mention_format), notification.account.getDisplayName());
|
||||
return String.format(context.getString(R.string.notification_mention_format),
|
||||
notification.account.getDisplayName());
|
||||
case FOLLOW:
|
||||
return String.format(context.getString(R.string.notification_follow_format), notification.account.getDisplayName());
|
||||
return String.format(context.getString(R.string.notification_follow_format),
|
||||
notification.account.getDisplayName());
|
||||
case FAVOURITE:
|
||||
return String.format(context.getString(R.string.notification_favourite_format), notification.account.getDisplayName());
|
||||
return String.format(context.getString(R.string.notification_favourite_format),
|
||||
notification.account.getDisplayName());
|
||||
case REBLOG:
|
||||
return String.format(context.getString(R.string.notification_reblog_format), notification.account.getDisplayName());
|
||||
return String.format(context.getString(R.string.notification_reblog_format),
|
||||
notification.account.getDisplayName());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -226,7 +236,6 @@ public class NotificationMaker {
|
|||
case REBLOG:
|
||||
return notification.status.content.toString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,17 @@ import android.text.Spannable;
|
|||
import android.text.Spanned;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SpanUtils {
|
||||
private static final String TAG_REGEX = "(?:^|[^/)\\w])#([\\w_]*[\\p{Alpha}_][\\w_]*)";
|
||||
private static Pattern TAG_PATTERN = Pattern.compile(TAG_REGEX, Pattern.CASE_INSENSITIVE);
|
||||
private static final String MENTION_REGEX =
|
||||
"(?:^|[^/[:word:]])@([a-z0-9_]+(?:@[a-z0-9\\.\\-]+[a-z0-9]+)?)";
|
||||
private static Pattern MENTION_PATTERN =
|
||||
Pattern.compile(MENTION_REGEX, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
private static class FindCharsResult {
|
||||
int charIndex;
|
||||
int stringIndex;
|
||||
|
@ -63,35 +73,29 @@ public class SpanUtils {
|
|||
}
|
||||
|
||||
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);
|
||||
Matcher matcher = TAG_PATTERN.matcher(string);
|
||||
if (fromIndex >= 1) {
|
||||
fromIndex--;
|
||||
}
|
||||
boolean found = matcher.find(fromIndex);
|
||||
if (found) {
|
||||
return matcher.end();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
private static int findEndOfMention(String string, int fromIndex) {
|
||||
int atCount = 0;
|
||||
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 == '@') {
|
||||
atCount += 1;
|
||||
if (atCount >= 2) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
i += Character.charCount(codepoint);
|
||||
Matcher matcher = MENTION_PATTERN.matcher(string);
|
||||
if (fromIndex >= 1) {
|
||||
fromIndex--;
|
||||
}
|
||||
boolean found = matcher.find(fromIndex);
|
||||
if (found) {
|
||||
return matcher.end();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
public static void highlightSpans(Spannable text, int colour) {
|
||||
|
|
Loading…
Reference in a new issue