kopia lustrzana https://github.com/ryukoposting/Signal-Android
Add support for modern profile sharing.
rodzic
2cb912681d
commit
de7f103130
|
@ -3295,7 +3295,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||||
groupShareProfileView.get().setVisibility(View.GONE);
|
groupShareProfileView.get().setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DISPLAY_LEGACY:
|
case DISPLAY_PRE_MESSAGE_REQUEST:
|
||||||
if (recipient.get().isGroup()) {
|
if (recipient.get().isGroup()) {
|
||||||
groupShareProfileView.get().setRecipient(recipient.get());
|
groupShareProfileView.get().setRecipient(recipient.get());
|
||||||
groupShareProfileView.get().setVisibility(View.VISIBLE);
|
groupShareProfileView.get().setVisibility(View.VISIBLE);
|
||||||
|
|
|
@ -90,8 +90,10 @@ public class MultiDeviceReadUpdateJob extends BaseJob {
|
||||||
|
|
||||||
for (SerializableSyncMessageId messageId : messageIds) {
|
for (SerializableSyncMessageId messageId : messageIds) {
|
||||||
Recipient recipient = Recipient.resolved(RecipientId.from(messageId.recipientId));
|
Recipient recipient = Recipient.resolved(RecipientId.from(messageId.recipientId));
|
||||||
|
if (!recipient.isGroup()) {
|
||||||
readMessages.add(new ReadMessage(RecipientUtil.toSignalServiceAddress(context, recipient), messageId.timestamp));
|
readMessages.add(new ReadMessage(RecipientUtil.toSignalServiceAddress(context, recipient), messageId.timestamp));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
|
SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
|
||||||
messageSender.sendMessage(SignalServiceSyncMessage.forRead(readMessages), UnidentifiedAccessUtil.getAccessForSync(context));
|
messageSender.sendMessage(SignalServiceSyncMessage.forRead(readMessages), UnidentifiedAccessUtil.getAccessForSync(context));
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||||
|
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
|
@ -86,9 +87,11 @@ final class MessageRequestRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return MessageRequestState.REQUIRED;
|
||||||
|
} else if (FeatureFlags.modernProfileSharing() && !recipient.isPushV2Group() && !recipient.isProfileSharing()) {
|
||||||
return MessageRequestState.REQUIRED;
|
return MessageRequestState.REQUIRED;
|
||||||
} else if (RecipientUtil.isPreMessageRequestThread(context, threadId) && !RecipientUtil.isLegacyProfileSharingAccepted(recipient)) {
|
} else if (RecipientUtil.isPreMessageRequestThread(context, threadId) && !RecipientUtil.isLegacyProfileSharingAccepted(recipient)) {
|
||||||
return MessageRequestState.LEGACY;
|
return MessageRequestState.PRE_MESSAGE_REQUEST;
|
||||||
} else {
|
} else {
|
||||||
return MessageRequestState.NOT_REQUIRED;
|
return MessageRequestState.NOT_REQUIRED;
|
||||||
}
|
}
|
||||||
|
@ -230,6 +233,7 @@ final class MessageRequestRepository {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
boolean isPendingMember(@NonNull GroupId.V2 groupId) {
|
boolean isPendingMember(@NonNull GroupId.V2 groupId) {
|
||||||
return DatabaseFactory.getGroupDatabase(context).isPendingMember(groupId, Recipient.self());
|
return DatabaseFactory.getGroupDatabase(context).isPendingMember(groupId, Recipient.self());
|
||||||
}
|
}
|
||||||
|
@ -248,6 +252,7 @@ final class MessageRequestRepository {
|
||||||
/** Explicit message request permission is required. */
|
/** Explicit message request permission is required. */
|
||||||
REQUIRED,
|
REQUIRED,
|
||||||
|
|
||||||
LEGACY
|
/** This conversation existed before message requests and needs the old UI */
|
||||||
|
PRE_MESSAGE_REQUEST
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,15 @@ import androidx.lifecycle.Transformations;
|
||||||
import androidx.lifecycle.ViewModel;
|
import androidx.lifecycle.ViewModel;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason;
|
import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason;
|
||||||
import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver;
|
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||||
|
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||||
|
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||||
import org.thoughtcrime.securesms.util.SingleLiveEvent;
|
import org.thoughtcrime.securesms.util.SingleLiveEvent;
|
||||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||||
import org.thoughtcrime.securesms.util.livedata.LiveDataTriple;
|
import org.thoughtcrime.securesms.util.livedata.LiveDataTriple;
|
||||||
|
@ -168,16 +172,20 @@ public class MessageRequestViewModel extends ViewModel {
|
||||||
} else {
|
} else {
|
||||||
return new MessageData(recipient, MessageClass.BLOCKED_INDIVIDUAL);
|
return new MessageData(recipient, MessageClass.BLOCKED_INDIVIDUAL);
|
||||||
}
|
}
|
||||||
} else if (recipient.isGroup()) {
|
} else if (recipient.isPushV2Group()) {
|
||||||
if (recipient.isPushV2Group()) {
|
|
||||||
if (repository.isPendingMember(recipient.requireGroupId().requireV2())) {
|
if (repository.isPendingMember(recipient.requireGroupId().requireV2())) {
|
||||||
return new MessageData(recipient, MessageClass.GROUP_V2_INVITE);
|
return new MessageData(recipient, MessageClass.GROUP_V2_INVITE);
|
||||||
} else {
|
} else {
|
||||||
return new MessageData(recipient, MessageClass.GROUP_V2_ADD);
|
return new MessageData(recipient, MessageClass.GROUP_V2_ADD);
|
||||||
}
|
}
|
||||||
|
} else if (isLegacyThread(recipient)) {
|
||||||
|
if (recipient.isGroup()) {
|
||||||
|
return new MessageData(recipient, MessageClass.LEGACY_GROUP_V1);
|
||||||
} else {
|
} else {
|
||||||
return new MessageData(recipient, MessageClass.GROUP_V1);
|
return new MessageData(recipient, MessageClass.LEGACY_INDIVIDUAL);
|
||||||
}
|
}
|
||||||
|
} else if (recipient.isGroup()) {
|
||||||
|
return new MessageData(recipient, MessageClass.GROUP_V1);
|
||||||
} else {
|
} else {
|
||||||
return new MessageData(recipient, MessageClass.INDIVIDUAL);
|
return new MessageData(recipient, MessageClass.INDIVIDUAL);
|
||||||
}
|
}
|
||||||
|
@ -198,13 +206,23 @@ public class MessageRequestViewModel extends ViewModel {
|
||||||
case REQUIRED:
|
case REQUIRED:
|
||||||
displayState.postValue(DisplayState.DISPLAY_MESSAGE_REQUEST);
|
displayState.postValue(DisplayState.DISPLAY_MESSAGE_REQUEST);
|
||||||
break;
|
break;
|
||||||
case LEGACY:
|
case PRE_MESSAGE_REQUEST:
|
||||||
displayState.postValue(DisplayState.DISPLAY_LEGACY);
|
displayState.postValue(DisplayState.DISPLAY_PRE_MESSAGE_REQUEST);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
|
private boolean isLegacyThread(@NonNull Recipient recipient) {
|
||||||
|
Context context = ApplicationDependencies.getApplication();
|
||||||
|
Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient.getId());
|
||||||
|
|
||||||
|
return FeatureFlags.modernProfileSharing() &&
|
||||||
|
threadId != null &&
|
||||||
|
(RecipientUtil.hasSentMessageInThread(context, threadId) || RecipientUtil.isPreMessageRequestThread(context, threadId));
|
||||||
|
}
|
||||||
|
|
||||||
public static class RecipientInfo {
|
public static class RecipientInfo {
|
||||||
@Nullable private final Recipient recipient;
|
@Nullable private final Recipient recipient;
|
||||||
@NonNull private final GroupMemberCount groupMemberCount;
|
@NonNull private final GroupMemberCount groupMemberCount;
|
||||||
|
@ -246,12 +264,16 @@ public class MessageRequestViewModel extends ViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum DisplayState {
|
public enum DisplayState {
|
||||||
DISPLAY_MESSAGE_REQUEST, DISPLAY_LEGACY, DISPLAY_NONE
|
DISPLAY_MESSAGE_REQUEST, DISPLAY_PRE_MESSAGE_REQUEST, DISPLAY_NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MessageClass {
|
public enum MessageClass {
|
||||||
BLOCKED_INDIVIDUAL,
|
BLOCKED_INDIVIDUAL,
|
||||||
BLOCKED_GROUP,
|
BLOCKED_GROUP,
|
||||||
|
/** An individual conversation that existed pre-message-requests but doesn't have profile sharing enabled */
|
||||||
|
LEGACY_INDIVIDUAL,
|
||||||
|
/** A V1 group conversation that existed pre-message-requests but doesn't have profile sharing enabled */
|
||||||
|
LEGACY_GROUP_V1,
|
||||||
GROUP_V1,
|
GROUP_V1,
|
||||||
GROUP_V2_INVITE,
|
GROUP_V2_INVITE,
|
||||||
GROUP_V2_ADD,
|
GROUP_V2_ADD,
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.messagerequests;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -12,15 +13,17 @@ import androidx.core.text.HtmlCompat;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
|
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||||
import org.thoughtcrime.securesms.util.Debouncer;
|
import org.thoughtcrime.securesms.util.Debouncer;
|
||||||
import org.thoughtcrime.securesms.util.HtmlUtil;
|
import org.thoughtcrime.securesms.util.HtmlUtil;
|
||||||
|
import org.thoughtcrime.securesms.util.views.LearnMoreTextView;
|
||||||
|
|
||||||
public class MessageRequestsBottomView extends ConstraintLayout {
|
public class MessageRequestsBottomView extends ConstraintLayout {
|
||||||
|
|
||||||
private final Debouncer showProgressDebouncer = new Debouncer(250);
|
private final Debouncer showProgressDebouncer = new Debouncer(250);
|
||||||
|
|
||||||
private TextView question;
|
private LearnMoreTextView question;
|
||||||
private View accept;
|
private Button accept;
|
||||||
private View block;
|
private View block;
|
||||||
private View delete;
|
private View delete;
|
||||||
private View bigDelete;
|
private View bigDelete;
|
||||||
|
@ -63,6 +66,9 @@ public class MessageRequestsBottomView extends ConstraintLayout {
|
||||||
public void setMessageData(@NonNull MessageRequestViewModel.MessageData messageData) {
|
public void setMessageData(@NonNull MessageRequestViewModel.MessageData messageData) {
|
||||||
Recipient recipient = messageData.getRecipient();
|
Recipient recipient = messageData.getRecipient();
|
||||||
|
|
||||||
|
question.setLearnMoreVisible(false);
|
||||||
|
question.setOnLinkClickListener(null);
|
||||||
|
|
||||||
switch (messageData.getMessageClass()) {
|
switch (messageData.getMessageClass()) {
|
||||||
case BLOCKED_INDIVIDUAL:
|
case BLOCKED_INDIVIDUAL:
|
||||||
question.setText(HtmlCompat.fromHtml(getContext().getString(R.string.MessageRequestBottomView_do_you_want_to_let_s_message_you_wont_receive_any_messages_until_you_unblock_them,
|
question.setText(HtmlCompat.fromHtml(getContext().getString(R.string.MessageRequestBottomView_do_you_want_to_let_s_message_you_wont_receive_any_messages_until_you_unblock_them,
|
||||||
|
@ -73,19 +79,36 @@ public class MessageRequestsBottomView extends ConstraintLayout {
|
||||||
question.setText(R.string.MessageRequestBottomView_unblock_this_group_and_share_your_name_and_photo_with_its_members);
|
question.setText(R.string.MessageRequestBottomView_unblock_this_group_and_share_your_name_and_photo_with_its_members);
|
||||||
setActiveInactiveGroups(blockedButtons, normalButtons);
|
setActiveInactiveGroups(blockedButtons, normalButtons);
|
||||||
break;
|
break;
|
||||||
|
case LEGACY_INDIVIDUAL:
|
||||||
|
question.setText(getContext().getString(R.string.MessageRequestBottomView_continue_your_conversation_with_s_and_share_your_name_and_photo, recipient.getShortDisplayName(getContext())));
|
||||||
|
question.setLearnMoreVisible(true);
|
||||||
|
question.setOnLinkClickListener(v -> CommunicationActions.openBrowserLink(getContext(), getContext().getString(R.string.MessageRequestBottomView_legacy_learn_more_url)));
|
||||||
|
setActiveInactiveGroups(normalButtons, blockedButtons);
|
||||||
|
accept.setText(R.string.MessageRequestBottomView_continue);
|
||||||
|
break;
|
||||||
|
case LEGACY_GROUP_V1:
|
||||||
|
question.setText(R.string.MessageRequestBottomView_continue_your_conversation_with_this_group_and_share_your_name_and_photo);
|
||||||
|
question.setLearnMoreVisible(true);
|
||||||
|
question.setOnLinkClickListener(v -> CommunicationActions.openBrowserLink(getContext(), getContext().getString(R.string.MessageRequestBottomView_legacy_learn_more_url)));
|
||||||
|
setActiveInactiveGroups(normalButtons, blockedButtons);
|
||||||
|
accept.setText(R.string.MessageRequestBottomView_continue);
|
||||||
|
break;
|
||||||
case GROUP_V1:
|
case GROUP_V1:
|
||||||
case GROUP_V2_INVITE:
|
case GROUP_V2_INVITE:
|
||||||
question.setText(R.string.MessageRequestBottomView_do_you_want_to_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept);
|
question.setText(R.string.MessageRequestBottomView_do_you_want_to_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept);
|
||||||
setActiveInactiveGroups(normalButtons, blockedButtons);
|
setActiveInactiveGroups(normalButtons, blockedButtons);
|
||||||
|
accept.setText(R.string.MessageRequestBottomView_accept);
|
||||||
break;
|
break;
|
||||||
case GROUP_V2_ADD:
|
case GROUP_V2_ADD:
|
||||||
question.setText(R.string.MessageRequestBottomView_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept);
|
question.setText(R.string.MessageRequestBottomView_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept);
|
||||||
setActiveInactiveGroups(normalButtons, blockedButtons);
|
setActiveInactiveGroups(normalButtons, blockedButtons);
|
||||||
|
accept.setText(R.string.MessageRequestBottomView_accept);
|
||||||
break;
|
break;
|
||||||
case INDIVIDUAL:
|
case INDIVIDUAL:
|
||||||
question.setText(HtmlCompat.fromHtml(getContext().getString(R.string.MessageRequestBottomView_do_you_want_to_let_s_message_you_they_wont_know_youve_seen_their_messages_until_you_accept,
|
question.setText(HtmlCompat.fromHtml(getContext().getString(R.string.MessageRequestBottomView_do_you_want_to_let_s_message_you_they_wont_know_youve_seen_their_messages_until_you_accept,
|
||||||
HtmlUtil.bold(recipient.getShortDisplayName(getContext()))), 0));
|
HtmlUtil.bold(recipient.getShortDisplayName(getContext()))), 0));
|
||||||
setActiveInactiveGroups(normalButtons, blockedButtons);
|
setActiveInactiveGroups(normalButtons, blockedButtons);
|
||||||
|
accept.setText(R.string.MessageRequestBottomView_accept);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,7 +280,7 @@ public class RecipientUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
private static boolean hasSentMessageInThread(@NonNull Context context, long threadId) {
|
public static boolean hasSentMessageInThread(@NonNull Context context, long threadId) {
|
||||||
return DatabaseFactory.getMmsSmsDatabase(context).getOutgoingSecureConversationCount(threadId) != 0;
|
return DatabaseFactory.getMmsSmsDatabase(context).getOutgoingSecureConversationCount(threadId) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ public final class FeatureFlags {
|
||||||
private static final String PHONE_NUMBER_PRIVACY_VERSION = "android.phoneNumberPrivacyVersion";
|
private static final String PHONE_NUMBER_PRIVACY_VERSION = "android.phoneNumberPrivacyVersion";
|
||||||
private static final String CLIENT_EXPIRATION = "android.clientExpiration";
|
private static final String CLIENT_EXPIRATION = "android.clientExpiration";
|
||||||
public static final String RESEARCH_MEGAPHONE_1 = "research.megaphone.1";
|
public static final String RESEARCH_MEGAPHONE_1 = "research.megaphone.1";
|
||||||
|
public static final String MODERN_PROFILE_SHARING = "android.modernProfileSharing";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We will only store remote values for flags in this set. If you want a flag to be controllable
|
* We will only store remote values for flags in this set. If you want a flag to be controllable
|
||||||
|
@ -74,7 +75,8 @@ public final class FeatureFlags {
|
||||||
MENTIONS,
|
MENTIONS,
|
||||||
VERIFY_V2,
|
VERIFY_V2,
|
||||||
CLIENT_EXPIRATION,
|
CLIENT_EXPIRATION,
|
||||||
RESEARCH_MEGAPHONE_1
|
RESEARCH_MEGAPHONE_1,
|
||||||
|
MODERN_PROFILE_SHARING
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -248,6 +250,11 @@ public final class FeatureFlags {
|
||||||
return getVersionFlag(PHONE_NUMBER_PRIVACY_VERSION) == VersionFlag.ON;
|
return getVersionFlag(PHONE_NUMBER_PRIVACY_VERSION) == VersionFlag.ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Whether or not to show the new profile sharing prompt for legacy conversations. */
|
||||||
|
public static boolean modernProfileSharing() {
|
||||||
|
return getBoolean(MODERN_PROFILE_SHARING, false);
|
||||||
|
}
|
||||||
|
|
||||||
/** Only for rendering debug info. */
|
/** Only for rendering debug info. */
|
||||||
public static synchronized @NonNull Map<String, Object> getMemoryValues() {
|
public static synchronized @NonNull Map<String, Object> getMemoryValues() {
|
||||||
return new TreeMap<>(REMOTE_VALUES);
|
return new TreeMap<>(REMOTE_VALUES);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
|
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
|
||||||
|
|
||||||
<TextView
|
<org.thoughtcrime.securesms.util.views.LearnMoreTextView
|
||||||
android:id="@+id/message_request_question"
|
android:id="@+id/message_request_question"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
|
@ -1061,14 +1061,18 @@
|
||||||
|
|
||||||
<!-- MessageRequestBottomView -->
|
<!-- MessageRequestBottomView -->
|
||||||
<string name="MessageRequestBottomView_accept">Accept</string>
|
<string name="MessageRequestBottomView_accept">Accept</string>
|
||||||
|
<string name="MessageRequestBottomView_continue">Continue</string>
|
||||||
<string name="MessageRequestBottomView_delete">Delete</string>
|
<string name="MessageRequestBottomView_delete">Delete</string>
|
||||||
<string name="MessageRequestBottomView_block">Block</string>
|
<string name="MessageRequestBottomView_block">Block</string>
|
||||||
<string name="MessageRequestBottomView_unblock">Unblock</string>
|
<string name="MessageRequestBottomView_unblock">Unblock</string>
|
||||||
<string name="MessageRequestBottomView_do_you_want_to_let_s_message_you_they_wont_know_youve_seen_their_messages_until_you_accept">Let %1$s message you and share your name and photo with them? They won\'t know you\'ve seen their message until you accept.</string>
|
<string name="MessageRequestBottomView_do_you_want_to_let_s_message_you_they_wont_know_youve_seen_their_messages_until_you_accept">Let %1$s message you and share your name and photo with them? They won\'t know you\'ve seen their message until you accept.</string>
|
||||||
<string name="MessageRequestBottomView_do_you_want_to_let_s_message_you_wont_receive_any_messages_until_you_unblock_them">Let %1$s message you and share your name and photo with them? You won\'t receive any messages until you unblock them.</string>
|
<string name="MessageRequestBottomView_do_you_want_to_let_s_message_you_wont_receive_any_messages_until_you_unblock_them">Let %1$s message you and share your name and photo with them? You won\'t receive any messages until you unblock them.</string>
|
||||||
|
<string name="MessageRequestBottomView_continue_your_conversation_with_this_group_and_share_your_name_and_photo">Continue your conversation with this group and share your name and photo with its members?</string>
|
||||||
|
<string name="MessageRequestBottomView_continue_your_conversation_with_s_and_share_your_name_and_photo">Continue your conversation with %1$s and share your name and photo with them?</string>
|
||||||
<string name="MessageRequestBottomView_do_you_want_to_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept">Join this group and share your name and photo with its members? They won\'t know you\'ve seen their messages until you accept.</string>
|
<string name="MessageRequestBottomView_do_you_want_to_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept">Join this group and share your name and photo with its members? They won\'t know you\'ve seen their messages until you accept.</string>
|
||||||
<string name="MessageRequestBottomView_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept">Join this group? They won’t know you’ve seen their messages until you accept.</string>
|
<string name="MessageRequestBottomView_join_this_group_they_wont_know_youve_seen_their_messages_until_you_accept">Join this group? They won’t know you’ve seen their messages until you accept.</string>
|
||||||
<string name="MessageRequestBottomView_unblock_this_group_and_share_your_name_and_photo_with_its_members">Unblock this group and share your name and photo with its members? You won\'t receive any messages until you unblock them.</string>
|
<string name="MessageRequestBottomView_unblock_this_group_and_share_your_name_and_photo_with_its_members">Unblock this group and share your name and photo with its members? You won\'t receive any messages until you unblock them.</string>
|
||||||
|
<string name="MessageRequestBottomView_legacy_learn_more_url" translatable="false">https://support.signal.org/hc/articles/360007459591</string>
|
||||||
<string name="MessageRequestProfileView_member_of_one_group">Member of %1$s</string>
|
<string name="MessageRequestProfileView_member_of_one_group">Member of %1$s</string>
|
||||||
<string name="MessageRequestProfileView_member_of_two_groups">Member of %1$s and %2$s</string>
|
<string name="MessageRequestProfileView_member_of_two_groups">Member of %1$s and %2$s</string>
|
||||||
<string name="MessageRequestProfileView_member_of_many_groups">Member of %1$s, %2$s, and %3$s</string>
|
<string name="MessageRequestProfileView_member_of_many_groups">Member of %1$s, %2$s, and %3$s</string>
|
||||||
|
|
Ładowanie…
Reference in New Issue