From 28856aaf9fb572a2d1fbf647047b5dfb3ec1cf83 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 19 Jul 2020 21:27:43 +0200 Subject: [PATCH] add icons for gpx files --- .../ui/adapter/MediaAdapter.java | 13 +- .../conversations/ui/util/Attachment.java | 12 + .../siacs/conversations/utils/MimeUtils.java | 37 +- .../siacs/conversations/utils/UIHelper.java | 1022 +++++++++-------- .../drawable-hdpi/baseline_tour_black_48.png | Bin 0 -> 369 bytes .../drawable-hdpi/baseline_tour_white_48.png | Bin 0 -> 372 bytes .../drawable-mdpi/baseline_tour_black_48.png | Bin 0 -> 273 bytes .../drawable-mdpi/baseline_tour_white_48.png | Bin 0 -> 277 bytes .../drawable-xhdpi/baseline_tour_black_48.png | Bin 0 -> 451 bytes .../drawable-xhdpi/baseline_tour_white_48.png | Bin 0 -> 451 bytes .../baseline_tour_black_48.png | Bin 0 -> 662 bytes .../baseline_tour_white_48.png | Bin 0 -> 662 bytes .../baseline_tour_black_48.png | Bin 0 -> 809 bytes .../baseline_tour_white_48.png | Bin 0 -> 809 bytes src/main/res/values/attrs.xml | 1 + src/main/res/values/strings.xml | 1 + src/main/res/values/themes.xml | 2 + 17 files changed, 564 insertions(+), 524 deletions(-) create mode 100644 src/main/res/drawable-hdpi/baseline_tour_black_48.png create mode 100644 src/main/res/drawable-hdpi/baseline_tour_white_48.png create mode 100644 src/main/res/drawable-mdpi/baseline_tour_black_48.png create mode 100644 src/main/res/drawable-mdpi/baseline_tour_white_48.png create mode 100644 src/main/res/drawable-xhdpi/baseline_tour_black_48.png create mode 100644 src/main/res/drawable-xhdpi/baseline_tour_white_48.png create mode 100644 src/main/res/drawable-xxhdpi/baseline_tour_black_48.png create mode 100644 src/main/res/drawable-xxhdpi/baseline_tour_white_48.png create mode 100644 src/main/res/drawable-xxxhdpi/baseline_tour_black_48.png create mode 100644 src/main/res/drawable-xxxhdpi/baseline_tour_white_48.png diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MediaAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MediaAdapter.java index bf6cc0689..03920f2dc 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MediaAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MediaAdapter.java @@ -11,6 +11,7 @@ import android.support.annotation.AttrRes; import android.support.annotation.DimenRes; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.ViewGroup; import android.widget.ImageView; @@ -21,6 +22,7 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.RejectedExecutionException; +import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.databinding.MediaBinding; import eu.siacs.conversations.services.ExportBackupService; @@ -51,14 +53,16 @@ public class MediaAdapter extends RecyclerView.Adapter mimeTypeToExtensionMap = new HashMap<>(); private static final Map extensionToMimeTypeMap = new HashMap<>(); + static { // The following table is based on /etc/mime.types data minus // chemical/* MIME types and MIME types that don't map to any @@ -52,7 +54,8 @@ public final class MimeUtils { // by guessExtensionFromMimeType. add("application/andrew-inset", "ez"); add("application/dsptype", "tsp"); - add("application/epub+zip","epub"); + add("application/epub+zip", "epub"); + add("application/gpx+xml", "gpx"); add("application/hta", "hta"); add("application/mac-binhex40", "hqx"); add("application/mathematica", "nb"); @@ -68,9 +71,9 @@ public final class MimeUtils { add("application/rdf+xml", "rdf"); add("application/rss+xml", "rss"); add("application/zip", "zip"); - add("application/vnd.amazon.mobi8-ebook","azw3"); - add("application/vnd.amazon.mobi8-ebook","azw"); - add("application/vnd.amazon.mobi8-ebook","kfx"); + add("application/vnd.amazon.mobi8-ebook", "azw3"); + add("application/vnd.amazon.mobi8-ebook", "azw"); + add("application/vnd.amazon.mobi8-ebook", "kfx"); add("application/vnd.android.package-archive", "apk"); add("application/vnd.cinderella", "cdy"); add(ExportBackupService.MIME_TYPE, "ceb"); @@ -183,7 +186,7 @@ public final class MimeUtils { add("application/x-maker", "book"); add("application/x-maker", "fbdoc"); add("application/x-mif", "mif"); - add("application/x-mobipocket-ebook","mobi"); + add("application/x-mobipocket-ebook", "mobi"); add("application/x-ms-wmd", "wmd"); add("application/x-ms-wmz", "wmz"); add("application/x-msi", "msi"); @@ -242,7 +245,7 @@ public final class MimeUtils { add("audio/mpeg", "mp2"); add("audio/mpeg", "m4a"); add("audio/mpegurl", "m3u"); - add("audio/ogg","oga"); + add("audio/ogg", "oga"); add("audio/prs.sid", "sid"); add("audio/x-aiff", "aif"); add("audio/x-aiff", "aiff"); @@ -268,7 +271,7 @@ public final class MimeUtils { add("image/ico", "cur"); add("image/ico", "ico"); add("image/ief", "ief"); - add("image/heic","heic"); + add("image/heic", "heic"); // add ".jpg" first so it will be the default for guessExtensionFromMimeType add("image/jpeg", "jpg"); add("image/jpeg", "jpeg"); @@ -367,7 +370,7 @@ public final class MimeUtils { add("video/fli", "fli"); add("video/m4v", "m4v"); add("video/mp2ts", "ts"); - add("video/ogg","ogv"); + add("video/ogg", "ogv"); add("video/mpeg", "mpeg"); add("video/mpeg", "mpg"); add("video/mpeg", "mpe"); @@ -393,6 +396,7 @@ public final class MimeUtils { add("x-epoc/x-sisx-app", "sisx"); applyOverrides(); } + private static void add(String mimeType, String extension) { // If we have an existing x -> y mapping, we do not want to // override it with another mapping x -> y2. @@ -406,6 +410,7 @@ public final class MimeUtils { extensionToMimeTypeMap.put(extension, mimeType); } } + private static InputStream getContentTypesPropertiesStream() { // User override? String userTable = System.getProperty("content.types.user.table"); @@ -428,6 +433,7 @@ public final class MimeUtils { } return null; } + /** * This isn't what the RI does. The RI doesn't have hard-coded defaults, so supplying your * own "content.types.user.table" means you don't get any of the built-ins, and the built-ins @@ -456,10 +462,13 @@ public final class MimeUtils { } catch (IOException ignored) { } } + private MimeUtils() { } + /** * Returns true if the given MIME type has an entry in the map. + * * @param mimeType A MIME type (i.e. text/plain) * @return True iff there is a mimeType entry in the map. */ @@ -469,8 +478,10 @@ public final class MimeUtils { } return mimeTypeToExtensionMap.containsKey(mimeType); } + /** * Returns the MIME type for the given extension. + * * @param extension A file extension without the leading '.' * @return The MIME type for the given extension or null iff there is none. */ @@ -480,8 +491,10 @@ public final class MimeUtils { } return extensionToMimeTypeMap.get(extension.toLowerCase()); } + /** * Returns true if the given extension has a registered MIME type. + * * @param extension A file extension without the leading '.' * @return True iff there is an extension entry in the map. */ @@ -491,10 +504,12 @@ public final class MimeUtils { } return extensionToMimeTypeMap.containsKey(extension); } + /** * Returns the registered extension for the given MIME type. Note that some * MIME types map to multiple extensions. This call will return the most * common extension for the given MIME type. + * * @param mimeType A MIME type (i.e. text/plain) * @return The extension for the given MIME type or null iff there is none. */ @@ -506,7 +521,7 @@ public final class MimeUtils { } public static String guessMimeTypeFromUriAndMime(final Context context, final Uri uri, final String mime) { - Log.d(Config.LOGTAG,"guessMimeTypeFromUriAndMime "+uri+" and mime="+mime); + Log.d(Config.LOGTAG, "guessMimeTypeFromUriAndMime " + uri + " and mime=" + mime); if (mime == null || mime.equals("application/octet-stream")) { final String guess = guessMimeTypeFromUri(context, uri); if (guess != null) { @@ -515,7 +530,7 @@ public final class MimeUtils { return mime; } } - return guessMimeTypeFromUri(context ,uri); + return guessMimeTypeFromUri(context, uri); } public static String guessMimeTypeFromUri(Context context, Uri uri) { @@ -565,7 +580,7 @@ public final class MimeUtils { String extension = filename.substring(dotPosition + 1); // we want the real file extension, not the crypto one if (ignoreCryptoExtension && Transferable.VALID_CRYPTO_EXTENSIONS.contains(extension)) { - return extractRelevantExtension(filename.substring(0,dotPosition)); + return extractRelevantExtension(filename.substring(0, dotPosition)); } else { return extension; } diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 238fd0875..bf87dd0bd 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -32,564 +32,566 @@ import eu.siacs.conversations.xmpp.Jid; public class UIHelper { - private static int[] UNSAFE_COLORS = { - 0xFFF44336, //red 500 - 0xFFE53935, //red 600 - 0xFFD32F2F, //red 700 - 0xFFC62828, //red 800 + private static int[] UNSAFE_COLORS = { + 0xFFF44336, //red 500 + 0xFFE53935, //red 600 + 0xFFD32F2F, //red 700 + 0xFFC62828, //red 800 - 0xFFEF6C00, //orange 800 + 0xFFEF6C00, //orange 800 - 0xFFF4511E, //deep orange 600 - 0xFFE64A19, //deep orange 700 - 0xFFD84315, //deep orange 800, - }; + 0xFFF4511E, //deep orange 600 + 0xFFE64A19, //deep orange 700 + 0xFFD84315, //deep orange 800, + }; - private static int[] SAFE_COLORS = { - 0xFFE91E63, //pink 500 - 0xFFD81B60, //pink 600 - 0xFFC2185B, //pink 700 - 0xFFAD1457, //pink 800 + private static int[] SAFE_COLORS = { + 0xFFE91E63, //pink 500 + 0xFFD81B60, //pink 600 + 0xFFC2185B, //pink 700 + 0xFFAD1457, //pink 800 - 0xFF9C27B0, //purple 500 - 0xFF8E24AA, //purple 600 - 0xFF7B1FA2, //purple 700 - 0xFF6A1B9A, //purple 800 + 0xFF9C27B0, //purple 500 + 0xFF8E24AA, //purple 600 + 0xFF7B1FA2, //purple 700 + 0xFF6A1B9A, //purple 800 - 0xFF673AB7, //deep purple 500, - 0xFF5E35B1, //deep purple 600 - 0xFF512DA8, //deep purple 700 - 0xFF4527A0, //deep purple 800, + 0xFF673AB7, //deep purple 500, + 0xFF5E35B1, //deep purple 600 + 0xFF512DA8, //deep purple 700 + 0xFF4527A0, //deep purple 800, - 0xFF3F51B5, //indigo 500, - 0xFF3949AB,//indigo 600 - 0xFF303F9F,//indigo 700 - 0xFF283593, //indigo 800 + 0xFF3F51B5, //indigo 500, + 0xFF3949AB,//indigo 600 + 0xFF303F9F,//indigo 700 + 0xFF283593, //indigo 800 - 0xFF2196F3, //blue 500 - 0xFF1E88E5, //blue 600 - 0xFF1976D2, //blue 700 - 0xFF1565C0, //blue 800 + 0xFF2196F3, //blue 500 + 0xFF1E88E5, //blue 600 + 0xFF1976D2, //blue 700 + 0xFF1565C0, //blue 800 - 0xFF03A9F4, //light blue 500 - 0xFF039BE5, //light blue 600 - 0xFF0288D1, //light blue 700 - 0xFF0277BD, //light blue 800 + 0xFF03A9F4, //light blue 500 + 0xFF039BE5, //light blue 600 + 0xFF0288D1, //light blue 700 + 0xFF0277BD, //light blue 800 - 0xFF00BCD4, //cyan 500 - 0xFF00ACC1, //cyan 600 - 0xFF0097A7, //cyan 700 - 0xFF00838F, //cyan 800 + 0xFF00BCD4, //cyan 500 + 0xFF00ACC1, //cyan 600 + 0xFF0097A7, //cyan 700 + 0xFF00838F, //cyan 800 - 0xFF009688, //teal 500, - 0xFF00897B, //teal 600 - 0xFF00796B, //teal 700 - 0xFF00695C, //teal 800, + 0xFF009688, //teal 500, + 0xFF00897B, //teal 600 + 0xFF00796B, //teal 700 + 0xFF00695C, //teal 800, - //0xFF558B2F, //light green 800 + //0xFF558B2F, //light green 800 - //0xFFC0CA33, //lime 600 - 0xFF9E9D24, //lime 800 + //0xFFC0CA33, //lime 600 + 0xFF9E9D24, //lime 800 - 0xFF795548, //brown 500, - //0xFF4E342E, //brown 800 - 0xFF607D8B, //blue grey 500, - //0xFF37474F //blue grey 800 - }; + 0xFF795548, //brown 500, + //0xFF4E342E, //brown 800 + 0xFF607D8B, //blue grey 500, + //0xFF37474F //blue grey 800 + }; - private static final int[] COLORS; + private static final int[] COLORS; - static { - COLORS = Arrays.copyOf(SAFE_COLORS, SAFE_COLORS.length + UNSAFE_COLORS.length); - System.arraycopy(UNSAFE_COLORS, 0, COLORS, SAFE_COLORS.length, UNSAFE_COLORS.length); - } + static { + COLORS = Arrays.copyOf(SAFE_COLORS, SAFE_COLORS.length + UNSAFE_COLORS.length); + System.arraycopy(UNSAFE_COLORS, 0, COLORS, SAFE_COLORS.length, UNSAFE_COLORS.length); + } - private static final List LOCATION_QUESTIONS = Arrays.asList( - "where are you", //en - "where are you now", //en - "where are you right now", //en - "whats your 20", //en - "what is your 20", //en - "what's your 20", //en - "whats your twenty", //en - "what is your twenty", //en - "what's your twenty", //en - "wo bist du", //de - "wo bist du jetzt", //de - "wo bist du gerade", //de - "wo seid ihr", //de - "wo seid ihr jetzt", //de - "wo seid ihr gerade", //de - "dónde estás", //es - "donde estas" //es - ); + private static final List LOCATION_QUESTIONS = Arrays.asList( + "where are you", //en + "where are you now", //en + "where are you right now", //en + "whats your 20", //en + "what is your 20", //en + "what's your 20", //en + "whats your twenty", //en + "what is your twenty", //en + "what's your twenty", //en + "wo bist du", //de + "wo bist du jetzt", //de + "wo bist du gerade", //de + "wo seid ihr", //de + "wo seid ihr jetzt", //de + "wo seid ihr gerade", //de + "dónde estás", //es + "donde estas" //es + ); - private static final List PUNCTIONATION = Arrays.asList('.', ',', '?', '!', ';', ':'); + private static final List PUNCTIONATION = Arrays.asList('.', ',', '?', '!', ';', ':'); - private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE - | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; - private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME - | DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE; + private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; + private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME + | DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE; - public static String readableTimeDifference(Context context, long time) { - return readableTimeDifference(context, time, false); - } + public static String readableTimeDifference(Context context, long time) { + return readableTimeDifference(context, time, false); + } - public static String readableTimeDifferenceFull(Context context, long time) { - return readableTimeDifference(context, time, true); - } + public static String readableTimeDifferenceFull(Context context, long time) { + return readableTimeDifference(context, time, true); + } - private static String readableTimeDifference(Context context, long time, - boolean fullDate) { - if (time == 0) { - return context.getString(R.string.just_now); - } - Date date = new Date(time); - long difference = (System.currentTimeMillis() - time) / 1000; - if (difference < 60) { - return context.getString(R.string.just_now); - } else if (difference < 60 * 2) { - return context.getString(R.string.minute_ago); - } else if (difference < 60 * 15) { - return context.getString(R.string.minutes_ago, Math.round(difference / 60.0)); - } else if (today(date)) { - java.text.DateFormat df = DateFormat.getTimeFormat(context); - return df.format(date); - } else { - if (fullDate) { - return DateUtils.formatDateTime(context, date.getTime(), - FULL_DATE_FLAGS); - } else { - return DateUtils.formatDateTime(context, date.getTime(), - SHORT_DATE_FLAGS); - } - } - } + private static String readableTimeDifference(Context context, long time, + boolean fullDate) { + if (time == 0) { + return context.getString(R.string.just_now); + } + Date date = new Date(time); + long difference = (System.currentTimeMillis() - time) / 1000; + if (difference < 60) { + return context.getString(R.string.just_now); + } else if (difference < 60 * 2) { + return context.getString(R.string.minute_ago); + } else if (difference < 60 * 15) { + return context.getString(R.string.minutes_ago, Math.round(difference / 60.0)); + } else if (today(date)) { + java.text.DateFormat df = DateFormat.getTimeFormat(context); + return df.format(date); + } else { + if (fullDate) { + return DateUtils.formatDateTime(context, date.getTime(), + FULL_DATE_FLAGS); + } else { + return DateUtils.formatDateTime(context, date.getTime(), + SHORT_DATE_FLAGS); + } + } + } - private static boolean today(Date date) { - return sameDay(date, new Date(System.currentTimeMillis())); - } + private static boolean today(Date date) { + return sameDay(date, new Date(System.currentTimeMillis())); + } - public static boolean today(long date) { - return sameDay(date, System.currentTimeMillis()); - } + public static boolean today(long date) { + return sameDay(date, System.currentTimeMillis()); + } - public static boolean yesterday(long date) { - Calendar cal1 = Calendar.getInstance(); - Calendar cal2 = Calendar.getInstance(); - cal1.add(Calendar.DAY_OF_YEAR, -1); - cal2.setTime(new Date(date)); - return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) - && cal1.get(Calendar.DAY_OF_YEAR) == cal2 - .get(Calendar.DAY_OF_YEAR); - } + public static boolean yesterday(long date) { + Calendar cal1 = Calendar.getInstance(); + Calendar cal2 = Calendar.getInstance(); + cal1.add(Calendar.DAY_OF_YEAR, -1); + cal2.setTime(new Date(date)); + return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) + && cal1.get(Calendar.DAY_OF_YEAR) == cal2 + .get(Calendar.DAY_OF_YEAR); + } - public static boolean sameDay(long a, long b) { - return sameDay(new Date(a), new Date(b)); - } + public static boolean sameDay(long a, long b) { + return sameDay(new Date(a), new Date(b)); + } - private static boolean sameDay(Date a, Date b) { - Calendar cal1 = Calendar.getInstance(); - Calendar cal2 = Calendar.getInstance(); - cal1.setTime(a); - cal2.setTime(b); - return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) - && cal1.get(Calendar.DAY_OF_YEAR) == cal2 - .get(Calendar.DAY_OF_YEAR); - } + private static boolean sameDay(Date a, Date b) { + Calendar cal1 = Calendar.getInstance(); + Calendar cal2 = Calendar.getInstance(); + cal1.setTime(a); + cal2.setTime(b); + return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) + && cal1.get(Calendar.DAY_OF_YEAR) == cal2 + .get(Calendar.DAY_OF_YEAR); + } - public static String lastseen(Context context, boolean active, long time) { - long difference = (System.currentTimeMillis() - time) / 1000; - if (active) { - return context.getString(R.string.online_right_now); - } else if (difference < 60) { - return context.getString(R.string.last_seen_now); - } else if (difference < 60 * 2) { - return context.getString(R.string.last_seen_min); - } else if (difference < 60 * 60) { - return context.getString(R.string.last_seen_mins, Math.round(difference / 60.0)); - } else if (difference < 60 * 60 * 2) { - return context.getString(R.string.last_seen_hour); - } else if (difference < 60 * 60 * 24) { - return context.getString(R.string.last_seen_hours, - Math.round(difference / (60.0 * 60.0))); - } else if (difference < 60 * 60 * 48) { - return context.getString(R.string.last_seen_day); - } else { - return context.getString(R.string.last_seen_days, - Math.round(difference / (60.0 * 60.0 * 24.0))); - } - } + public static String lastseen(Context context, boolean active, long time) { + long difference = (System.currentTimeMillis() - time) / 1000; + if (active) { + return context.getString(R.string.online_right_now); + } else if (difference < 60) { + return context.getString(R.string.last_seen_now); + } else if (difference < 60 * 2) { + return context.getString(R.string.last_seen_min); + } else if (difference < 60 * 60) { + return context.getString(R.string.last_seen_mins, Math.round(difference / 60.0)); + } else if (difference < 60 * 60 * 2) { + return context.getString(R.string.last_seen_hour); + } else if (difference < 60 * 60 * 24) { + return context.getString(R.string.last_seen_hours, + Math.round(difference / (60.0 * 60.0))); + } else if (difference < 60 * 60 * 48) { + return context.getString(R.string.last_seen_day); + } else { + return context.getString(R.string.last_seen_days, + Math.round(difference / (60.0 * 60.0 * 24.0))); + } + } - public static int getColorForName(String name) { - return getColorForName(name, false); - } + public static int getColorForName(String name) { + return getColorForName(name, false); + } - public static int getColorForName(String name, boolean safe) { - if (Config.XEP_0392) { - return XEP0392Helper.rgbFromNick(name); - } - if (name == null || name.isEmpty()) { - return 0xFF202020; - } - if (safe) { - return SAFE_COLORS[(int) (getLongForName(name) % SAFE_COLORS.length)]; - } else { - return COLORS[(int) (getLongForName(name) % COLORS.length)]; - } - } + public static int getColorForName(String name, boolean safe) { + if (Config.XEP_0392) { + return XEP0392Helper.rgbFromNick(name); + } + if (name == null || name.isEmpty()) { + return 0xFF202020; + } + if (safe) { + return SAFE_COLORS[(int) (getLongForName(name) % SAFE_COLORS.length)]; + } else { + return COLORS[(int) (getLongForName(name) % COLORS.length)]; + } + } - private static long getLongForName(String name) { - try { - final MessageDigest messageDigest = MessageDigest.getInstance("MD5"); - return Math.abs(new BigInteger(messageDigest.digest(name.getBytes())).longValue()); - } catch (Exception e) { - return 0; - } - } + private static long getLongForName(String name) { + try { + final MessageDigest messageDigest = MessageDigest.getInstance("MD5"); + return Math.abs(new BigInteger(messageDigest.digest(name.getBytes())).longValue()); + } catch (Exception e) { + return 0; + } + } - public static Pair getMessagePreview(final Context context, final Message message) { - return getMessagePreview(context, message, 0); - } + public static Pair getMessagePreview(final Context context, final Message message) { + return getMessagePreview(context, message, 0); + } - public static Pair getMessagePreview(final Context context, final Message message, @ColorInt int textColor) { - final Transferable d = message.getTransferable(); - if (d != null) { - switch (d.getStatus()) { - case Transferable.STATUS_CHECKING: - return new Pair<>(context.getString(R.string.checking_x, - getFileDescriptionString(context, message)), true); - case Transferable.STATUS_DOWNLOADING: - return new Pair<>(context.getString(R.string.receiving_x_file, - getFileDescriptionString(context, message), - d.getProgress()), true); - case Transferable.STATUS_OFFER: - case Transferable.STATUS_OFFER_CHECK_FILESIZE: - return new Pair<>(context.getString(R.string.x_file_offered_for_download, - getFileDescriptionString(context, message)), true); - case Transferable.STATUS_FAILED: - return new Pair<>(context.getString(R.string.file_transmission_failed), true); - case Transferable.STATUS_CANCELLED: - return new Pair<>(context.getString(R.string.file_transmission_cancelled), true); - case Transferable.STATUS_UPLOADING: - if (message.getStatus() == Message.STATUS_OFFERED) { - return new Pair<>(context.getString(R.string.offering_x_file, - getFileDescriptionString(context, message)), true); - } else { - return new Pair<>(context.getString(R.string.sending_x_file, - getFileDescriptionString(context, message)), true); - } - default: - return new Pair<>("", false); - } - } else if (message.isFileOrImage() && message.isDeleted()) { - return new Pair<>(context.getString(R.string.file_deleted), true); - } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { - return new Pair<>(context.getString(R.string.pgp_message), true); - } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { - return new Pair<>(context.getString(R.string.decryption_failed), true); - } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_NOT_FOR_THIS_DEVICE) { - return new Pair<>(context.getString(R.string.not_encrypted_for_this_device), true); - } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_FAILED) { - return new Pair<>(context.getString(R.string.omemo_decryption_failed), true); - } else if (message.isFileOrImage()) { - return new Pair<>(getFileDescriptionString(context, message), true); - } else if (message.getType() == Message.TYPE_RTP_SESSION) { - RtpSessionStatus rtpSessionStatus = RtpSessionStatus.of(message.getBody()); - final boolean received = message.getStatus() == Message.STATUS_RECEIVED; - if (!rtpSessionStatus.successful && received) { - return new Pair<>(context.getString(R.string.missed_call),true); - } else { - return new Pair<>(context.getString(received ? R.string.incoming_call : R.string.outgoing_call), true); - } - } else { - final String body = MessageUtils.filterLtrRtl(message.getBody()); - if (body.startsWith(Message.ME_COMMAND)) { - return new Pair<>(body.replaceAll("^" + Message.ME_COMMAND, - UIHelper.getMessageDisplayName(message) + " "), false); - } else if (message.isGeoUri()) { - return new Pair<>(context.getString(R.string.location), true); - } else if (message.treatAsDownloadable() || MessageUtils.unInitiatedButKnownSize(message)) { - return new Pair<>(context.getString(R.string.x_file_offered_for_download, - getFileDescriptionString(context, message)), true); - } else { - SpannableStringBuilder styledBody = new SpannableStringBuilder(body); - if (textColor != 0) { - StylingHelper.format(styledBody, 0, styledBody.length() - 1, textColor); - } - SpannableStringBuilder builder = new SpannableStringBuilder(); - for (CharSequence l : CharSequenceUtils.split(styledBody, '\n')) { - if (l.length() > 0) { - if (l.toString().equals("```")) { - continue; - } - char first = l.charAt(0); - if ((first != '>' || !isPositionFollowedByQuoteableCharacter(l, 0)) && first != '\u00bb') { - CharSequence line = CharSequenceUtils.trim(l); - if (line.length() == 0) { - continue; - } - char last = line.charAt(line.length() - 1); - if (builder.length() != 0) { - builder.append(' '); - } - builder.append(line); - if (!PUNCTIONATION.contains(last)) { - break; - } - } - } - } - if (builder.length() == 0) { - builder.append(body.trim()); - } - return new Pair<>(builder, false); - } - } - } + public static Pair getMessagePreview(final Context context, final Message message, @ColorInt int textColor) { + final Transferable d = message.getTransferable(); + if (d != null) { + switch (d.getStatus()) { + case Transferable.STATUS_CHECKING: + return new Pair<>(context.getString(R.string.checking_x, + getFileDescriptionString(context, message)), true); + case Transferable.STATUS_DOWNLOADING: + return new Pair<>(context.getString(R.string.receiving_x_file, + getFileDescriptionString(context, message), + d.getProgress()), true); + case Transferable.STATUS_OFFER: + case Transferable.STATUS_OFFER_CHECK_FILESIZE: + return new Pair<>(context.getString(R.string.x_file_offered_for_download, + getFileDescriptionString(context, message)), true); + case Transferable.STATUS_FAILED: + return new Pair<>(context.getString(R.string.file_transmission_failed), true); + case Transferable.STATUS_CANCELLED: + return new Pair<>(context.getString(R.string.file_transmission_cancelled), true); + case Transferable.STATUS_UPLOADING: + if (message.getStatus() == Message.STATUS_OFFERED) { + return new Pair<>(context.getString(R.string.offering_x_file, + getFileDescriptionString(context, message)), true); + } else { + return new Pair<>(context.getString(R.string.sending_x_file, + getFileDescriptionString(context, message)), true); + } + default: + return new Pair<>("", false); + } + } else if (message.isFileOrImage() && message.isDeleted()) { + return new Pair<>(context.getString(R.string.file_deleted), true); + } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { + return new Pair<>(context.getString(R.string.pgp_message), true); + } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { + return new Pair<>(context.getString(R.string.decryption_failed), true); + } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_NOT_FOR_THIS_DEVICE) { + return new Pair<>(context.getString(R.string.not_encrypted_for_this_device), true); + } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_FAILED) { + return new Pair<>(context.getString(R.string.omemo_decryption_failed), true); + } else if (message.isFileOrImage()) { + return new Pair<>(getFileDescriptionString(context, message), true); + } else if (message.getType() == Message.TYPE_RTP_SESSION) { + RtpSessionStatus rtpSessionStatus = RtpSessionStatus.of(message.getBody()); + final boolean received = message.getStatus() == Message.STATUS_RECEIVED; + if (!rtpSessionStatus.successful && received) { + return new Pair<>(context.getString(R.string.missed_call), true); + } else { + return new Pair<>(context.getString(received ? R.string.incoming_call : R.string.outgoing_call), true); + } + } else { + final String body = MessageUtils.filterLtrRtl(message.getBody()); + if (body.startsWith(Message.ME_COMMAND)) { + return new Pair<>(body.replaceAll("^" + Message.ME_COMMAND, + UIHelper.getMessageDisplayName(message) + " "), false); + } else if (message.isGeoUri()) { + return new Pair<>(context.getString(R.string.location), true); + } else if (message.treatAsDownloadable() || MessageUtils.unInitiatedButKnownSize(message)) { + return new Pair<>(context.getString(R.string.x_file_offered_for_download, + getFileDescriptionString(context, message)), true); + } else { + SpannableStringBuilder styledBody = new SpannableStringBuilder(body); + if (textColor != 0) { + StylingHelper.format(styledBody, 0, styledBody.length() - 1, textColor); + } + SpannableStringBuilder builder = new SpannableStringBuilder(); + for (CharSequence l : CharSequenceUtils.split(styledBody, '\n')) { + if (l.length() > 0) { + if (l.toString().equals("```")) { + continue; + } + char first = l.charAt(0); + if ((first != '>' || !isPositionFollowedByQuoteableCharacter(l, 0)) && first != '\u00bb') { + CharSequence line = CharSequenceUtils.trim(l); + if (line.length() == 0) { + continue; + } + char last = line.charAt(line.length() - 1); + if (builder.length() != 0) { + builder.append(' '); + } + builder.append(line); + if (!PUNCTIONATION.contains(last)) { + break; + } + } + } + } + if (builder.length() == 0) { + builder.append(body.trim()); + } + return new Pair<>(builder, false); + } + } + } - public static boolean isLastLineQuote(String body) { - if (body.endsWith("\n")) { - return false; - } - String[] lines = body.split("\n"); - if (lines.length == 0) { - return false; - } - String line = lines[lines.length - 1]; - if (line.isEmpty()) { - return false; - } - char first = line.charAt(0); - return first == '>' && isPositionFollowedByQuoteableCharacter(line,0) || first == '\u00bb'; - } + public static boolean isLastLineQuote(String body) { + if (body.endsWith("\n")) { + return false; + } + String[] lines = body.split("\n"); + if (lines.length == 0) { + return false; + } + String line = lines[lines.length - 1]; + if (line.isEmpty()) { + return false; + } + char first = line.charAt(0); + return first == '>' && isPositionFollowedByQuoteableCharacter(line, 0) || first == '\u00bb'; + } - public static CharSequence shorten(CharSequence input) { - return input.length() > 256 ? StylingHelper.subSequence(input, 0, 256) : input; - } + public static CharSequence shorten(CharSequence input) { + return input.length() > 256 ? StylingHelper.subSequence(input, 0, 256) : input; + } - public static boolean isPositionFollowedByQuoteableCharacter(CharSequence body, int pos) { - return !isPositionFollowedByNumber(body, pos) - && !isPositionFollowedByEmoticon(body, pos) - && !isPositionFollowedByEquals(body, pos); - } + public static boolean isPositionFollowedByQuoteableCharacter(CharSequence body, int pos) { + return !isPositionFollowedByNumber(body, pos) + && !isPositionFollowedByEmoticon(body, pos) + && !isPositionFollowedByEquals(body, pos); + } - private static boolean isPositionFollowedByNumber(CharSequence body, int pos) { - boolean previousWasNumber = false; - for (int i = pos + 1; i < body.length(); i++) { - char c = body.charAt(i); - if (Character.isDigit(body.charAt(i))) { - previousWasNumber = true; - } else if (previousWasNumber && (c == '.' || c == ',')) { - previousWasNumber = false; - } else { - return (Character.isWhitespace(c) || c == '%' || c == '+') && previousWasNumber; - } - } - return previousWasNumber; - } + private static boolean isPositionFollowedByNumber(CharSequence body, int pos) { + boolean previousWasNumber = false; + for (int i = pos + 1; i < body.length(); i++) { + char c = body.charAt(i); + if (Character.isDigit(body.charAt(i))) { + previousWasNumber = true; + } else if (previousWasNumber && (c == '.' || c == ',')) { + previousWasNumber = false; + } else { + return (Character.isWhitespace(c) || c == '%' || c == '+') && previousWasNumber; + } + } + return previousWasNumber; + } - private static boolean isPositionFollowedByEquals(CharSequence body, int pos) { - return body.length() > pos + 1 && body.charAt(pos + 1) == '='; - } + private static boolean isPositionFollowedByEquals(CharSequence body, int pos) { + return body.length() > pos + 1 && body.charAt(pos + 1) == '='; + } - private static boolean isPositionFollowedByEmoticon(CharSequence body, int pos) { - if (body.length() <= pos + 1) { - return false; - } else { - final char first = body.charAt(pos + 1); - return first == ';' - || first == ':' - || closingBeforeWhitespace(body, pos + 1); - } - } + private static boolean isPositionFollowedByEmoticon(CharSequence body, int pos) { + if (body.length() <= pos + 1) { + return false; + } else { + final char first = body.charAt(pos + 1); + return first == ';' + || first == ':' + || closingBeforeWhitespace(body, pos + 1); + } + } - private static boolean closingBeforeWhitespace(CharSequence body, int pos) { - for (int i = pos; i < body.length(); ++i) { - final char c = body.charAt(i); - if (Character.isWhitespace(c)) { - return false; - } else if (c == '<' || c == '>') { - return body.length() == i + 1 || Character.isWhitespace(body.charAt(i + 1)); - } - } - return false; - } + private static boolean closingBeforeWhitespace(CharSequence body, int pos) { + for (int i = pos; i < body.length(); ++i) { + final char c = body.charAt(i); + if (Character.isWhitespace(c)) { + return false; + } else if (c == '<' || c == '>') { + return body.length() == i + 1 || Character.isWhitespace(body.charAt(i + 1)); + } + } + return false; + } - public static boolean isPositionFollowedByQuote(CharSequence body, int pos) { - if (body.length() <= pos + 1 || Character.isWhitespace(body.charAt(pos + 1))) { - return false; - } - boolean previousWasWhitespace = false; - for (int i = pos + 1; i < body.length(); i++) { - char c = body.charAt(i); - if (c == '\n' || c == '»') { - return false; - } else if (c == '«' && !previousWasWhitespace) { - return true; - } else { - previousWasWhitespace = Character.isWhitespace(c); - } - } - return false; - } + public static boolean isPositionFollowedByQuote(CharSequence body, int pos) { + if (body.length() <= pos + 1 || Character.isWhitespace(body.charAt(pos + 1))) { + return false; + } + boolean previousWasWhitespace = false; + for (int i = pos + 1; i < body.length(); i++) { + char c = body.charAt(i); + if (c == '\n' || c == '»') { + return false; + } else if (c == '«' && !previousWasWhitespace) { + return true; + } else { + previousWasWhitespace = Character.isWhitespace(c); + } + } + return false; + } - public static String getDisplayName(MucOptions.User user) { - Contact contact = user.getContact(); - if (contact != null) { - return contact.getDisplayName(); - } else { - final String name = user.getName(); - if (name != null) { - return name; - } - final Jid realJid = user.getRealJid(); - if (realJid != null) { - return JidHelper.localPartOrFallback(realJid); - } - return null; - } - } + public static String getDisplayName(MucOptions.User user) { + Contact contact = user.getContact(); + if (contact != null) { + return contact.getDisplayName(); + } else { + final String name = user.getName(); + if (name != null) { + return name; + } + final Jid realJid = user.getRealJid(); + if (realJid != null) { + return JidHelper.localPartOrFallback(realJid); + } + return null; + } + } - public static String concatNames(List users) { - return concatNames(users, users.size()); - } + public static String concatNames(List users) { + return concatNames(users, users.size()); + } - public static String concatNames(List users, int max) { - StringBuilder builder = new StringBuilder(); - final boolean shortNames = users.size() >= 3; - for (int i = 0; i < Math.min(users.size(), max); ++i) { - if (builder.length() != 0) { - builder.append(", "); - } - final String name = UIHelper.getDisplayName(users.get(i)); - if (name != null) { - builder.append(shortNames ? name.split("\\s+")[0] : name); - } - } - return builder.toString(); - } + public static String concatNames(List users, int max) { + StringBuilder builder = new StringBuilder(); + final boolean shortNames = users.size() >= 3; + for (int i = 0; i < Math.min(users.size(), max); ++i) { + if (builder.length() != 0) { + builder.append(", "); + } + final String name = UIHelper.getDisplayName(users.get(i)); + if (name != null) { + builder.append(shortNames ? name.split("\\s+")[0] : name); + } + } + return builder.toString(); + } - public static String getFileDescriptionString(final Context context, final Message message) { - if (message.getType() == Message.TYPE_IMAGE) { - return context.getString(R.string.image); - } - final String mime = message.getMimeType(); - if (mime == null) { - return context.getString(R.string.file); - } else if (mime.startsWith("audio/")) { - return context.getString(R.string.audio); - } else if (mime.startsWith("video/")) { - return context.getString(R.string.video); - } else if (mime.equals("image/gif")) { - return context.getString(R.string.gif); - } else if (mime.startsWith("image/")) { - return context.getString(R.string.image); - } else if (mime.contains("pdf")) { - return context.getString(R.string.pdf_document); - } else if (mime.equals("application/vnd.android.package-archive")) { - return context.getString(R.string.apk); - } else if (mime.equals(ExportBackupService.MIME_TYPE)) { - return context.getString(R.string.conversations_backup); - } else if (mime.contains("vcard")) { - return context.getString(R.string.vcard); - } else if (mime.equals("text/x-vcalendar") || mime.equals("text/calendar")) { - return context.getString(R.string.event); - } else if (mime.equals("application/epub+zip") || mime.equals("application/vnd.amazon.mobi8-ebook")) { - return context.getString(R.string.ebook); - } else { - return mime; - } - } + public static String getFileDescriptionString(final Context context, final Message message) { + if (message.getType() == Message.TYPE_IMAGE) { + return context.getString(R.string.image); + } + final String mime = message.getMimeType(); + if (mime == null) { + return context.getString(R.string.file); + } else if (mime.startsWith("audio/")) { + return context.getString(R.string.audio); + } else if (mime.startsWith("video/")) { + return context.getString(R.string.video); + } else if (mime.equals("image/gif")) { + return context.getString(R.string.gif); + } else if (mime.startsWith("image/")) { + return context.getString(R.string.image); + } else if (mime.contains("pdf")) { + return context.getString(R.string.pdf_document); + } else if (mime.equals("application/vnd.android.package-archive")) { + return context.getString(R.string.apk); + } else if (mime.equals(ExportBackupService.MIME_TYPE)) { + return context.getString(R.string.conversations_backup); + } else if (mime.contains("vcard")) { + return context.getString(R.string.vcard); + } else if (mime.equals("text/x-vcalendar") || mime.equals("text/calendar")) { + return context.getString(R.string.event); + } else if (mime.equals("application/epub+zip") || mime.equals("application/vnd.amazon.mobi8-ebook")) { + return context.getString(R.string.ebook); + } else if (mime.equals("application/gpx+xml")) { + return context.getString(R.string.gpx_track); + } else { + return mime; + } + } - public static String getMessageDisplayName(final Message message) { - final Conversational conversation = message.getConversation(); - if (message.getStatus() == Message.STATUS_RECEIVED) { - final Contact contact = message.getContact(); - if (conversation.getMode() == Conversation.MODE_MULTI) { - if (contact != null) { - return contact.getDisplayName(); - } else { - return getDisplayedMucCounterpart(message.getCounterpart()); - } - } else { - return contact != null ? contact.getDisplayName() : ""; - } - } else { - if (conversation instanceof Conversation && conversation.getMode() == Conversation.MODE_MULTI) { - return ((Conversation) conversation).getMucOptions().getSelf().getName(); - } else { - final Jid jid = conversation.getAccount().getJid(); - return jid.getLocal() != null ? jid.getLocal() : jid.getDomain().toString(); - } - } - } + public static String getMessageDisplayName(final Message message) { + final Conversational conversation = message.getConversation(); + if (message.getStatus() == Message.STATUS_RECEIVED) { + final Contact contact = message.getContact(); + if (conversation.getMode() == Conversation.MODE_MULTI) { + if (contact != null) { + return contact.getDisplayName(); + } else { + return getDisplayedMucCounterpart(message.getCounterpart()); + } + } else { + return contact != null ? contact.getDisplayName() : ""; + } + } else { + if (conversation instanceof Conversation && conversation.getMode() == Conversation.MODE_MULTI) { + return ((Conversation) conversation).getMucOptions().getSelf().getName(); + } else { + final Jid jid = conversation.getAccount().getJid(); + return jid.getLocal() != null ? jid.getLocal() : jid.getDomain().toString(); + } + } + } - public static String getMessageHint(Context context, Conversation conversation) { - switch (conversation.getNextEncryption()) { - case Message.ENCRYPTION_NONE: - if (Config.multipleEncryptionChoices()) { - return context.getString(R.string.send_unencrypted_message); - } else { - return context.getString(R.string.send_message_to_x, conversation.getName()); - } - case Message.ENCRYPTION_AXOLOTL: - AxolotlService axolotlService = conversation.getAccount().getAxolotlService(); - if (axolotlService != null && axolotlService.trustedSessionVerified(conversation)) { - return context.getString(R.string.send_omemo_x509_message); - } else { - return context.getString(R.string.send_omemo_message); - } - case Message.ENCRYPTION_PGP: - return context.getString(R.string.send_pgp_message); - default: - return ""; - } - } + public static String getMessageHint(Context context, Conversation conversation) { + switch (conversation.getNextEncryption()) { + case Message.ENCRYPTION_NONE: + if (Config.multipleEncryptionChoices()) { + return context.getString(R.string.send_unencrypted_message); + } else { + return context.getString(R.string.send_message_to_x, conversation.getName()); + } + case Message.ENCRYPTION_AXOLOTL: + AxolotlService axolotlService = conversation.getAccount().getAxolotlService(); + if (axolotlService != null && axolotlService.trustedSessionVerified(conversation)) { + return context.getString(R.string.send_omemo_x509_message); + } else { + return context.getString(R.string.send_omemo_message); + } + case Message.ENCRYPTION_PGP: + return context.getString(R.string.send_pgp_message); + default: + return ""; + } + } - public static String getDisplayedMucCounterpart(final Jid counterpart) { - if (counterpart == null) { - return ""; - } else if (!counterpart.isBareJid()) { - return counterpart.getResource().trim(); - } else { - return counterpart.toString().trim(); - } - } + public static String getDisplayedMucCounterpart(final Jid counterpart) { + if (counterpart == null) { + return ""; + } else if (!counterpart.isBareJid()) { + return counterpart.getResource().trim(); + } else { + return counterpart.toString().trim(); + } + } - public static boolean receivedLocationQuestion(Message message) { - if (message == null - || message.getStatus() != Message.STATUS_RECEIVED - || message.getType() != Message.TYPE_TEXT) { - return false; - } - String body = message.getBody() == null ? null : message.getBody().trim().toLowerCase(Locale.getDefault()); - body = body.replace("?", "").replace("¿", ""); - return LOCATION_QUESTIONS.contains(body); - } + public static boolean receivedLocationQuestion(Message message) { + if (message == null + || message.getStatus() != Message.STATUS_RECEIVED + || message.getType() != Message.TYPE_TEXT) { + return false; + } + String body = message.getBody() == null ? null : message.getBody().trim().toLowerCase(Locale.getDefault()); + body = body.replace("?", "").replace("¿", ""); + return LOCATION_QUESTIONS.contains(body); + } - public static ListItem.Tag getTagForStatus(Context context, Presence.Status status) { - switch (status) { - case CHAT: - return new ListItem.Tag(context.getString(R.string.presence_chat), 0xff259b24); - case AWAY: - return new ListItem.Tag(context.getString(R.string.presence_away), 0xffff9800); - case XA: - return new ListItem.Tag(context.getString(R.string.presence_xa), 0xfff44336); - case DND: - return new ListItem.Tag(context.getString(R.string.presence_dnd), 0xfff44336); - default: - return new ListItem.Tag(context.getString(R.string.presence_online), 0xff259b24); - } - } + public static ListItem.Tag getTagForStatus(Context context, Presence.Status status) { + switch (status) { + case CHAT: + return new ListItem.Tag(context.getString(R.string.presence_chat), 0xff259b24); + case AWAY: + return new ListItem.Tag(context.getString(R.string.presence_away), 0xffff9800); + case XA: + return new ListItem.Tag(context.getString(R.string.presence_xa), 0xfff44336); + case DND: + return new ListItem.Tag(context.getString(R.string.presence_dnd), 0xfff44336); + default: + return new ListItem.Tag(context.getString(R.string.presence_online), 0xff259b24); + } + } - public static String filesizeToString(long size) { - if (size > (1.5 * 1024 * 1024)) { - return Math.round(size * 1f / (1024 * 1024)) + " MiB"; - } else if (size >= 1024) { - return Math.round(size * 1f / 1024) + " KiB"; - } else { - return size + " B"; - } - } + public static String filesizeToString(long size) { + if (size > (1.5 * 1024 * 1024)) { + return Math.round(size * 1f / (1024 * 1024)) + " MiB"; + } else if (size >= 1024) { + return Math.round(size * 1f / 1024) + " KiB"; + } else { + return size + " B"; + } + } } diff --git a/src/main/res/drawable-hdpi/baseline_tour_black_48.png b/src/main/res/drawable-hdpi/baseline_tour_black_48.png new file mode 100644 index 0000000000000000000000000000000000000000..3652cab68064566102120c5a2b07e60b5e22ed8d GIT binary patch literal 369 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2V6^abaSW+oe0z;?nUkYP`^STa z4j5&8o4la)-2oZo{U2V~3@d0>>jCTij+? zo1$#Hg!g8^wr%$3zB#ZT?J%7%_f7w1-V2e}`1-Zqf>=6Bwtp;`V>;PBFZuK19ELAG zxnN5ClD5%3{XNX3&Q*VVzH7gCxIE#W(c`~+-yAo-p!zX=pYraMx?>k~C*-MTw^Z2P zeAxOu`?|xf#W_mZuYUipDi+KCHBF4oVO<#Gl(IF9r|hpWTxEDFpWRR*>X3O{YQdjm v-hf?%!@|zf6MfYFG#)6-k#U+KK8h!_67b8Hy+({sCG_UaQwj8@7D^?@myie zySKHkIBLOzv#cL?U2!;&`QTYk#pX8-(;H`BKN6kBUd3^zM)96_!5qnqJD<$!8GE)| zUCydi%k=rwTI~ei>eW{qmhu+x&zb&y{?xOTY2T04%V&SuDxzU`jp^vIs0C9Uej8o8 zQoLs6^N8T{8<#za`2ELKp^-(%W5E}YXTUyUnhB* z*r&kL6mwW%xk9|3<@0x^EzfA4_+E3c`}XbIe0w)TR?3;%ND^lZ+G#m48@YWM7^Y?%Bq=JC_B z%q7b<_fIjG-e5F0H=%wmuf>dWsvGK0v+dbn;MeZ|fi+r%!L5Ti>_x#L>wWJd{z}z` zu-9x{SI2#qi{Y8(=Lr_aUp2V@zViRp{A5O;9~vD0UEBRUfQ^#_4j9DSwTiP@>Uiyd O@(iA?elF{r5}E*CV{8-v literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-mdpi/baseline_tour_white_48.png b/src/main/res/drawable-mdpi/baseline_tour_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..d220b1447547bc173a0cf9cf29e1ba447e4fbf07 GIT binary patch literal 277 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpUtJDx6%Ar*{orZcj&I7qaLCkj4e zNM!83Aj{O!Ct&5^{z9O73ZGy?zkt;NnS_gW9FsmO&s+ZgBjdA=4|`{}>&o?~TR$md z(tE&k=gcdnxtknV{8JnIf3bO`HqNZ&Ub}!@b;SV&r47rHxpWlfeA(l$rEj|C1+`sl zuPbIUDP9b{dHl5S3E|lM!#|sJ1Jrj_9sW5{_XF!qPk)BhAK6aNVA}1%TO{DXEtcTB z_@C6=E39=30_wSYUolVC?dAaSW+oe0xLDr^!*`_(N`% zDkXsqw%;8kizYfK2z9bBP0V;-`$e$#iy*IC^TY+>dK+Ipczo>a-t+m@pDpL@v{&|= zq~aOWy6?XYBZC410}F#g0|Ns`X+FcPdom8Yf1kO|e&JnQ@MQ*@c2g*@CpZ(@A-p9*u?q}G~s+Zq?{VX#)w*AWi{`yJl^1n5F z~h3z<=?!$J_}K5C0~X zG&sJxx8u<7*)JG2U)fvQ`u+aruS(1^LEEc-`c3`UmKo7dr2q0;nCSic?(9EKeJ^=@ z{e1D$`A%&U8MzLH{^vY>O8(zbiQksL0@^AIKGxPxd>`?5Z?_@ag>TD%K9h4eoNa%M z;a0z4gV8YtB_LHB!;s9g;0{}ZVIFrv596Ev%)np}U|?WkZ~z7eFrXoUgH6x@7=V-B ay=M2VIWv3vZ^KLmAnVC?dAaSW+oe0xoBf>WSK`$vTn znjD8(YYy4)G%N5NR^T{X`u(JO%o+8Vh?t0)4{N9ByqSG(uW|abx$n)3|DLJ&u%CJA zBo)s|F5Qhh2@GHL8i1ta0S2Y*{LDvgNhq8%H!yOTQ*N$s?F_@m$I|CN@;>{)R$S9; zx$mIN{e+*#t}~QBU^vtG^097%@CQ+YeVI%q2jnFF6`$s?VDHI)&untwQS0n$SIke# zBwT;EuK4Z8vr-SPeOwoK)b~aT-v-?sZ$q+cjM-<1-PyLnbYCX3$UU=O*?49j4RcRf z1_|*yX3OswRyUL$%w<1S%XIh*<2u>*QcUHqB9`%f*zl_0`n)Q=o6LV0^7ZTNrC((> zcs^q|&$0Sj^$kYeudl~O|lO-B!FRH)WDd+zXwWmgWIPw!p|?@O1TaS?83{1ORF`wl)9& literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xxhdpi/baseline_tour_black_48.png b/src/main/res/drawable-xxhdpi/baseline_tour_black_48.png new file mode 100644 index 0000000000000000000000000000000000000000..ade2fdb4dc8fa215bd8410ff02dd8edd2f9a581a GIT binary patch literal 662 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=Dgt~$T!Hj}0MQd39YBjUN`m}? z8U7y*f6dXYv44KBg@R4=^3VA!JoVcJWKK_Bz4>wc?RE*1=jZ*e&n{oOj(ZCO1LIOp z7srqa#<#av^Ozk4TrR%5aoXl|+PA;{63@<5xyWu^^Gm&Al2=U2JL?t!r$4$43``sf zjSNg4Hq+iZN@pzNG5J2Fu_lO(Yf7V25Zf$G=Cih`3iGElGNmqfy3(w0s`d($vC!1u%Nmi}TyR*bW>Pp#{wRHu4Q4%InzXJCb z_(Vx;G5NB(3dj)Ivg)OO?aO&vBr<%bNqt|k)Ir*L+N(>pnTi*ttr30a$=ztQY1(de zU6xlTqn^#%BGB<>={wK=`YWDy24!C8Tcc`oF-&TUdbXi|iNT=-ZEIX@LUnkoCg~bK zUm2AsF#kl*(aTE@E!dnYa(B-1+g!~*oc0^*-hYwM;#l+dt>n+NjV2xXZTmv?f0nJa z=r|vL+U&LHZm*+`XO5@sSAMnmZQI>kR)=#gX=j6u-f~!LCb0aLLv-$f=0LVb5z;HJ zvONls&RES`VsOeqCYyQdEr&T-%(+J$KW$FCnUuTW+q`oc42&!S4tNM)sBlFzsbGA2i#3ngQNZQmyBnu%PN#kQ>o4)_OqGl5)-}J>D<*lxw7j!!5pepW+rYrY zq0q>{N+VP1f(cU^(@r@Q`%9is zPhH?3siBg(V5ZT9JCoVZF1GNztfTK$_I$EQMx12T`n)?!9Hg$4eOX&q;1?xfBK0e9 zZ-Gyg#1@k;tE+$vku9rU`q#dkw?!hucbe4qB}*Noou|FJWSgmYVcHtecb?phMw_PX zR@Y^Dbu#MNye$G9Z_d1p}Og}ybaHW$OBwy0+t`j;3STF|z})h1Mj$7+(U z@$;2Yi30Oa1RcG+^w5IMsUmmhEWgdw{KIL#vF`mB2`!E_f8R>}OxtMEq2IPIRR3q$ zT8obJ@u$sRi|+P1>UidO+J5C%o8PwG&1H2s=aP0d=;$qnwPpg#Z#hKgE@%#9dlVtP z;wsyt5b2E7yd?&w9AvVYx88D?lf|5S)bZ2iw3|t}3%<=er@_F;BH)0B0ERlpLiM$( W3iYz-fh&NK%;4$j=d#Wzp$PzyiBvQI literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xxxhdpi/baseline_tour_black_48.png b/src/main/res/drawable-xxxhdpi/baseline_tour_black_48.png new file mode 100644 index 0000000000000000000000000000000000000000..d5c00c8afe7e86a49f95403ab078b5df4df91076 GIT binary patch literal 809 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE8Azrw%`pX16#+gWu0VP~fanR24xq&vB|(0{ z4F3;@zvk%H*kA5%pG#P{Fr0<#@HUpIIzQystFgk|ye+v%b88)_IBm@GV9 z978G?-<;pc%j77+dXWA9jFa|BH8M6!u9c+*{B)h9;yEcUo=3tU;Xnf;GaHYMdBTAM z^Y^}NY+|o^(8z03@Sst;V!?w(xrzj4ewm5~Y;qbE3)tmu9AIXb+tJ9*CHJC{-R#4G zM)tf15G}r+7S8LN#@n_~gXjIy9!C~08P(85U;pJ-ygMhe*!NQ5#U9RH)a2sX9h)yW)EKYeG2>8EGU|D;ERsD=+%zalMUSy=dH7=Pt-eb z{nG8Nr($PtTdYf6pj4iy_du=r>D-tCM!TYf$`esDxHD8Psbwc>JusN;p_UGm*1Nb( zlDn9(*X6cCs3V(=$}C@fAGRw(xpU)Y@Jy(9wi{@(R40#gfY%mLAxpCdS{J8zJYkj$ z@Yuo{6lwH8^P-x^)k%z@6FgKeN$N3pcW!aFa%U@XWV3!d;T*djgTCY$MRjkskYdRf zH7o8Xv>1r}l@| ze3S@2%}^6!+nuc$WIyXSqq1?$fpW{Y4DwT$6Sgu(y=9Pi%dlMbL30tqnlgvgvJ8u5 zA8cW+3E*qE%9pW~IbjR)oU#V~Q;ZvKF|I9R=qYQs%=f|3k|E4`!Qb5bd@P_;%JMUs szet*8gQ66+H2Z)ZnmdKI;Vst0A3>moB#j- literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xxxhdpi/baseline_tour_white_48.png b/src/main/res/drawable-xxxhdpi/baseline_tour_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..bf6ee424cc73718a00d84ac28f2b5a94886144fb GIT binary patch literal 809 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE8Azrw%`pX16#+gWu0Z<#K!9T_o~!}dtx*!> z7tHYgaQJJEZjJrr{uT;0!S(0g=SzJ5-7YZO;q!Ha=Q7pt>rGe|Z@--$TEC%&fq}`w z)5S5Qg7MAyoxDtrBCH45|IavSpHw4bv*cP?YQRs|Nh+R`;^KKE3=$4BFfz08*qA3A zI52|Am$8rjW0 z9B5?EdjQem`)T34zG=K|3pIG&FYR$;@sd#uUG()|e#N_UGK+mL6>d!XpZ_8DPtAdp zjWLp&x6OY0qxEOQ-F;K`pLu3blxX(gh2N*JpUr}zIS0Pz$ctX>Xg%4`J#pSTyZS`E z1J^Iz-g+u_2Din!)CEfAiFyyznxD>%DPXiKN~k;$HG?}t<&s)T{Td0d^u7&^g2^^&9>gLmf^cPn?c5=S=cw-e5>>oMp{o>5fyW(z5n zd{N`#rz_d;PG#>*%}+)t3~GCuel?wuk#5M-lV59F^tqAO;VajtYj4V2>Zb8A?0RZ{ zXw657;L{8>A-3JwnnCunelsc?*BmIfe9Is|g*jm>bJSY~iMI^PWgj#bF{~+bSS`!2 zSoXmd=9&P$hO2xTTbUEKFwZG#;6KH<;TGfCGKQYAhRb{(94#5btQY*vz0b!2Oe_p6 vKco4Jq**p7N`ZLj-~l_j2%J9wm?V}k%vf*wXpyv25=hw7)z4*}Q$iB}pp$xd literal 0 HcmV?d00001 diff --git a/src/main/res/values/attrs.xml b/src/main/res/values/attrs.xml index e67517049..fc05b1696 100644 --- a/src/main/res/values/attrs.xml +++ b/src/main/res/values/attrs.xml @@ -66,6 +66,7 @@ + diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 1e46347c6..9b6568a15 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -925,6 +925,7 @@ Could not switch camera Add to favorites Remove from favorites + GPX track View %1$d Participant View %1$d Participants diff --git a/src/main/res/values/themes.xml b/src/main/res/values/themes.xml index 8def180d8..c9d20fcd8 100644 --- a/src/main/res/values/themes.xml +++ b/src/main/res/values/themes.xml @@ -85,6 +85,7 @@ @drawable/ic_mic_black_48dp @drawable/ic_headset_black_48dp @drawable/ic_room_black_48dp + @drawable/baseline_tour_black_48 @drawable/ic_person_black_48dp @drawable/ic_android_black_48dp @drawable/ic_event_black_48dp @@ -240,6 +241,7 @@ @drawable/ic_mic_white_48dp @drawable/ic_headset_white_48dp @drawable/ic_room_white_48dp + @drawable/baseline_tour_white_48 @drawable/ic_person_white_48dp @drawable/ic_android_white_48dp @drawable/ic_event_white_48dp