mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-10-02 18:02:41 +01:00
Add a megaphone to celebrate Valentine's Day.
This commit is contained in:
1 parent
65af5f0849
commit
597cf3f576
5 files changed
+142
-18
No files matched your search
@@ -7,6 +7,7 @@ import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
@@ -15,7 +16,6 @@ import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.badges.models.Badge;
|
||||
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity;
|
||||
import org.thoughtcrime.securesms.conversationlist.ConversationListFragment;
|
||||
import org.thoughtcrime.securesms.database.model.MegaphoneRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
@@ -24,37 +24,38 @@ import org.thoughtcrime.securesms.lock.SignalPinReminderDialog;
|
||||
import org.thoughtcrime.securesms.lock.SignalPinReminders;
|
||||
import org.thoughtcrime.securesms.lock.v2.CreateKbsPinActivity;
|
||||
import org.thoughtcrime.securesms.lock.v2.KbsMigrationActivity;
|
||||
import org.thoughtcrime.securesms.messagerequests.MessageRequestMegaphoneActivity;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.profiles.manage.ManageProfileActivity;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.LocaleFeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.PlayServicesUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.SetUtil;
|
||||
import org.thoughtcrime.securesms.util.VersionTracker;
|
||||
import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageContextWrapper;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperActivity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.Month;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Creating a new megaphone:
|
||||
* - Add an enum to {@link Event}
|
||||
* - Return a megaphone in {@link #forRecord(Context, MegaphoneRecord)}
|
||||
* - Include the event in {@link #buildDisplayOrder(Context)}
|
||||
* - Include the event in {@link #buildDisplayOrder(Context, Map)}
|
||||
*
|
||||
* Common patterns:
|
||||
* - For events that have a snooze-able recurring display schedule, use a {@link RecurringSchedule}.
|
||||
* - For events guarded by feature flags, set a {@link ForeverSchedule} with false in
|
||||
* {@link #buildDisplayOrder(Context)}.
|
||||
* {@link #buildDisplayOrder(Context, Map)}.
|
||||
* - For events that change, return different megaphones in {@link #forRecord(Context, MegaphoneRecord)}
|
||||
* based on whatever properties you're interested in.
|
||||
*/
|
||||
@@ -65,12 +66,16 @@ public final class Megaphones {
|
||||
private static final MegaphoneSchedule ALWAYS = new ForeverSchedule(true);
|
||||
private static final MegaphoneSchedule NEVER = new ForeverSchedule(false);
|
||||
|
||||
private static final Set<Event> DONATE_EVENTS = SetUtil.newHashSet(Event.VALENTINES_DONATIONS_2022, Event.BECOME_A_SUSTAINER);
|
||||
private static final long MIN_TIME_BETWEEN_DONATE_MEGAPHONES = TimeUnit.DAYS.toMillis(30);
|
||||
|
||||
private Megaphones() {}
|
||||
|
||||
@WorkerThread
|
||||
static @Nullable Megaphone getNextMegaphone(@NonNull Context context, @NonNull Map<Event, MegaphoneRecord> records) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
List<Megaphone> megaphones = Stream.of(buildDisplayOrder(context))
|
||||
List<Megaphone> megaphones = Stream.of(buildDisplayOrder(context, records))
|
||||
.filter(e -> {
|
||||
MegaphoneRecord record = Objects.requireNonNull(records.get(e.getKey()));
|
||||
MegaphoneSchedule schedule = e.getValue();
|
||||
@@ -95,13 +100,14 @@ public final class Megaphones {
|
||||
*
|
||||
* This is also when you would hide certain megaphones based on things like {@link FeatureFlags}.
|
||||
*/
|
||||
private static Map<Event, MegaphoneSchedule> buildDisplayOrder(@NonNull Context context) {
|
||||
private static Map<Event, MegaphoneSchedule> buildDisplayOrder(@NonNull Context context, @NonNull Map<Event, MegaphoneRecord> records) {
|
||||
return new LinkedHashMap<Event, MegaphoneSchedule>() {{
|
||||
put(Event.PINS_FOR_ALL, new PinsForAllSchedule());
|
||||
put(Event.CLIENT_DEPRECATED, SignalStore.misc().isClientDeprecated() ? ALWAYS : NEVER);
|
||||
put(Event.NOTIFICATIONS, shouldShowNotificationsMegaphone(context) ? RecurringSchedule.every(TimeUnit.DAYS.toMillis(30)) : NEVER);
|
||||
put(Event.ONBOARDING, shouldShowOnboardingMegaphone(context) ? ALWAYS : NEVER);
|
||||
put(Event.BECOME_A_SUSTAINER, shouldShowDonateMegaphone(context) ? ShowForDurationSchedule.showForDays(7) : NEVER);
|
||||
put(Event.BECOME_A_SUSTAINER, shouldShowDonateMegaphone(context, records) ? ShowForDurationSchedule.showForDays(7) : NEVER);
|
||||
put(Event.VALENTINES_DONATIONS_2022, shouldShowValentinesDonationsMegaphone(context, records) ? ShowForDurationSchedule.showForDays(1) : NEVER);
|
||||
put(Event.PIN_REMINDER, new SignalPinReminderSchedule());
|
||||
|
||||
// Feature-introduction megaphones should *probably* be added below this divider
|
||||
@@ -129,6 +135,8 @@ public final class Megaphones {
|
||||
return buildAddAProfilePhotoMegaphone(context);
|
||||
case BECOME_A_SUSTAINER:
|
||||
return buildBecomeASustainerMegaphone(context);
|
||||
case VALENTINES_DONATIONS_2022:
|
||||
return buildValentinesDonationsMegaphone(context);
|
||||
case NOTIFICATION_PROFILES:
|
||||
return buildNotificationProfilesMegaphone(context);
|
||||
default:
|
||||
@@ -275,6 +283,21 @@ public final class Megaphones {
|
||||
.build();
|
||||
}
|
||||
|
||||
private static @NonNull Megaphone buildValentinesDonationsMegaphone(@NonNull Context context) {
|
||||
return new Megaphone.Builder(Event.VALENTINES_DONATIONS_2022, Megaphone.Style.BASIC)
|
||||
.setTitle(R.string.ValentinesDayMegaphone_happy_heart_day)
|
||||
.setImage(R.drawable.ic_valentines_donor_megaphone_64)
|
||||
.setBody(R.string.ValentinesDayMegaphone_show_your_affection)
|
||||
.setActionButton(R.string.BecomeASustainerMegaphone__contribute, (megaphone, listener) -> {
|
||||
listener.onMegaphoneNavigationRequested(AppSettingsActivity.subscriptions(context));
|
||||
listener.onMegaphoneCompleted(Event.VALENTINES_DONATIONS_2022);
|
||||
})
|
||||
.setSecondaryButton(R.string.BecomeASustainerMegaphone__no_thanks, (megaphone, listener) -> {
|
||||
listener.onMegaphoneCompleted(Event.VALENTINES_DONATIONS_2022);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
private static @NonNull Megaphone buildNotificationProfilesMegaphone(@NonNull Context context) {
|
||||
return new Megaphone.Builder(Event.NOTIFICATION_PROFILES, Megaphone.Style.BASIC)
|
||||
.setTitle(R.string.NotificationProfilesMegaphone__notification_profiles)
|
||||
@@ -290,15 +313,36 @@ public final class Megaphones {
|
||||
.build();
|
||||
}
|
||||
|
||||
private static boolean shouldShowDonateMegaphone(@NonNull Context context) {
|
||||
return VersionTracker.getDaysSinceFirstInstalled(context) >= 7 &&
|
||||
private static boolean shouldShowDonateMegaphone(@NonNull Context context, @NonNull Map<Event, MegaphoneRecord> records) {
|
||||
long timeSinceLastDonatePrompt = timeSinceLastDonatePrompt(records);
|
||||
|
||||
return timeSinceLastDonatePrompt > MIN_TIME_BETWEEN_DONATE_MEGAPHONES &&
|
||||
VersionTracker.getDaysSinceFirstInstalled(context) >= 7 &&
|
||||
LocaleFeatureFlags.isInDonateMegaphone() &&
|
||||
PlayServicesUtil.getPlayServicesStatus(context) == PlayServicesUtil.PlayServicesStatus.SUCCESS &&
|
||||
Recipient.self()
|
||||
.getBadges()
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.noneMatch(badge -> badge.getCategory() == Badge.Category.Donor);
|
||||
.getBadges()
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.noneMatch(badge -> badge.getCategory() == Badge.Category.Donor);
|
||||
}
|
||||
|
||||
private static boolean shouldShowValentinesDonationsMegaphone(@NonNull Context context, @NonNull Map<Event, MegaphoneRecord> records) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
long timeSinceLastDonatePrompt = timeSinceLastDonatePrompt(records);
|
||||
|
||||
return timeSinceLastDonatePrompt > MIN_TIME_BETWEEN_DONATE_MEGAPHONES &&
|
||||
VersionTracker.getDaysSinceFirstInstalled(context) >= 7 &&
|
||||
LocaleFeatureFlags.isInValentinesDonateMegaphone() &&
|
||||
now.getMonth() == Month.FEBRUARY &&
|
||||
now.getDayOfMonth() == 14 &&
|
||||
now.getYear() == 2022 &&
|
||||
PlayServicesUtil.getPlayServicesStatus(context) == PlayServicesUtil.PlayServicesStatus.SUCCESS &&
|
||||
Recipient.self()
|
||||
.getBadges()
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.noneMatch(badge -> badge.getCategory() == Badge.Category.Donor);
|
||||
}
|
||||
|
||||
private static boolean shouldShowOnboardingMegaphone(@NonNull Context context) {
|
||||
@@ -316,7 +360,8 @@ public final class Megaphones {
|
||||
.textExistsInUsersLanguage(R.string.NotificationsMegaphone_turn_on_notifications,
|
||||
R.string.NotificationsMegaphone_never_miss_a_message,
|
||||
R.string.NotificationsMegaphone_turn_on,
|
||||
R.string.NotificationsMegaphone_not_now)) {
|
||||
R.string.NotificationsMegaphone_not_now))
|
||||
{
|
||||
Log.i(TAG, "Would show NotificationsMegaphone but is not yet translated in " + locale);
|
||||
return false;
|
||||
}
|
||||
@@ -338,6 +383,23 @@ public final class Megaphones {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unfortunately lastSeen is only set today upon snoozing, which never happens to donate prompts.
|
||||
* So we use firstVisible as a proxy.
|
||||
*/
|
||||
private static long timeSinceLastDonatePrompt(@NonNull Map<Event, MegaphoneRecord> records) {
|
||||
long lastSeenDonatePrompt = records.entrySet()
|
||||
.stream()
|
||||
.filter(e -> DONATE_EVENTS.contains(e.getKey()))
|
||||
.map(e -> e.getValue().getFirstVisible())
|
||||
.filter(t -> t > 0)
|
||||
.sorted()
|
||||
.findFirst()
|
||||
.orElse(0L);
|
||||
return System.currentTimeMillis() - lastSeenDonatePrompt;
|
||||
}
|
||||
|
||||
|
||||
public enum Event {
|
||||
PINS_FOR_ALL("pins_for_all"),
|
||||
PIN_REMINDER("pin_reminder"),
|
||||
@@ -347,6 +409,7 @@ public final class Megaphones {
|
||||
CHAT_COLORS("chat_colors"),
|
||||
ADD_A_PROFILE_PHOTO("add_a_profile_photo"),
|
||||
BECOME_A_SUSTAINER("become_a_sustainer"),
|
||||
VALENTINES_DONATIONS_2022("valentines_donations_2022"),
|
||||
NOTIFICATION_PROFILES("notification_profiles");
|
||||
|
||||
private final String key;
|
||||
|
||||
@@ -63,6 +63,7 @@ public final class FeatureFlags {
|
||||
private static final String PHONE_NUMBER_PRIVACY_VERSION = "android.phoneNumberPrivacyVersion";
|
||||
private static final String CLIENT_EXPIRATION = "android.clientExpiration";
|
||||
public static final String DONATE_MEGAPHONE = "android.donate.2";
|
||||
public static final String VALENTINES_DONATE_MEGAPHONE = "android.donate.valentines.2022";
|
||||
private static final String CUSTOM_VIDEO_MUXER = "android.customVideoMuxer";
|
||||
private static final String CDS_REFRESH_INTERVAL = "cds.syncInterval.seconds";
|
||||
private static final String AUTOMATIC_SESSION_RESET = "android.automaticSessionReset.2";
|
||||
@@ -132,7 +133,8 @@ public final class FeatureFlags {
|
||||
DONOR_BADGES_DISPLAY,
|
||||
CHANGE_NUMBER_ENABLED,
|
||||
HARDWARE_AEC_MODELS,
|
||||
FORCE_DEFAULT_AEC
|
||||
FORCE_DEFAULT_AEC,
|
||||
VALENTINES_DONATE_MEGAPHONE
|
||||
);
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -187,7 +189,8 @@ public final class FeatureFlags {
|
||||
SENDER_KEY_MAX_AGE,
|
||||
DONOR_BADGES_DISPLAY,
|
||||
DONATE_MEGAPHONE,
|
||||
FORCE_DEFAULT_AEC
|
||||
FORCE_DEFAULT_AEC,
|
||||
VALENTINES_DONATE_MEGAPHONE
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -303,6 +306,11 @@ public final class FeatureFlags {
|
||||
return getString(DONATE_MEGAPHONE, "");
|
||||
}
|
||||
|
||||
/** The raw valentine's day donate megaphone CSV string */
|
||||
public static String valentinesDonateMegaphone() {
|
||||
return getString(VALENTINES_DONATE_MEGAPHONE, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the user can choose phone number privacy settings, and;
|
||||
* Whether to fetch and store the secondary certificate
|
||||
|
||||
@@ -37,6 +37,13 @@ public final class LocaleFeatureFlags {
|
||||
return isEnabled(FeatureFlags.DONATE_MEGAPHONE, FeatureFlags.donateMegaphone());
|
||||
}
|
||||
|
||||
/**
|
||||
* In valentines donation megaphone group for given country code
|
||||
*/
|
||||
public static boolean isInValentinesDonateMegaphone() {
|
||||
return isEnabled(FeatureFlags.VALENTINES_DONATE_MEGAPHONE, FeatureFlags.valentinesDonateMegaphone());
|
||||
}
|
||||
|
||||
public static @NonNull Optional<PushMediaConstraints.MediaConfig> getMediaQualityLevel() {
|
||||
Map<String, Integer> countryValues = parseCountryValues(FeatureFlags.getMediaQualityLevels(), NOT_FOUND);
|
||||
int level = getCountryValue(countryValues, Recipient.self().getE164().or(""), NOT_FOUND);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="64dp"
|
||||
android:height="64dp"
|
||||
android:viewportWidth="64"
|
||||
android:viewportHeight="64">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M32,0L32,0A32,32 0,0 1,64 32L64,32A32,32 0,0 1,32 64L32,64A32,32 0,0 1,0 32L0,32A32,32 0,0 1,32 0z"/>
|
||||
<path
|
||||
android:pathData="M32,0L32,0A32,32 0,0 1,64 32L64,32A32,32 0,0 1,32 64L32,64A32,32 0,0 1,0 32L0,32A32,32 0,0 1,32 0z"
|
||||
android:fillColor="#DC8787"/>
|
||||
<path
|
||||
android:pathData="M32.1645,23.2543L48,34.0159L17.1019,34.0159L32.1645,23.2543Z"
|
||||
android:fillColor="#C9C9C9"/>
|
||||
<path
|
||||
android:pathData="M17,34h31v19h-31z"
|
||||
android:fillColor="#C9C9C9"/>
|
||||
<path
|
||||
android:pathData="M33.5,43L48,34L48,52L33.5,43Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M31.5,43L17,34L17,52L31.5,43Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M30.87,35.65C30.34,35.29 18,26.71 18,17.82C18.0006,16.2593 18.4748,14.7354 19.36,13.45C20.265,12.1588 21.5313,11.1638 23,10.59C24.4552,10.0023 26.0497,9.8495 27.59,10.15C29.1317,10.4404 30.554,11.1776 31.68,12.27L32.04,12.62L32.43,12.25C33.1695,11.5335 34.0428,10.9694 35,10.59C36.9504,9.8037 39.1296,9.8037 41.08,10.59C42.0495,10.9721 42.9333,11.5432 43.68,12.27C44.4236,12.9921 45.0152,13.8558 45.42,14.81C45.8276,15.7577 46.0385,16.7783 46.04,17.81C46.04,26.7 33.7,35.28 33.17,35.64L32,36.43L30.87,35.65Z"
|
||||
android:fillColor="#F5D7D7"/>
|
||||
<path
|
||||
android:pathData="M26,12C26.3925,12.0014 26.7841,12.0382 27.17,12.11C28.3305,12.3322 29.401,12.8883 30.25,13.71C30.8923,14.3227 31.478,14.9921 32,15.71C32.5221,14.9921 33.1078,14.3227 33.75,13.71C34.8878,12.6049 36.414,11.9909 38,12V12C38.7876,12 39.5681,12.1493 40.3,12.44C41.0231,12.7332 41.6821,13.1646 42.24,13.71C42.7921,14.2435 43.2321,14.8819 43.5343,15.5876C43.8365,16.2933 43.9948,17.0523 44,17.82C44,25.76 32,34 32,34C32,34 20,25.76 20,17.82C19.9984,16.6669 20.3471,15.5405 21,14.59C21.67,13.6244 22.6089,12.8768 23.7,12.44C24.4319,12.149 25.2124,11.9997 26,12V12ZM26,8C24.7019,8.0014 23.4158,8.2491 22.21,8.73C20.3942,9.4614 18.833,10.7097 17.72,12.32C16.597,13.9339 15.9966,15.8538 16,17.82C16,22.2 18.4,26.87 23.15,31.69C25.1777,33.7499 27.3829,35.6272 29.74,37.3L32,38.85L34.26,37.3C36.6172,35.6272 38.8224,33.7499 40.85,31.69C45.6,26.87 48,22.2 48,17.82C48.0022,16.5134 47.7367,15.2201 47.22,14.02C46.7021,12.8211 45.947,11.7394 45,10.84C44.0664,9.934 42.9662,9.2175 41.76,8.73C40.1592,8.0956 38.4232,7.8792 36.7156,8.1014C35.008,8.3236 33.3852,8.977 32,10C30.7931,9.1126 29.4021,8.5077 27.93,8.23C27.2962,8.088 26.6495,8.011 26,8V8Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M31.91,26C33.9424,26 35.59,24.3524 35.59,22.32C35.59,20.2876 33.9424,18.64 31.91,18.64C29.8776,18.64 28.23,20.2876 28.23,22.32C28.23,24.3524 29.8776,26 31.91,26Z"
|
||||
android:fillColor="#FDF1C0"/>
|
||||
<path
|
||||
android:pathData="M33.36,18.4C32.5253,18.0913 31.614,18.057 30.7585,18.3022C29.903,18.5473 29.1481,19.0591 28.6036,19.763C28.0592,20.4669 27.7536,21.3262 27.7313,22.2159C27.709,23.1055 27.9713,23.979 28.4799,24.7093C28.9884,25.4396 29.7168,25.9884 30.5589,26.2761C31.4011,26.5637 32.313,26.5751 33.1621,26.3085C34.0111,26.0419 34.753,25.5114 35.2796,24.794C35.8062,24.0766 36.0901,23.2099 36.09,22.32C36.0871,21.4666 35.8243,20.6344 35.3366,19.9341C34.8489,19.2338 34.1594,18.6987 33.36,18.4ZM33,25.31C32.363,25.544 31.668,25.5688 31.016,25.3807C30.364,25.1927 29.789,24.8016 29.3744,24.2644C28.9599,23.7271 28.7275,23.0717 28.7109,22.3933C28.6944,21.7149 28.8947,21.049 29.2826,20.4922C29.6705,19.9354 30.2258,19.5168 30.8679,19.2972C31.51,19.0777 32.2053,19.0686 32.8529,19.2713C33.5005,19.474 34.0666,19.878 34.4689,20.4244C34.8712,20.9709 35.0888,21.6314 35.09,22.31C35.0869,22.963 34.8854,23.5996 34.5121,24.1354C34.1388,24.6712 33.6115,25.0808 33,25.31V25.31ZM29.07,14.37C29.0897,14.4349 29.0954,14.5031 29.0868,14.5704C29.0781,14.6376 29.0554,14.7022 29.02,14.76C28.9555,14.8703 28.8521,14.9524 28.73,14.99C28.5984,15.024 28.4588,15.0061 28.34,14.94C28.2822,14.9105 28.2337,14.8655 28.2,14.81C28.1604,14.7589 28.13,14.7014 28.11,14.64L27.74,13.71C27.7127,13.6486 27.6986,13.5822 27.6986,13.515C27.6986,13.4478 27.7127,13.3814 27.74,13.32C27.8087,13.2058 27.9194,13.123 28.0483,13.0894C28.1773,13.0557 28.3143,13.0739 28.43,13.14C28.4856,13.1726 28.5334,13.2169 28.57,13.27C28.6096,13.321 28.64,13.3786 28.66,13.44L29.02,14.37H29.07ZM30.26,17.11C30.2795,17.1732 30.2851,17.2399 30.2765,17.3055C30.2678,17.371 30.2452,17.434 30.21,17.49C30.1439,17.603 30.0362,17.6855 29.91,17.72C29.7784,17.754 29.6388,17.7361 29.52,17.67C29.4642,17.6377 29.4163,17.5933 29.38,17.54C29.3384,17.4903 29.3077,17.4324 29.29,17.37L28.93,16.44C28.9056,16.345 28.9096,16.245 28.9416,16.1523C28.9736,16.0596 29.0321,15.9784 29.1099,15.9187C29.1877,15.859 29.2813,15.8235 29.3791,15.8167C29.4769,15.8098 29.5746,15.8318 29.66,15.88C29.72,15.9063 29.7694,15.9521 29.8,16.01C29.8473,16.0557 29.8788,16.1152 29.89,16.18L30.26,17.11ZM34.79,28.22C34.8095,28.2832 34.8151,28.3499 34.8065,28.4155C34.7978,28.481 34.7752,28.544 34.74,28.6C34.7093,28.6556 34.6678,28.7046 34.6181,28.7441C34.5683,28.7836 34.5112,28.8128 34.45,28.83C34.3885,28.8567 34.3221,28.8705 34.255,28.8705C34.1879,28.8705 34.1215,28.8567 34.06,28.83C34.0022,28.8005 33.9537,28.7555 33.92,28.7C33.8763,28.6517 33.8453,28.5933 33.83,28.53C33.71,28.24 33.6,27.94 33.48,27.65C33.4501,27.5171 33.4715,27.3778 33.54,27.26C33.6045,27.1497 33.7079,27.0676 33.83,27.03C33.9616,26.996 34.1012,27.0139 34.22,27.08C34.2735,27.1153 34.3208,27.1592 34.36,27.21C34.3996,27.261 34.43,27.3186 34.45,27.38C34.56,27.68 34.68,27.97 34.79,28.27V28.22ZM35.79,30.57C35.8098,30.6589 35.8098,30.7511 35.79,30.84L35.74,30.96C35.6717,31.0709 35.5649,31.1528 35.44,31.19C35.3748,31.21 35.3052,31.21 35.24,31.19C35.172,31.1901 35.1056,31.1691 35.05,31.13C34.9923,31.0965 34.9414,31.0524 34.9,31C34.8604,30.9489 34.83,30.8914 34.81,30.83L34.52,30.11C34.4998,30.0211 34.4998,29.9289 34.52,29.84L34.57,29.72C34.6383,29.6091 34.7451,29.5272 34.87,29.49C34.9358,29.475 35.0042,29.475 35.07,29.49C35.133,29.4994 35.1939,29.5197 35.25,29.55C35.3078,29.5795 35.3563,29.6245 35.39,29.68C35.4367,29.7261 35.4681,29.7854 35.48,29.85L35.78,30.57H35.79ZM35.49,14.88C35.4727,14.9636 35.431,15.0402 35.37,15.1L35.26,15.18C35.1458,15.2456 35.0103,15.2635 34.883,15.2298C34.7557,15.1961 34.6468,15.1135 34.58,15C34.5448,14.944 34.5222,14.881 34.5135,14.8155C34.5049,14.7499 34.5105,14.6832 34.53,14.62L34.92,13.62C34.9345,13.5553 34.9617,13.4941 35,13.44L35.1,13.36C35.2253,13.3104 35.3647,13.3104 35.49,13.36C35.6121,13.3976 35.7155,13.4797 35.78,13.59C35.8494,13.7074 35.8709,13.8471 35.84,13.98C35.7,14.29 35.57,14.61 35.44,14.98L35.49,14.88ZM34.49,17.41C34.4734,17.4961 34.4274,17.5739 34.36,17.63L34.26,17.71C34.1381,17.7589 34.0019,17.7589 33.88,17.71C33.7551,17.6728 33.6483,17.5909 33.58,17.48C33.5409,17.4244 33.5199,17.358 33.52,17.29C33.5001,17.2282 33.5001,17.1618 33.52,17.1L33.85,16.29C33.8693,16.2021 33.9146,16.1219 33.98,16.06L34.08,15.99C34.1942,15.9244 34.3297,15.9065 34.457,15.9402C34.5843,15.9739 34.6932,16.0565 34.76,16.17C34.7989,16.2219 34.82,16.2851 34.82,16.35C34.84,16.4152 34.84,16.4848 34.82,16.55L34.49,17.36V17.41ZM29.86,28.41C29.8158,28.484 29.754,28.5458 29.68,28.59L29.56,28.64C29.4951,28.659 29.4269,28.6644 29.3598,28.6558C29.2926,28.6472 29.228,28.6248 29.17,28.59C29.0597,28.521 28.978,28.4144 28.94,28.29C28.9201,28.2282 28.9201,28.1618 28.94,28.1C28.9399,28.032 28.9609,27.9656 29,27.91L29.33,27.13C29.3742,27.056 29.436,26.9942 29.51,26.95L29.63,26.9C29.7615,26.886 29.8935,26.9217 30,27C30.108,27.0715 30.189,27.1771 30.23,27.3C30.25,27.3652 30.25,27.4348 30.23,27.5C30.229,27.5633 30.2118,27.6253 30.18,27.68C30.06,27.94 29.95,28.2 29.84,28.46L29.86,28.41ZM28.96,30.61C28.9383,30.6941 28.8932,30.7704 28.83,30.83L28.73,30.91C28.6731,30.9429 28.610Line truncated
|
||||
android:fillColor="#6D2313"/>
|
||||
<path
|
||||
android:pathData="M17,53L32.5,43.5114L48,53L17,53Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -1445,6 +1445,12 @@
|
||||
<string name="RedPhone_the_number_you_dialed_does_not_support_secure_voice">The number you dialed does not support secure voice!</string>
|
||||
<string name="RedPhone_got_it">Got it</string>
|
||||
|
||||
<!-- Valentine's Day Megaphone -->
|
||||
<!-- Title text for the Valentine's Day donation megaphone. The placeholder will always be a heart emoji. Needs to be a placeholder for Android reasons. -->
|
||||
<string name="ValentinesDayMegaphone_happy_heart_day">Happy 💜 Day!</string>
|
||||
<!-- Body text for the Valentine's Day donation megaphone. -->
|
||||
<string name="ValentinesDayMegaphone_show_your_affection">Show your affection by becoming a Signal sustainer.</string>
|
||||
|
||||
<!-- WebRtcCallActivity -->
|
||||
<string name="WebRtcCallActivity__tap_here_to_turn_on_your_video">Tap here to turn on your video</string>
|
||||
<string name="WebRtcCallActivity__to_call_s_signal_needs_access_to_your_camera">To call %1$s, Signal needs access to your camera</string>
|
||||
|
||||
Reference in new issue
Block a user