Copione merged onto master

master
blallo 2020-09-11 00:00:14 +02:00
commit 5dd557b569
54 changed files with 620 additions and 184 deletions

View File

@ -80,8 +80,8 @@ protobuf {
}
}
def canonicalVersionCode = 705
def canonicalVersionName = "4.71.2"
def canonicalVersionCode = 706
def canonicalVersionName = "4.71.3"
def postFixSize = 10
def abiPostFix = ['universal' : 0,

View File

@ -106,7 +106,7 @@ public final class ContactSelectionListFragment extends LoggingFragment
public static final String MULTI_SELECT = "multi_select";
public static final String REFRESHABLE = "refreshable";
public static final String RECENTS = "recents";
public static final String TOTAL_CAPACITY = "total_capacity";
public static final String SELECTION_LIMIT = "selection_limit";
public static final String CURRENT_SELECTION = "current_selection";
private ConstraintLayout constraintLayout;
@ -208,7 +208,7 @@ public final class ContactSelectionListFragment extends LoggingFragment
swipeRefresh.setEnabled(requireActivity().getIntent().getBooleanExtra(REFRESHABLE, true));
selectionLimit = requireActivity().getIntent().getIntExtra(TOTAL_CAPACITY, NO_LIMIT);
selectionLimit = requireActivity().getIntent().getIntExtra(SELECTION_LIMIT, NO_LIMIT);
currentSelection = getCurrentSelection();
updateGroupLimit(getChipCount());

View File

@ -111,13 +111,13 @@ public class ConversationListArchiveFragment extends ConversationListFragment im
@Override
@WorkerThread
protected void archiveThreads(Set<Long> threadIds) {
DatabaseFactory.getThreadDatabase(getActivity()).setArchived(threadIds, true);
DatabaseFactory.getThreadDatabase(getActivity()).setArchived(threadIds, false);
}
@Override
@WorkerThread
protected void reverseArchiveThreads(Set<Long> threadIds) {
DatabaseFactory.getThreadDatabase(getActivity()).setArchived(threadIds, false);
DatabaseFactory.getThreadDatabase(getActivity()).setArchived(threadIds, true);
}
@SuppressLint("StaticFieldLeak")

View File

@ -260,7 +260,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
InsightsLauncher.showInsightsModal(requireContext(), requireFragmentManager());
}
SimpleTask.run(getLifecycle(), Recipient::self, this::initializeProfileIcon);
SimpleTask.run(getViewLifecycleOwner().getLifecycle(), Recipient::self, this::initializeProfileIcon);
if (!searchToolbar.isVisible() && list.getAdapter() != defaultAdapter) {
list.removeItemDecoration(searchAdapterDecoration);

View File

@ -859,13 +859,14 @@ public class RecipientDatabase extends Database {
for (SignalGroupV2Record insert : groupV2Inserts) {
db.insertOrThrow(TABLE_NAME, null, getValuesForStorageGroupV2(insert));
GroupId.V2 groupId = GroupId.v2(insert.getMasterKey());
Recipient recipient = Recipient.externalGroup(context, groupId);
GroupMasterKey masterKey = insert.getMasterKeyOrThrow();
GroupId.V2 groupId = GroupId.v2(masterKey);
Recipient recipient = Recipient.externalGroup(context, groupId);
Log.i(TAG, "Creating restore placeholder for " + groupId);
DatabaseFactory.getGroupDatabase(context)
.create(insert.getMasterKey(),
.create(masterKey,
DecryptedGroup.newBuilder()
.setRevision(GroupsV2StateProcessor.RESTORE_PLACEHOLDER_REVISION)
.build());
@ -886,7 +887,8 @@ public class RecipientDatabase extends Database {
throw new AssertionError("Had an update, but it didn't match any rows!");
}
Recipient recipient = Recipient.externalGroup(context, GroupId.v2(update.getOld().getMasterKey()));
GroupMasterKey masterKey = update.getOld().getMasterKeyOrThrow();
Recipient recipient = Recipient.externalGroup(context, GroupId.v2(masterKey));
threadDatabase.setArchived(recipient.getId(), update.getNew().isArchived());
needsRefresh.add(recipient.getId());
@ -1031,7 +1033,7 @@ public class RecipientDatabase extends Database {
private static @NonNull ContentValues getValuesForStorageGroupV2(@NonNull SignalGroupV2Record groupV2) {
ContentValues values = new ContentValues();
values.put(GROUP_ID, GroupId.v2(groupV2.getMasterKey()).toString());
values.put(GROUP_ID, GroupId.v2(groupV2.getMasterKeyOrThrow()).toString());
values.put(GROUP_TYPE, GroupType.SIGNAL_V2.getId());
values.put(PROFILE_SHARING, groupV2.isProfileSharingEnabled() ? "1" : "0");
values.put(BLOCKED, groupV2.isBlocked() ? "1" : "0");

View File

@ -329,18 +329,16 @@ public class ThreadDatabase extends Database {
return;
}
long trimDate = trimBeforeDate;
if (length != NO_TRIM_MESSAGE_COUNT_SET) {
try (Cursor cursor = DatabaseFactory.getMmsSmsDatabase(context).getConversation(threadId)) {
if (cursor != null && length > 0 && cursor.getCount() > length) {
cursor.moveToPosition(length - 1);
trimDate = Math.max(trimDate, cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.NORMALIZED_DATE_RECEIVED)));
trimBeforeDate = Math.max(trimBeforeDate, cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.NORMALIZED_DATE_RECEIVED)));
}
}
}
if (trimDate != NO_TRIM_BEFORE_DATE_SET) {
if (trimBeforeDate != NO_TRIM_BEFORE_DATE_SET) {
Log.i(TAG, "Trimming thread: " + threadId + " before: " + trimBeforeDate);
DatabaseFactory.getMmsSmsDatabase(context).deleteMessagesInThreadBeforeDate(threadId, trimBeforeDate);

View File

@ -19,6 +19,7 @@ public abstract class GroupId {
private static final String ENCODED_MMS_GROUP_PREFIX = "__signal_mms_group__!";
private static final int MMS_BYTE_LENGTH = 16;
private static final int V1_MMS_BYTE_LENGTH = 16;
private static final int V1_BYTE_LENGTH = 16;
private static final int V2_BYTE_LENGTH = GroupIdentifier.SIZE;
private final String encodedId;
@ -46,6 +47,13 @@ public abstract class GroupId {
return new GroupId.V1(gv1GroupIdBytes);
}
public static @NonNull GroupId.V1 v1Exact(byte[] gv1GroupIdBytes) throws BadGroupIdException {
if (gv1GroupIdBytes.length != V1_BYTE_LENGTH) {
throw new BadGroupIdException();
}
return new GroupId.V1(gv1GroupIdBytes);
}
public static GroupId.V1 createV1(@NonNull SecureRandom secureRandom) {
return v1orThrow(Util.getSecretBytes(secureRandom, V1_MMS_BYTE_LENGTH));
}
@ -54,15 +62,11 @@ public abstract class GroupId {
return mms(Util.getSecretBytes(secureRandom, MMS_BYTE_LENGTH));
}
public static GroupId.V2 v2orThrow(@NonNull byte[] bytes) {
try {
return v2(bytes);
} catch (BadGroupIdException e) {
throw new AssertionError(e);
}
}
public static GroupId.V2 v2(@NonNull byte[] bytes) throws BadGroupIdException {
/**
* Private because it's too easy to pass the {@link GroupMasterKey} bytes directly to this as they
* are the same length as the {@link GroupIdentifier}.
*/
private static GroupId.V2 v2(@NonNull byte[] bytes) throws BadGroupIdException {
if (bytes.length != V2_BYTE_LENGTH) {
throw new BadGroupIdException();
}
@ -70,7 +74,11 @@ public abstract class GroupId {
}
public static GroupId.V2 v2(@NonNull GroupIdentifier groupIdentifier) {
return v2orThrow(groupIdentifier.serialize());
try {
return v2(groupIdentifier.serialize());
} catch (BadGroupIdException e) {
throw new AssertionError(e);
}
}
public static GroupId.V2 v2(@NonNull GroupMasterKey masterKey) {

View File

@ -51,7 +51,7 @@ public final class AddToGroupsActivity extends ContactSelectionActivity {
intent.putExtra(EXTRA_RECIPIENT_ID, recipientId);
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, ContactsCursorLoader.DisplayMode.FLAG_ACTIVE_GROUPS);
intent.putExtra(ContactSelectionListFragment.TOTAL_CAPACITY, ContactSelectionListFragment.NO_LIMIT);
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMIT, ContactSelectionListFragment.NO_LIMIT);
intent.putParcelableArrayListExtra(ContactSelectionListFragment.CURRENT_SELECTION, new ArrayList<>(currentGroupsMemberOf));

View File

@ -31,7 +31,6 @@ import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
import org.whispersystems.libsignal.util.guava.Optional;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -55,8 +54,8 @@ public class CreateGroupActivity extends ContactSelectionActivity {
: ContactsCursorLoader.DisplayMode.FLAG_PUSH;
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, displayMode);
intent.putExtra(ContactSelectionListFragment.TOTAL_CAPACITY, FeatureFlags.groupsV2create() ? FeatureFlags.gv2GroupCapacity() - 1
: ContactSelectionListFragment.NO_LIMIT);
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMIT, FeatureFlags.groupsV2create() ? FeatureFlags.gv2GroupCapacity() - 1
: ContactSelectionListFragment.NO_LIMIT);
return intent;
}

View File

@ -199,6 +199,16 @@ final class ManageGroupRepository {
return totalCapacity;
}
public int getSelectionLimit() {
if (totalCapacity == ContactSelectionListFragment.NO_LIMIT) {
return totalCapacity;
}
boolean containsSelf = members.indexOf(Recipient.self().getId()) != -1;
return totalCapacity - (containsSelf ? 1 : 0);
}
public int getRemainingCapacity() {
return totalCapacity - members.size();
}

View File

@ -46,7 +46,6 @@ import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
import java.util.ArrayList;
import java.util.List;
public class ManageGroupViewModel extends ViewModel {
@ -321,7 +320,7 @@ public class ManageGroupViewModel extends ViewModel {
Intent intent = new Intent(fragment.requireActivity(), AddMembersActivity.class);
intent.putExtra(AddMembersActivity.GROUP_ID, manageGroupRepository.getGroupId().toString());
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, ContactsCursorLoader.DisplayMode.FLAG_PUSH);
intent.putExtra(ContactSelectionListFragment.TOTAL_CAPACITY, capacity.getTotalCapacity() - 1);
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMIT, capacity.getSelectionLimit());
intent.putParcelableArrayListExtra(ContactSelectionListFragment.CURRENT_SELECTION, capacity.getMembersWithoutSelf());
fragment.startActivityForResult(intent, resultCode);
}

View File

@ -131,6 +131,7 @@ public class StorageSyncJob extends BaseJob {
StorageKey storageServiceKey = SignalStore.storageServiceValues().getOrCreateStorageKey();
boolean needsMultiDeviceSync = false;
boolean needsForcePush = false;
long localManifestVersion = TextSecurePreferences.getStorageManifestVersion(context);
Optional<SignalStorageManifest> remoteManifest = accountManager.getStorageManifestIfDifferentVersion(storageServiceKey, localManifestVersion);
long remoteManifestVersion = remoteManifest.transform(SignalStorageManifest::getVersion).or(localManifestVersion);
@ -143,6 +144,11 @@ public class StorageSyncJob extends BaseJob {
List<StorageId> allLocalStorageKeys = getAllLocalStorageIds(context, Recipient.self().fresh());
KeyDifferenceResult keyDifference = StorageSyncHelper.findKeyDifference(remoteManifest.get().getStorageIds(), allLocalStorageKeys);
if (keyDifference.hasTypeMismatches()) {
Log.w(TAG, "Found type mismatches in the key sets! Scheduling a force push after this sync completes.");
needsForcePush = true;
}
if (!keyDifference.isEmpty()) {
Log.i(TAG, "[Remote Newer] There's a difference in keys. Local-only: " + keyDifference.getLocalOnlyKeys().size() + ", Remote-only: " + keyDifference.getRemoteOnlyKeys().size());
@ -152,6 +158,11 @@ public class StorageSyncJob extends BaseJob {
MergeResult mergeResult = StorageSyncHelper.resolveConflict(remoteOnly, localOnly);
WriteOperationResult writeOperationResult = StorageSyncHelper.createWriteOperation(remoteManifest.get().getVersion(), allLocalStorageKeys, mergeResult);
if (remoteOnly.size() != keyDifference.getRemoteOnlyKeys().size()) {
Log.w(TAG, "Could not find all remote-only records! Requested: " + keyDifference.getRemoteOnlyKeys().size() + ", Found: " + remoteOnly.size() + ". Scheduling a force push after this sync completes.");
needsForcePush = true;
}
StorageSyncValidations.validate(writeOperationResult);
Log.i(TAG, "[Remote Newer] MergeResult :: " + mergeResult);
@ -248,6 +259,11 @@ public class StorageSyncJob extends BaseJob {
Log.i(TAG, "[Local Changes] No local changes.");
}
if (needsForcePush) {
Log.w(TAG, "Scheduling a force push.");
ApplicationDependencies.getJobManager().add(new StorageForcePushJob());
}
return needsMultiDeviceSync;
}

View File

@ -215,7 +215,7 @@ public class StoragePreferenceFragment extends ListSummaryPreferenceFragment {
}
AlertDialog dialog = new AlertDialog.Builder(activity)
.setTitle(R.string.preferences_Storage__custom_conversation_length_limit)
.setTitle(R.string.preferences__conversation_length_limit)
.setView(view)
.setPositiveButton(android.R.string.ok, (d, w) -> onSelectionChanged(Integer.parseInt(editText.getText().toString())))
.setNegativeButton(android.R.string.cancel, (d, w) -> updateSettingsList())

View File

@ -5,16 +5,16 @@ import androidx.annotation.NonNull;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.groups.BadGroupIdException;
import org.thoughtcrime.securesms.groups.GroupId;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.storage.SignalGroupV1Record;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
class GroupV1ConflictMerger implements StorageSyncHelper.ConflictMerger<SignalGroupV1Record> {
final class GroupV1ConflictMerger implements StorageSyncHelper.ConflictMerger<SignalGroupV1Record> {
private final Map<GroupId, SignalGroupV1Record> localByGroupId;
@ -29,7 +29,9 @@ class GroupV1ConflictMerger implements StorageSyncHelper.ConflictMerger<SignalGr
@Override
public @NonNull Collection<SignalGroupV1Record> getInvalidEntries(@NonNull Collection<SignalGroupV1Record> remoteRecords) {
return Collections.emptySet();
return Stream.of(remoteRecords)
.filterNot(GroupV1ConflictMerger::isValidGroupId)
.toList();
}
@Override
@ -54,4 +56,13 @@ class GroupV1ConflictMerger implements StorageSyncHelper.ConflictMerger<SignalGr
.build();
}
}
private static boolean isValidGroupId(@NonNull SignalGroupV1Record record) {
try {
GroupId.v1Exact(record.getGroupId());
return true;
} catch (BadGroupIdException e) {
return false;
}
}
}

View File

@ -4,6 +4,7 @@ import androidx.annotation.NonNull;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import com.google.protobuf.ByteString;
import org.signal.zkgroup.groups.GroupMasterKey;
import org.whispersystems.libsignal.util.guava.Optional;
@ -11,25 +12,26 @@ import org.whispersystems.signalservice.api.storage.SignalGroupV2Record;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
class GroupV2ConflictMerger implements StorageSyncHelper.ConflictMerger<SignalGroupV2Record> {
final class GroupV2ConflictMerger implements StorageSyncHelper.ConflictMerger<SignalGroupV2Record> {
private final Map<GroupMasterKey, SignalGroupV2Record> localByGroupId;
private final Map<ByteString, SignalGroupV2Record> localByMasterKeyBytes;
GroupV2ConflictMerger(@NonNull Collection<SignalGroupV2Record> localOnly) {
localByGroupId = Stream.of(localOnly).collect(Collectors.toMap(SignalGroupV2Record::getMasterKey, g -> g));
localByMasterKeyBytes = Stream.of(localOnly).collect(Collectors.toMap((SignalGroupV2Record signalGroupV2Record) -> ByteString.copyFrom(signalGroupV2Record.getMasterKeyBytes()), g -> g));
}
@Override
public @NonNull Optional<SignalGroupV2Record> getMatching(@NonNull SignalGroupV2Record record) {
return Optional.fromNullable(localByGroupId.get(record.getMasterKey()));
return Optional.fromNullable(localByMasterKeyBytes.get(ByteString.copyFrom(record.getMasterKeyBytes())));
}
@Override
public @NonNull Collection<SignalGroupV2Record> getInvalidEntries(@NonNull Collection<SignalGroupV2Record> remoteRecords) {
return Collections.emptySet();
return Stream.of(remoteRecords)
.filterNot(GroupV2ConflictMerger::isValidMasterKey)
.toList();
}
@Override
@ -47,11 +49,15 @@ class GroupV2ConflictMerger implements StorageSyncHelper.ConflictMerger<SignalGr
} else if (matchesLocal) {
return local;
} else {
return new SignalGroupV2Record.Builder(keyGenerator.generate(), remote.getMasterKey())
return new SignalGroupV2Record.Builder(keyGenerator.generate(), remote.getMasterKeyBytes())
.setUnknownFields(unknownFields)
.setBlocked(blocked)
.setProfileSharingEnabled(blocked)
.build();
}
}
private static boolean isValidMasterKey(@NonNull SignalGroupV2Record record) {
return record.getMasterKeyBytes().length == GroupMasterKey.SIZE;
}
}

View File

@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.database.DatabaseFactory;
@ -19,6 +20,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.SetUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
@ -41,6 +43,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -213,10 +216,30 @@ public final class StorageSyncHelper {
public static @NonNull KeyDifferenceResult findKeyDifference(@NonNull Collection<StorageId> remoteKeys,
@NonNull Collection<StorageId> localKeys)
{
Set<StorageId> remoteOnlyKeys = SetUtil.difference(remoteKeys, localKeys);
Set<StorageId> localOnlyKeys = SetUtil.difference(localKeys, remoteKeys);
Map<String, StorageId> remoteByRawId = Stream.of(remoteKeys).collect(Collectors.toMap(id -> Base64.encodeBytes(id.getRaw()), id -> id));
Map<String, StorageId> localByRawId = Stream.of(localKeys).collect(Collectors.toMap(id -> Base64.encodeBytes(id.getRaw()), id -> id));
return new KeyDifferenceResult(new ArrayList<>(remoteOnlyKeys), new ArrayList<>(localOnlyKeys));
boolean hasTypeMismatch = remoteByRawId.size() != remoteKeys.size() || localByRawId.size() != localKeys.size();
Set<String> remoteOnlyRawIds = SetUtil.difference(remoteByRawId.keySet(), localByRawId.keySet());
Set<String> localOnlyRawIds = SetUtil.difference(localByRawId.keySet(), remoteByRawId.keySet());
Set<String> sharedRawIds = SetUtil.intersection(localByRawId.keySet(), remoteByRawId.keySet());
for (String rawId : sharedRawIds) {
StorageId remote = Objects.requireNonNull(remoteByRawId.get(rawId));
StorageId local = Objects.requireNonNull(localByRawId.get(rawId));
if (remote.getType() != local.getType()) {
remoteOnlyRawIds.remove(rawId);
localOnlyRawIds.remove(rawId);
hasTypeMismatch = true;
}
}
List<StorageId> remoteOnlyKeys = Stream.of(remoteOnlyRawIds).map(remoteByRawId::get).toList();
List<StorageId> localOnlyKeys = Stream.of(localOnlyRawIds).map(localByRawId::get).toList();
return new KeyDifferenceResult(remoteOnlyKeys, localOnlyKeys, hasTypeMismatch);
}
/**
@ -282,6 +305,7 @@ public final class StorageSyncHelper {
Set<SignalRecord> remoteDeletes = new HashSet<>();
remoteDeletes.addAll(contactMergeResult.remoteDeletes);
remoteDeletes.addAll(groupV1MergeResult.remoteDeletes);
remoteDeletes.addAll(groupV2MergeResult.remoteDeletes);
remoteDeletes.addAll(accountMergeResult.remoteDeletes);
return new MergeResult(contactMergeResult.localInserts,
@ -458,12 +482,15 @@ public final class StorageSyncHelper {
public static final class KeyDifferenceResult {
private final List<StorageId> remoteOnlyKeys;
private final List<StorageId> localOnlyKeys;
private final boolean hasTypeMismatches;
private KeyDifferenceResult(@NonNull List<StorageId> remoteOnlyKeys,
@NonNull List<StorageId> localOnlyKeys)
@NonNull List<StorageId> localOnlyKeys,
boolean hasTypeMismatches)
{
this.remoteOnlyKeys = remoteOnlyKeys;
this.localOnlyKeys = localOnlyKeys;
this.remoteOnlyKeys = remoteOnlyKeys;
this.localOnlyKeys = localOnlyKeys;
this.hasTypeMismatches = hasTypeMismatches;
}
public @NonNull List<StorageId> getRemoteOnlyKeys() {
@ -474,6 +501,14 @@ public final class StorageSyncHelper {
return localOnlyKeys;
}
/**
* @return True if there exist some keys that have matching raw ID's but different types,
* otherwise false.
*/
public boolean hasTypeMismatches() {
return hasTypeMismatches;
}
public boolean isEmpty() {
return remoteOnlyKeys.isEmpty() && localOnlyKeys.isEmpty();
}
@ -603,8 +638,8 @@ public final class StorageSyncHelper {
@Override
public @NonNull String toString() {
return String.format(Locale.ENGLISH,
"localContactInserts: %d, localContactUpdates: %d, localGroupV1Inserts: %d, localGroupV1Updates: %d, localGroupV2Inserts: %d, localGroupV2Updates: %d, localUnknownInserts: %d, localUnknownDeletes: %d, localAccountUpdate: %b, remoteInserts: %d, remoteUpdates: %d",
localContactInserts.size(), localContactUpdates.size(), localGroupV1Inserts.size(), localGroupV1Updates.size(), localGroupV2Inserts.size(), localGroupV2Updates.size(), localUnknownInserts.size(), localUnknownDeletes.size(), localAccountUpdate.isPresent(), remoteInserts.size(), remoteUpdates.size());
"localContactInserts: %d, localContactUpdates: %d, localGroupV1Inserts: %d, localGroupV1Updates: %d, localGroupV2Inserts: %d, localGroupV2Updates: %d, localUnknownInserts: %d, localUnknownDeletes: %d, localAccountUpdate: %b, remoteInserts: %d, remoteUpdates: %d, remoteDeletes: %d",
localContactInserts.size(), localContactUpdates.size(), localGroupV1Inserts.size(), localGroupV1Updates.size(), localGroupV2Inserts.size(), localGroupV2Updates.size(), localUnknownInserts.size(), localUnknownDeletes.size(), localAccountUpdate.isPresent(), remoteInserts.size(), remoteUpdates.size(), remoteDeletes.size());
}
}

View File

@ -38,7 +38,7 @@ public final class GroupUtil {
throws BadGroupIdException
{
if (groupContext.getGroupV1().isPresent()) {
return GroupId.v1(groupContext.getGroupV1().get().getGroupId());
return GroupId.v1Exact(groupContext.getGroupV1().get().getGroupId());
} else if (groupContext.getGroupV2().isPresent()) {
return GroupId.v2(groupContext.getGroupV2().get().getMasterKey());
} else {

View File

@ -16,8 +16,9 @@
android:id="@+id/customizable_single_select_radio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="20dp"
android:clickable="false"
android:paddingEnd="20dp"
android:theme="?radio_theme"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
@ -28,7 +29,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="?attr/textColorAlertDialogListItem"
app:layout_constraintBottom_toTopOf="@id/customizable_single_select_summary"
app:layout_constraintStart_toEndOf="@id/customizable_single_select_radio"

View File

@ -28,7 +28,8 @@
android:paddingEnd="?attr/dialogPreferredPadding"
android:text="@string/GroupMentionSettingDialog_always_notify_me"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?attr/textColorAlertDialogListItem" />
android:textColor="?attr/textColorAlertDialogListItem"
android:theme="?radio_theme" />
<CheckedTextView
android:id="@+id/group_mention_setting_dont_notify"
@ -43,6 +44,7 @@
android:paddingEnd="?attr/dialogPreferredPadding"
android:text="@string/GroupMentionSettingDialog_dont_notify_me"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?attr/textColorAlertDialogListItem" />
android:textColor="?attr/textColorAlertDialogListItem"
android:theme="?radio_theme" />
</LinearLayout>

View File

@ -11,6 +11,7 @@
android:minHeight="?attr/listPreferredItemHeightSmall"
android:paddingStart="20dp"
android:paddingEnd="?attr/dialogPreferredPadding"
tools:text="Pick me!"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?attr/textColorAlertDialogListItem" />
android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="?attr/textColorAlertDialogListItem"
android:theme="?radio_theme"
tools:text="Pick me!" />

View File

@ -1862,7 +1862,7 @@
<string name="preferences_storage__none">Nijedno</string>
<string name="preferences_storage__s_messages">%1$s poruka</string>
<string name="preferences_storage__custom">Ostalo</string>
<string name="preferences_Storage__custom_conversation_length_limit">Maksimalni broj poruka</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Maksimalni broj poruka</string> -->
<string name="preferences_advanced__use_system_emoji">Koristi sistemske emoji sličice</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Onemogući Signalovu ugrađenu podršku za emoji sličice</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Preusmjeri sve pozive na Signal server kako bi Vaša IP adresa bila skrivena od sagovornika. Aktiviranjem ove opcije smanjit će se kvalitet poziva.</string>

View File

@ -1913,7 +1913,7 @@ Obdržen požadavek na výměnu klíčů pro neplatnou verzi protokolu.
<string name="preferences_storage__none">Nic</string>
<string name="preferences_storage__s_messages">%1$s zpráv</string>
<string name="preferences_storage__custom">Vlastní</string>
<string name="preferences_Storage__custom_conversation_length_limit">Vlastní limit délky konverzace</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Vlastní limit délky konverzace</string> -->
<string name="preferences_advanced__use_system_emoji">Použít systémové smajlíky</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Zakázat použití interních smajlíků aplikace Signal </string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Přenášet všechna volání přes servery Signal, aby nedošlo k odhalení vaší IP adresy volanému. Povolením dojde ke zhoršení kvality hovoru.</string>

View File

@ -1795,7 +1795,9 @@ Modtog en nøgle besked, for en ugyldig protokol-version
<string name="preferences_storage__review_storage">Vis hukommelse</string>
<string name="preferences_storage__delete_older_messages">Slet ældre beskeder?</string>
<string name="preferences_storage__clear_message_history">Ryd beskedhistorik?</string>
<string name="preferences_storage__this_will_permanently_delete_all_message_history_and_media">Dette vil slette al beskedhistorik og medier permanent fra din enhed, der er ældre end %1$s.</string>
<string name="preferences_storage__this_will_permanently_trim_all_conversations_to_the_d_most_recent_messages">Dette vil reducere alle samtaler permanent til de %1$s seneste beskeder.</string>
<string name="preferences_storage__this_will_delete_all_message_history_and_media_from_your_device">Dette vil slette al beskedhistorik og medier permanent fra din enhed.</string>
<string name="preferences_storage__are_you_sure_you_want_to_delete_all_message_history">Er du sikker på, du vil slette al beskedhistorik?</string>
<string name="preferences_storage__all_message_history_will_be_permanently_removed_this_action_cannot_be_undone">Al beskedhistorik fjernes permanent. Denne handling kan ikke fortrydes.</string>
<string name="preferences_storage__delete_all_now">Slet det hele nu</string>
@ -1806,7 +1808,7 @@ Modtog en nøgle besked, for en ugyldig protokol-version
<string name="preferences_storage__none">Ingen</string>
<string name="preferences_storage__s_messages">%1$s beskeder</string>
<string name="preferences_storage__custom">Tilpasset</string>
<string name="preferences_Storage__custom_conversation_length_limit">Tilpas begrænsning af samtalelængde</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Tilpas begrænsning af samtalelængde</string> -->
<string name="preferences_advanced__use_system_emoji">Anvend system emoji</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Deaktivér Signal´s indbyggede emoji understøttelse</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Videresend alle opkald gennem Signal serveren, for at undgå at afsløre din IP-adresse for din kontakt. Opkaldskvaliteten vil blive forringet</string>

View File

@ -1797,7 +1797,7 @@ Schlüsselaustausch-Nachricht für eine ungültige Protokollversion empfangen</s
<string name="preferences_storage__none">Keine</string>
<string name="preferences_storage__s_messages">%1$s Nachrichten</string>
<string name="preferences_storage__custom">Personalisiert</string>
<string name="preferences_Storage__custom_conversation_length_limit">Höchstzahl an Nachrichten</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Höchstzahl an Nachrichten</string> -->
<string name="preferences_advanced__use_system_emoji">System-Emojis verwenden</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Integrierte Emojis deaktivieren und stattdessen System-Emojis verwenden</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Alle Anrufe über den Signal-Server leiten, um die eigene IP-Adresse gegenüber Kontakten nicht offenzulegen. Dies verringert die Anrufqualität.</string>

View File

@ -1803,7 +1803,7 @@
<string name="preferences_storage__none">Κανένα</string>
<string name="preferences_storage__s_messages">%1$s μηνύματα</string>
<string name="preferences_storage__custom">Προσαρμοσμένο</string>
<string name="preferences_Storage__custom_conversation_length_limit">Προσαρμοσμένο όριο μήκους συνομιλίας</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Προσαρμοσμένο όριο μήκους συνομιλίας</string> -->
<string name="preferences_advanced__use_system_emoji">Χρήση emoji συστήματος</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Απενεργοποίηση της ενσωματωμένης υποστήριξης για emoji του Signal</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Αναμετάδοση όλων των κλήσεων μέσω του σέρβερ Signal για να αποφύγεις την αποκάλυψη της διεύθυνσης IP σου στην επαφή. Η ενεργοποίηση θα ρίξει την ποιότητα των κλήσεων.</string>

View File

@ -449,6 +449,7 @@
<!--RequestingMembersFragment-->
<string name="RequestingMembersFragment_pending_member_requests">Pritraktotaj petoj por aniĝi</string>
<string name="RequestingMembersFragment_no_member_requests_to_show">Neniu peto.</string>
<string name="RequestingMembersFragment_explanation">Homoj en tiu listo provas anigi tiun grupon per kunhavita grupligilo.</string>
<string name="RequestingMembersFragment_added_s">„%1$s“ aldonita</string>
<string name="RequestingMembersFragment_denied_s">„%1$s“ malaprobita</string>
<!--AddMembersActivity-->
@ -610,6 +611,7 @@
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_links_coming_soon">Grupligiloj baldaŭ disponeblos</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal_to_use_group_links">Ĝisdatigu Signal-on por uzi grupligilojn</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_coming_soon">Anigi grupon pere de ligilo ankoraŭ ne eblas en Signal. Tio alvenos per baldaŭa ĝisdatigo.</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_message">La versio de Signal, kiun vi uzas ne subtenas kunhaveblajn grupligilojn. Ĝisdatigu al lasta versio por anigi tiun grupon per ligilo.</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal">Ĝisdatigi Signal-on</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_link_is_not_valid">Grupligilo ne validas</string>
<!--GV2 Request confirmation dialog-->
@ -845,6 +847,9 @@
<string name="MessageRecord_s_changed_who_can_edit_group_membership_to_s">%1$s ŝanĝis, kiu povas modifi la grupan membrecon al „%2$s“.</string>
<string name="MessageRecord_who_can_edit_group_membership_has_been_changed_to_s">Tiuj, kiuj povas modifi la grupan membrecon ŝanĝiĝis al „%1$s“.</string>
<!--GV2 group link invite access level change-->
<string name="MessageRecord_you_turned_on_the_group_link_with_admin_approval_off">Vi ŝaltis la grupligilon sen bezono de administranto-aprobo.</string>
<string name="MessageRecord_you_turned_on_the_group_link_with_admin_approval_on">Vi ŝaltis la grupligilon kun administranto-aprobo.</string>
<string name="MessageRecord_you_turned_off_the_group_link">Vi malŝaltis la grupligilon.</string>
<!--GV2 group link reset-->
<!--GV2 group link joins-->
<!--GV2 group link requests-->

View File

@ -1801,14 +1801,14 @@ Se recibió un mensaje de intercambio de claves para una versión no válida del
<string name="preferences_storage__are_you_sure_you_want_to_delete_all_message_history">¿Seguro que deseas eliminar todo tu historial de mensajes?</string>
<string name="preferences_storage__all_message_history_will_be_permanently_removed_this_action_cannot_be_undone">El historial completo de mensajes se eliminará permanentemente. Esta acción no se puede deshacer.</string>
<string name="preferences_storage__delete_all_now">Borrar todos ahora</string>
<string name="preferences_storage__forever">cero días</string>
<string name="preferences_storage__forever">Siempre</string>
<string name="preferences_storage__one_year">1 año</string>
<string name="preferences_storage__six_months">6 meses</string>
<string name="preferences_storage__thirty_days">30 días</string>
<string name="preferences_storage__none">Ninguna</string>
<string name="preferences_storage__s_messages">%1$s mensajes</string>
<string name="preferences_storage__custom">Personalizado</string>
<string name="preferences_Storage__custom_conversation_length_limit">Límite de longitud de chat personalizado</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Límite de longitud de chat personalizado</string> -->
<string name="preferences_advanced__use_system_emoji">Usar emoji del sistema</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Desactivar soporte de emoji integrado de Signal</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Redirige todas las llamadas a través del servidor de Signal para evitar revelar tu dirección IP. Activar la opción reducirá la calidad de las llamadas.</string>

View File

@ -48,6 +48,7 @@
<string name="ApplicationPreferencesActivity_pin_created">Sortu da PINa.</string>
<string name="ApplicationPreferencesActivity_pin_disabled">PINa desaktibatuta</string>
<string name="ApplicationPreferencesActivity_hide">Ezkutatu</string>
<string name="ApplicationPreferencesActivity_hide_reminder">Ezkutatu gogorarazlea?</string>
<!--AppProtectionPreferenceFragment-->
<plurals name="AppProtectionPreferenceFragment_minutes">
<item quantity="one">minutu %d</item>
@ -214,6 +215,7 @@
<string name="ConversationActivity_unable_to_record_audio">Ezgai audioa grabatzeko!</string>
<string name="ConversationActivity_you_cant_send_messages_to_this_group">Ezin diozu talde honi mezurik bidali dagoeneko kide ez zarelako.</string>
<string name="ConversationActivity_there_is_no_app_available_to_handle_this_link_on_your_device">Ez dago erabil daitekeen aplikaziorik lotura hau kudeatzeko zure gailuan.</string>
<string name="ConversationActivity_cancel_request">Bertan behera utzi eskaera</string>
<string name="ConversationActivity_to_send_audio_messages_allow_signal_access_to_your_microphone">Audio mezuak bidaltzeko, onartu Signalek zure mikrofonoa erabiltzea</string>
<string name="ConversationActivity_signal_requires_the_microphone_permission_in_order_to_send_audio_messages">Signalek Mikrofono baimena behar du audio mezuak bidaltzeko, baina ukatu egin diozu. Joan aplikazioaren ezarpenetara, aukeratu \"Baimenak\" eta aktibatu \"Mikrofonoa\"</string>
<string name="ConversationActivity_signal_needs_the_microphone_and_camera_permissions_in_order_to_call_s">Signal aplikazioak Mikronofoa eta Kamera baimenak behar ditu %skontaktuari deitzeko, baina ukatu egin dizkiozu. Joan aplikazioaren ezarpenetara, aukeratu \"Baimenak\" eta aktibatu \"Mikrofonoa\" eta \"Kamera\"</string>
@ -339,6 +341,7 @@
<string name="AvatarSelectionBottomSheetDialogFragment__take_photo">Atera argazkia</string>
<string name="AvatarSelectionBottomSheetDialogFragment__choose_from_gallery">Aukeratu galeriatik</string>
<string name="AvatarSelectionBottomSheetDialogFragment__remove_photo">Argazkia ezabatu</string>
<string name="AvatarSelectionBottomSheetDialogFragment__taking_a_photo_requires_the_camera_permission">Argazki bat ateratzeko kamera erabiltzeko baimena behar da.</string>
<!--DateUtils-->
<string name="DateUtils_just_now">Orain</string>
<string name="DateUtils_minutes_ago">%dm</string>
@ -401,6 +404,7 @@
<string name="GroupManagement_access_level_anyone">Edozein</string>
<string name="GroupManagement_access_level_all_members">Partaide guztiak</string>
<string name="GroupManagement_access_level_only_admins">Administratzaileak bakarrik</string>
<string name="GroupManagement_access_level_no_one">Inor ez</string>
<!--GV2 invites sent-->
<plurals name="GroupManagement_invitation_sent">
<item quantity="one">Gonbidapena bidalita</item>
@ -411,16 +415,25 @@
<string name="GroupManagement_invite_multiple_users">Ezin duzu erabiltzaile hauek modu automatikoan taldean sartu. Sartzeko gonbidapena bidali zaie eta ezingo dute talde mezurik ikusi onartu arte.</string>
<!--LinkPreviewsMegaphone-->
<string name="LinkPreviewsMegaphone_disable">Desgaitu</string>
<string name="LinkPreviewsMegaphone_preview_any_link">Aurreikusi edozein esteka</string>
<!--LinkPreviewView-->
<string name="LinkPreviewView_no_link_preview_available">Ez dago estekaren aurrebistarik</string>
<string name="LinkPreviewView_this_group_link_is_not_active">Talde esteka hau ez dago indarrean</string>
<!--LinkPreviewRepository-->
<!--PendingMembersActivity-->
<string name="PendingMemberInvitesActivity_pending_group_invites">Falta diren talde gonbidapenak</string>
<string name="PendingMembersActivity_requests">Eskaerak</string>
<string name="PendingMembersActivity_invites">Gonbidapenak</string>
<string name="PendingMembersActivity_people_you_invited">Gondibatu duzun jendea</string>
<string name="PendingMembersActivity_you_have_no_pending_invites">Ez duzu ikusi gabeko gonbidapenik.</string>
<string name="PendingMembersActivity_invites_by_other_group_members">Taldeko beste partaideek egindako gonbidapenak</string>
<string name="PendingMembersActivity_no_pending_invites_by_other_group_members">Taldeko beste partaideek egindako gonbidapenik ez dago.</string>
<string name="PendingMembersActivity_missing_detail_explanation">Taldeko beste partaideek gonbidatutako pertsonen xehetasunak ez dira erakusten. Gonbidatuek taldean sartzea erabakitzen badute, beraien informazioa une horretan partekatuko da taldearekin. Taldean sartu arte ez dute mezurik ikusiko.</string>
<string name="PendingMembersActivity_revoke_invite">Bertan behera utzi gonbidapena</string>
<string name="PendingMembersActivity_revoke_invites">Bertan behera utzi gonbidapenak</string>
<!--RequestingMembersFragment-->
<string name="RequestingMembersFragment_added_s">\"%1$s\" gehitua</string>
<string name="RequestingMembersFragment_denied_s">\"%1$s\" ukatua</string>
<!--AddMembersActivity-->
<string name="AddMembersActivity__done">Eginda</string>
<string name="AddMembersActivity__this_person_cant_be_added_to_legacy_groups">Pertsona hau ezin da jarauntsitako taldeetan gehitu.</string>
@ -450,11 +463,13 @@
<string name="ManageGroupActivity_edit_group_info">Editatu taldeari buruzko informazioa</string>
<string name="ManageGroupActivity_choose_who_can_edit_the_group_name_avatar_and_disappearing_messages">Aukeratu taldearen izena, abatarra eta mezuak desagertzeko tenporizadorea alda dezakeena.</string>
<string name="ManageGroupActivity_choose_who_can_add_or_invite_new_members">Aukeratu kide berriak gehitu edo gonbidatu dezakeena</string>
<string name="ManageGroupActivity_group_link">Talderako esteka</string>
<string name="ManageGroupActivity_block_group">Blokeatu taldea</string>
<string name="ManageGroupActivity_unblock_group">Desblokeatu taldea</string>
<string name="ManageGroupActivity_leave_group">Utzi taldea</string>
<string name="ManageGroupActivity_mute_notifications">Desaktibatu jakinarazpenak</string>
<string name="ManageGroupActivity_custom_notifications">Jakinarazpen pertsonalizatuak</string>
<string name="ManageGroupActivity_mentions">Aipamenak</string>
<string name="ManageGroupActivity_until_s">%1$s dataraino</string>
<string name="ManageGroupActivity_off">Desaktibatuta</string>
<string name="ManageGroupActivity_on">Aktibatuta</string>
@ -479,6 +494,11 @@
<string name="ManageGroupActivity_legacy_group">Jarauntsitako Taldea</string>
<string name="ManageGroupActivity_legacy_group_learn_more">Hau Jarauntsitako Talde bat da. Talde administratzaile moduko ezaugarriak erabili ahal izateko, Talde Berri bat sortu.</string>
<!--GroupMentionSettingDialog-->
<string name="GroupMentionSettingDialog_notify_me_for_mentions">Nahi dut aipamenak jakinaraztea</string>
<string name="GroupMentionSettingDialog_default_notify_me">Lehenetsia (Jakinarazi)</string>
<string name="GroupMentionSettingDialog_default_dont_notify_me">Lehenetsia (Ez jakinarazi)</string>
<string name="GroupMentionSettingDialog_always_notify_me">Beti jakinarazi</string>
<string name="GroupMentionSettingDialog_dont_notify_me">Ez jakinarazi</string>
<!--ManageRecipientActivity-->
<string name="ManageRecipientActivity_add_to_system_contacts">Gehitu sistemaren kontaktuetara</string>
<string name="ManageRecipientActivity_this_person_is_in_your_contacts">Pertsona hau zure kontaktuetan dago</string>
@ -521,18 +541,41 @@
<string name="CustomNotificationsDialogFragment__disabled">Desaktibatuta</string>
<string name="CustomNotificationsDialogFragment__default">Lehenetsia</string>
<!--ShareableGroupLinkDialogFragment-->
<string name="ShareableGroupLinkDialogFragment__shareable_group_link">Partekatu daitekeen taldeko esteka</string>
<string name="ShareableGroupLinkDialogFragment__manage_and_share">Kudeatu &amp; partekatu</string>
<string name="ShareableGroupLinkDialogFragment__group_link">Talderako esteka</string>
<string name="ShareableGroupLinkDialogFragment__share">Elkarbanatu</string>
<string name="ShareableGroupLinkDialogFragment__reset_link">Berrezarri esteka</string>
<string name="ShareableGroupLinkDialogFragment__member_requests">Kideen eskaerak</string>
<string name="ShareableGroupLinkDialogFragment__approve_new_members">Onartu kide berriak</string>
<string name="ShareableGroupLinkDialogFragment__enabled">Aktibatuta</string>
<string name="ShareableGroupLinkDialogFragment__disabled">Desaktibatuta</string>
<string name="ShareableGroupLinkDialogFragment__default">Lehenetsia</string>
<string name="ShareableGroupLinkDialogFragment__group_link_reset">Berrezarri talderako esteka</string>
<!--GroupLinkShareQrDialogFragment-->
<string name="GroupLinkShareQrDialogFragment__qr_code">QR kodea</string>
<string name="GroupLinkShareQrDialogFragment__share_code">Partekatu kodea</string>
<!--GV2 Invite Revoke confirmation dialog-->
<!--GroupJoinBottomSheetDialogFragment-->
<string name="GroupJoinBottomSheetDialogFragment_join">Batu</string>
<string name="GroupJoinBottomSheetDialogFragment_request_to_join">Eskatu batzea</string>
<string name="GroupJoinBottomSheetDialogFragment_unable_to_join_group_please_try_again_later">Ezin izan da taldean sartu. Mesedez, saia zaitez beranduago</string>
<string name="GroupJoinBottomSheetDialogFragment_encountered_a_network_error">Sare errore bat izan da.</string>
<string name="GroupJoinBottomSheetDialogFragment_this_group_link_is_not_active">Talde esteka hau ez dago indarrean</string>
<string name="GroupJoinBottomSheetDialogFragment_unable_to_get_group_information_please_try_again_later">Ez da posible izan taldeari buruzko informazioa eskuratzea; mesedez, saia zaitez berriro beranduago</string>
<string name="GroupJoinBottomSheetDialogFragment_direct_join">Talde honetan sartu eta zure izena eta argazkia kideekin partekatu nahi duzu?</string>
<plurals name="GroupJoinBottomSheetDialogFragment_group_dot_d_members">
<item quantity="one">Taldea · kide %1$d</item>
<item quantity="other">Taldea · %1$d kide</item>
</plurals>
<!--GroupJoinUpdateRequiredBottomSheetDialogFragment-->
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_links_coming_soon">Talderako estekak eskuragarri egongo dira laster</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal_to_use_group_links">Talderako estekak erabiltzeko Signal eguneatu behar duzu</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal">Eguneratu Signal</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_link_is_not_valid">Talde esteka hau ez da baliagarria</string>
<!--GV2 Request confirmation dialog-->
<string name="RequestConfirmationDialog_add">Gehitu</string>
<string name="RequestConfirmationDialog_deny">Ukatu</string>
<!--CropImageActivity-->
<string name="CropImageActivity_group_avatar">Taldearen abatarra</string>
<string name="CropImageActivity_profile_avatar">Abatarra</string>
@ -1688,6 +1731,7 @@ Inportatu \'SMSBackup and Restorekin\' bateragarria den enkriptatu gabeko babesk
<string name="preferences_communication__sealed_sender_allow_from_anyone">Edozeinengandik onartu</string>
<string name="preferences_communication__sealed_sender_allow_from_anyone_description">Nahiz eta zure kontaktuetan ez egon eta beraiekin zure profila ez partekatu, gaitu igorle zigilatuta horrelako erabiltzaileek bidaltzen dituzten mezuetarako.</string>
<string name="preferences_communication__sealed_sender_learn_more">Gehiago jakin</string>
<string name="preferences_notifications__mentions">Aipamenak</string>
<!--Internal only preferences-->
<!--****************************************-->
<!--menus-->
@ -2060,6 +2104,7 @@ Inportatu \'SMSBackup and Restorekin\' bateragarria den enkriptatu gabeko babesk
<string name="RecipientBottomSheet_remove">Ezabatu</string>
<string name="RecipientBottomSheet_copied_to_clipboard">Arbelera kopiatuta</string>
<string name="GroupRecipientListItem_admin">Administratzailea</string>
<string name="GroupRecipientListItem_deny_description">Ukatu</string>
<!--GroupsLearnMoreBottomSheetDialogFragment-->
<string name="GroupsLearnMore_legacy_vs_new_groups">Jarauntsitako Taldeak vs. Talde Berriak</string>
<string name="GroupsLearnMore_what_are_legacy_groups">Zer dira Jarauntsitako Taldeak?</string>

View File

@ -1796,7 +1796,7 @@ Vastaanotetiin avaintenvaihtoviesti, joka kuuluu väärälle protokollaversiolle
<string name="preferences_storage__none">Ei mitään</string>
<string name="preferences_storage__s_messages">%1$s viestiä</string>
<string name="preferences_storage__custom">Mukautettu</string>
<string name="preferences_Storage__custom_conversation_length_limit">Mukautettu keskustelun pituusraja</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Mukautettu keskustelun pituusraja</string> -->
<string name="preferences_advanced__use_system_emoji">Käytä järjestelmän hymiöitä</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Ota Signalin oletushymiöt pois käytöstä</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Välitä kaikki puhelut Signal-palvelimen kautta välttääksesi IP-osoitteesi paljastumista yhteystiedollesi. Tämä toiminto heikentää puhelun laatua.</string>

View File

@ -2102,6 +2102,7 @@
<string name="BackupUtil_never">Jamais</string>
<string name="BackupUtil_unknown">Inconnu</string>
<string name="PhoneNumberPrivacy_nobody">Personne</string>
<string name="PhoneNumberPrivacy_my_contacts_see_description">Seuls vos contacts verront votre numéro de téléphone sur Signal.</string>
<string name="preferences_app_protection__screen_lock">Verrouillage de lécran</string>
<string name="preferences_app_protection__lock_signal_access_with_android_screen_lock_or_fingerprint">Verrouiller laccès à Signal avec le verrouillage de lécran dAndroid ou une empreinte</string>
<string name="preferences_app_protection__screen_lock_inactivity_timeout">Délai dinactivité avant verrouillage de lécran</string>

View File

@ -1808,7 +1808,7 @@
<string name="preferences_storage__none">Nessuno</string>
<string name="preferences_storage__s_messages">%1$s messaggi</string>
<string name="preferences_storage__custom">Personalizzato</string>
<string name="preferences_Storage__custom_conversation_length_limit">Limite di lunghezza delle conversazioni personalizzato</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Limite di lunghezza delle conversazioni personalizzato</string> -->
<string name="preferences_advanced__use_system_emoji">Usa le emoji di sistema</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Disattiva le emoji di Signal</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Ritrasmetti le chiamate attraverso i server di Signal per non rivelare il tuo indirizzo IP ai tuoi contatti. Abilitandolo verrà ridotta la qualità della chiamata.</string>

View File

@ -623,7 +623,7 @@
<string name="ShareableGroupLinkDialogFragment__manage_and_share">נהל ושתף</string>
<string name="ShareableGroupLinkDialogFragment__group_link">קישור קבוצה</string>
<string name="ShareableGroupLinkDialogFragment__share">שתף</string>
<string name="ShareableGroupLinkDialogFragment__reset_link">קישור איפוס</string>
<string name="ShareableGroupLinkDialogFragment__reset_link">אפס קישור</string>
<string name="ShareableGroupLinkDialogFragment__member_requests">בקשות חברי קבוצה</string>
<string name="ShareableGroupLinkDialogFragment__approve_new_members">אשר חברי קבוצה חדשים</string>
<string name="ShareableGroupLinkDialogFragment__enabled">מאופשר</string>
@ -924,6 +924,9 @@
<string name="MessageRecord_who_can_edit_group_membership_has_been_changed_to_s">מי יכול לערוך חברות קבוצה השתנה אל \"%1$s\".</string>
<!--GV2 group link invite access level change-->
<!--GV2 group link reset-->
<string name="MessageRecord_you_reset_the_group_link">איפסת את קישור הקבוצה.</string>
<string name="MessageRecord_s_reset_the_group_link">%1$s איפס/ה את קישור הקבוצה.</string>
<string name="MessageRecord_the_group_link_has_been_reset">קישור הקבוצה אופס.</string>
<!--GV2 group link joins-->
<!--GV2 group link requests-->
<string name="MessageRecord_you_sent_a_request_to_join_the_group">שלחת בקשה להצטרף אל הקבוצה.</string>
@ -2224,6 +2227,7 @@
<string name="RegistrationActivity_code_support_subject">הרשמת Signal - קוד וידוא עבור Android</string>
<string name="BackupUtil_never">אף פעם</string>
<string name="BackupUtil_unknown">בלתי ידוע</string>
<string name="PhoneNumberPrivacy_nobody">אף אחד</string>
<string name="preferences_app_protection__screen_lock">נעילת מסך</string>
<string name="preferences_app_protection__lock_signal_access_with_android_screen_lock_or_fingerprint">נעל גישה אל Signal באמצעות נעילת מסך או טביעת אצבע</string>
<string name="preferences_app_protection__screen_lock_inactivity_timeout">פסק זמן אי־פעילות של נעילת מסך</string>

View File

@ -86,9 +86,9 @@
<string name="BlockUnblockDialog_group_members_will_be_able_to_add_you">グループのメンバーはあなたをもう一度このグループに加えることができるようになります。</string>
<string name="BlockUnblockDialog_you_will_be_able_to_call_and_message_each_other">お互いにメッセージや通話ができるようになります。あなたの名前とプロフィール写真が相手と共有されます。</string>
<string name="BlockUnblockDialog_blocked_people_wont_be_able_to_call_you_or_send_you_messages">ブロックされた相手は、あなたへのメッセージ送信や通話発信ができなくなります。</string>
<string name="BlockUnblockDialog_unblock_s">%1$s をブロック解除しますか?</string>
<string name="BlockUnblockDialog_unblock">ブロックを解除</string>
<string name="BlockUnblockDialog_block">ブロック</string>
<string name="BlockUnblockDialog_unblock_s">%1$s のブロックを解除しますか?</string>
<string name="BlockUnblockDialog_unblock">ブロックを解除する</string>
<string name="BlockUnblockDialog_block">ブロックする</string>
<string name="BlockUnblockDialog_block_and_leave">ブロックして抜ける</string>
<string name="BlockUnblockDialog_block_and_delete">ブロックして削除</string>
<!--BucketedThreadMedia-->
@ -510,8 +510,8 @@
<string name="ManageRecipientActivity_this_person_is_in_your_contacts">このユーザは連絡先に入っています</string>
<string name="ManageRecipientActivity_disappearing_messages">消えるメッセージ</string>
<string name="ManageRecipientActivity_chat_color">チャットの色</string>
<string name="ManageRecipientActivity_block">ブロック</string>
<string name="ManageRecipientActivity_unblock">ブロック解除</string>
<string name="ManageRecipientActivity_block">ブロックする</string>
<string name="ManageRecipientActivity_unblock">ブロック解除する</string>
<string name="ManageRecipientActivity_view_safety_number">安全番号を表示</string>
<string name="ManageRecipientActivity_mute_notifications">通知をミュート</string>
<string name="ManageRecipientActivity_custom_notifications">カスタム通知</string>
@ -808,8 +808,14 @@
<string name="MessageRecord_s_changed_who_can_edit_group_membership_to_s">%1$s がグループ情報を編集できるユーザを「%2$s」に変更しました。</string>
<string name="MessageRecord_who_can_edit_group_membership_has_been_changed_to_s">グループ情報を編集できるユーザーが「%1$s」に変更されました。</string>
<!--GV2 group link invite access level change-->
<string name="MessageRecord_you_turned_on_the_group_link_with_admin_approval_off">管理者承認が不要なグループリンクを有効にしました。</string>
<string name="MessageRecord_you_turned_on_the_group_link_with_admin_approval_on">管理者承認制のグループリンクを有効にしました。</string>
<string name="MessageRecord_you_turned_off_the_group_link">グループリンクを無効にしました。</string>
<string name="MessageRecord_s_turned_on_the_group_link_with_admin_approval_off">%1$s が管理者承認が不要なグループリンクを有効にしました。</string>
<string name="MessageRecord_s_turned_on_the_group_link_with_admin_approval_on">%1$s が管理者承認制のグループリンクを有効にしました。</string>
<string name="MessageRecord_s_turned_off_the_group_link">%1$s がグループリンクを無効にしました。</string>
<string name="MessageRecord_the_group_link_has_been_turned_on_with_admin_approval_off">管理者承認が不要なグループリンクが有効になりました。</string>
<string name="MessageRecord_the_group_link_has_been_turned_on_with_admin_approval_on">管理者承認制のグループリンクが有効になりました。</string>
<string name="MessageRecord_the_group_link_has_been_turned_off">グループリンクが無効になりました。</string>
<!--GV2 group link reset-->
<string name="MessageRecord_you_reset_the_group_link">グループリンクをリセットしました。</string>
@ -1070,7 +1076,7 @@
<!--SubmitDebugLogActivity-->
<string name="SubmitDebugLogActivity_edit">編集</string>
<string name="SubmitDebugLogActivity_done">完了</string>
<string name="SubmitDebugLogActivity_tap_a_line_to_delete_it">線をタップして削除</string>
<string name="SubmitDebugLogActivity_tap_a_line_to_delete_it">タップした行を削除します</string>
<string name="SubmitDebugLogActivity_submit">送信する</string>
<string name="SubmitDebugLogActivity_failed_to_submit_logs">ログの送信に失敗しました</string>
<string name="SubmitDebugLogActivity_success">成功しました!</string>
@ -1519,7 +1525,7 @@
<string name="unknown_sender_view__add_to_contacts">連絡先に登録する</string>
<string name="unknown_sender_view__don_t_add_but_make_my_profile_visible">登録せずにプロフィール情報を提示する</string>
<!--verify_display_fragment-->
<string name="verify_display_fragment__if_you_wish_to_verify_the_security_of_your_end_to_end_encryption_with_s"><![CDATA[%s との暗号化を検証したい場合は、上記の番号が相手端末上の番号と一致するか確認してください。相手の端末上のQRコードを読み取るか、こちらのQRコードを相手に読み取ってもらうことでもきます。<a href="https://signal.org/redirect/safety-numbers">詳細</a>]]></string>
<string name="verify_display_fragment__if_you_wish_to_verify_the_security_of_your_end_to_end_encryption_with_s"><![CDATA[%s との暗号化を検証したい場合は、上記の番号が相手端末上の番号と一致するか確認してください。相手の端末上のQRコードを読み取るか、こちらのQRコードを相手に読み取ってもらうことでも可能です。<a href="https://signal.org/redirect/safety-numbers">詳細</a>]]></string>
<string name="verify_display_fragment__tap_to_scan">タップしてスキャンする</string>
<string name="verify_display_fragment__loading">読み込んでいます…</string>
<string name="verify_display_fragment__verified">検証済み</string>
@ -1684,7 +1690,7 @@
<string name="preferences__request_a_delivery_report_for_each_sms_message_you_send">送信するすべてのSMSで配信レポートを要求します</string>
<string name="preferences__chats">チャットとメディア</string>
<string name="preferences__storage">ストレージ</string>
<string name="preferences__conversation_length_limit">会話の長さ制限</string>
<string name="preferences__conversation_length_limit">会話の最大メッセージ件数</string>
<string name="preferences__keep_messages">メッセージの保存期間</string>
<string name="preferences__clear_message_history">メッセージ履歴を消去する</string>
<string name="preferences__linked_devices">リンク済み端末</string>
@ -1725,7 +1731,9 @@
<string name="preferences_storage__review_storage">ストレージを確認</string>
<string name="preferences_storage__delete_older_messages">より古いメッセージを消去しますか?</string>
<string name="preferences_storage__clear_message_history">メッセージ履歴を消去しますか?</string>
<string name="preferences_storage__this_will_permanently_delete_all_message_history_and_media">%1$sより古いすべてのメッセージ履歴とメディアを、この端末から完全に削除します。</string>
<string name="preferences_storage__this_will_permanently_trim_all_conversations_to_the_d_most_recent_messages">すべての会話で最新%1$s件のメッセージを残して完全に削除します。</string>
<string name="preferences_storage__this_will_delete_all_message_history_and_media_from_your_device">すべてのメッセージ履歴とメディアを、この端末から完全に削除します。</string>
<string name="preferences_storage__are_you_sure_you_want_to_delete_all_message_history">本当にすべてのメッセージ履歴を削除しますか?</string>
<string name="preferences_storage__all_message_history_will_be_permanently_removed_this_action_cannot_be_undone">すべてのメッセージ履歴を完全に削除します。取り消しはできません。</string>
<string name="preferences_storage__delete_all_now">すべて削除する</string>
@ -1736,11 +1744,12 @@
<string name="preferences_storage__none">なし</string>
<string name="preferences_storage__s_messages">%1$s件</string>
<string name="preferences_storage__custom">カスタム</string>
<string name="preferences_Storage__custom_conversation_length_limit">会話の長さ制限</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">会話の最大メッセージ件数</string> -->
<string name="preferences_advanced__use_system_emoji">システムの絵文字を使う</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Signal独自の絵文字を無効にします</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">すべての通話をSignalサーバで中継して、相手にIPアドレスを知られることを防ぎます。ただし通話の品質は下がります。</string>
<string name="preferences_advanced__always_relay_calls">通話を常に中継する</string>
<string name="preferences_app_protection__who_can">電話番号のプライバシー</string>
<string name="preferences_app_protection__app_access">アプリのアクセス</string>
<string name="preferences_app_protection__communication">通信</string>
<string name="preferences_chats__chats">チャット</string>
@ -2055,19 +2064,20 @@
<string name="RegistrationActivity_code_support_subject">Signal登録 - Android用認証コード</string>
<string name="BackupUtil_never">なし</string>
<string name="BackupUtil_unknown">不明</string>
<string name="preferences_app_protection__see_my_phone_number">私の電話番号を見る</string>
<string name="preferences_app_protection__find_me_by_phone_number">電話番号で私を見つける</string>
<string name="preferences_app_protection__see_my_phone_number">私の電話番号を確認できる人</string>
<string name="preferences_app_protection__find_me_by_phone_number">電話番号で私を検索できる人</string>
<string name="PhoneNumberPrivacy_everyone">全員</string>
<string name="PhoneNumberPrivacy_my_contacts">自分の連絡先</string>
<string name="PhoneNumberPrivacy_nobody">無人</string>
<string name="PhoneNumberPrivacy_everyone_see_description">あなたの電話番号は、メッセージを送信したすべての相手とグループに表示されます。</string>
<string name="PhoneNumberPrivacy_my_contacts_see_description">あなたの連絡先だけが、Signal上であなたの電話番号を見ることができます。</string>
<string name="PhoneNumberPrivacy_nobody">なし</string>
<string name="PhoneNumberPrivacy_everyone_see_description">あなたの電話番号は、あなたがメッセージを送信したすべての相手とグループに表示されます。</string>
<string name="PhoneNumberPrivacy_everyone_find_description">あなたの電話番号を連絡先に登録している人には、あなたがSignalの連絡先として表示されます。他の人は検索であなたを見つけることができます。</string>
<string name="PhoneNumberPrivacy_my_contacts_see_description">あなたの連絡先だけが、Signal上であなたの電話番号を確認できます。</string>
<string name="preferences_app_protection__screen_lock">画面ロック</string>
<string name="preferences_app_protection__lock_signal_access_with_android_screen_lock_or_fingerprint">SignalをAndroidの画面ロックや指紋認証でロックします</string>
<string name="preferences_app_protection__screen_lock_inactivity_timeout">画面ロックの無操作タイムアウト</string>
<string name="preferences_app_protection__signal_pin">Signal PIN</string>
<string name="preferences_app_protection__create_a_pin">PINを作成</string>
<string name="preferences_app_protection__change_your_pin">PINを変更</string>
<string name="preferences_app_protection__create_a_pin">PINを作成する</string>
<string name="preferences_app_protection__change_your_pin">PINを変更する</string>
<string name="preferences_app_protection__pin_reminders">PINリマインダー</string>
<string name="preferences_app_protection__pins_keep_information_stored_with_signal_encrypted">Signal内に保存された情報は、PINにより暗号化を保持されるため、あなたのみアクセスできます。PINを使うことで、Signalの再インストール時にあなたのプロフィール、設定および連絡先が復元されます。</string>
<string name="preferences_app_protection__add_extra_security_by_requiring_your_signal_pin_to_register">電話番号を再度Signalに登録する際にSignal PINを要求することで、さらにセキュリティを強化します。</string>

File diff suppressed because one or more lines are too long

View File

@ -1916,7 +1916,7 @@
<string name="preferences_storage__none">Nėra</string>
<string name="preferences_storage__s_messages">%1$s žinučių</string>
<string name="preferences_storage__custom">Tinkintai</string>
<string name="preferences_Storage__custom_conversation_length_limit">Tinkinta pokalbio ilgio riba</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Tinkinta pokalbio ilgio riba</string> -->
<string name="preferences_advanced__use_system_emoji">Naudoti sistemos jaustukus</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Išjungti Signal įtaisytą jaustukų palaikymą</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Retransliuoti visus skambučius per Signal serverį, kad būtų išvengta jūsų IP adreso atskleidimo jūsų adresatui. Įjungus, pablogės skambučių kokybė.</string>

View File

@ -214,8 +214,8 @@
<string name="ConversationActivity_quick_camera_unavailable">Camera niet beschikbaar</string>
<string name="ConversationActivity_unable_to_record_audio">Kan audio niet opnemen!</string>
<string name="ConversationActivity_you_cant_send_messages_to_this_group">Je kunt naar dit groepsgesprek geen berichten verzenden omdat je niet langer een lid van deze groep bent.</string>
<string name="ConversationActivity_there_is_no_app_available_to_handle_this_link_on_your_device">Er is geen app beschikbaar op je apparaat om deze koppeling te openen.</string>
<string name="ConversationActivity_your_request_to_join_has_been_sent_to_the_group_admin">Je verzoek om lid te worden van de groep is doorgestuurd naar een beheerder. Je krijgt bericht zodra deze gereageerd heeft.</string>
<string name="ConversationActivity_there_is_no_app_available_to_handle_this_link_on_your_device">Er is geen app beschikbaar op je apparaat om deze verwijzing te openen.</string>
<string name="ConversationActivity_your_request_to_join_has_been_sent_to_the_group_admin">Je verzoek om lid te worden van de groep is doorgestuurd naar een beheerder. Je krijgt een melding zodra deze een besluit heeft genomen.</string>
<string name="ConversationActivity_cancel_request">Verzoek annuleren</string>
<string name="ConversationActivity_to_send_audio_messages_allow_signal_access_to_your_microphone">Om audioberichten op te nemen, moet je Signal toegang geven tot je microfoon.</string>
<string name="ConversationActivity_signal_requires_the_microphone_permission_in_order_to_send_audio_messages">Signal heeft toegang nodig tot de microfoon om audioberichten te kunnen opnemen, maar deze is pertinent geweigerd. Ga naar de instellingen voor deze app, selecteer Machtigingen en schakel Microfoon in.</string>
@ -420,7 +420,7 @@
<string name="LinkPreviewsMegaphone_you_can_now_retrieve_link_previews_directly_from_any_website">Vanaf nu kun je voor elke website een voorbeeldafbeelding bijvoegen, maar wanneer je dat doet zou die website kunnen zien dat je ze vermeld.</string>
<!--LinkPreviewView-->
<string name="LinkPreviewView_no_link_preview_available">Geen voorbeeldafbeelding beschikbaar.</string>
<string name="LinkPreviewView_this_group_link_is_not_active">Deze groepslink is niet actief</string>
<string name="LinkPreviewView_this_group_link_is_not_active">Deze groepsverwijzing is niet actief</string>
<string name="LinkPreviewView_domain_date">%1$s · %2$s</string>
<!--LinkPreviewRepository-->
<plurals name="LinkPreviewRepository_d_members">
@ -523,10 +523,10 @@
<string name="ManageGroupActivity_legacy_group">Verouderde groep</string>
<string name="ManageGroupActivity_legacy_group_learn_more">Dit is een verouderde groep. Om nieuwe functionaliteiten te kunnen gebruiken zoals beheerders moet je een nieuwe groep aanmaken.</string>
<!--GroupMentionSettingDialog-->
<string name="GroupMentionSettingDialog_notify_me_for_mentions">Geef een melding bij mentions</string>
<string name="GroupMentionSettingDialog_notify_me_for_mentions">Geef me een melding bij naamsvermeldingen</string>
<string name="GroupMentionSettingDialog_receive_notifications_when_youre_mentioned_in_muted_chats">Wil je meldingen ontvangen wanneer iemand je in een gedempt gesprek vermeld?</string>
<string name="GroupMentionSettingDialog_default_notify_me">Standaard (geef me een notificatie)</string>
<string name="GroupMentionSettingDialog_default_dont_notify_me">Standaard (geef me geen bericht)</string>
<string name="GroupMentionSettingDialog_default_notify_me">Standaard (geef me een melding)</string>
<string name="GroupMentionSettingDialog_default_dont_notify_me">Standaard (geef me geen melding)</string>
<string name="GroupMentionSettingDialog_always_notify_me">Geef me altijd een bericht</string>
<string name="GroupMentionSettingDialog_dont_notify_me">Geef me nooit een bericht</string>
<!--ManageRecipientActivity-->
@ -566,24 +566,24 @@
<string name="CustomNotificationsDialogFragment__notification_sound">Meldingsgeluid</string>
<string name="CustomNotificationsDialogFragment__vibrate">Trillen</string>
<string name="CustomNotificationsDialogFragment__call_settings">Oproep instellingen</string>
<string name="CustomNotificationsDialogFragment__ringtone">Beltoon</string>
<string name="CustomNotificationsDialogFragment__ringtone">Oproepgeluid</string>
<string name="CustomNotificationsDialogFragment__enabled">Ingeschakeld</string>
<string name="CustomNotificationsDialogFragment__disabled">Uitgeschakeld</string>
<string name="CustomNotificationsDialogFragment__default">Systeemstandaard</string>
<!--ShareableGroupLinkDialogFragment-->
<string name="ShareableGroupLinkDialogFragment__shareable_group_link">Deelbare groepslink</string>
<string name="ShareableGroupLinkDialogFragment__shareable_group_link">Deelbare groepsverwijzing</string>
<string name="ShareableGroupLinkDialogFragment__manage_and_share">Beheer &amp; delen</string>
<string name="ShareableGroupLinkDialogFragment__group_link">Groepslink</string>
<string name="ShareableGroupLinkDialogFragment__group_link">Groepsverwijzing</string>
<string name="ShareableGroupLinkDialogFragment__share">Doorsturen via andere app</string>
<string name="ShareableGroupLinkDialogFragment__reset_link">Link vernieuwen</string>
<string name="ShareableGroupLinkDialogFragment__reset_link">Verwijzing vernieuwen</string>
<string name="ShareableGroupLinkDialogFragment__member_requests">Lidmaatschaps verzoeken</string>
<string name="ShareableGroupLinkDialogFragment__approve_new_members">Nieuwe groepsleden goedkeuren</string>
<string name="ShareableGroupLinkDialogFragment__enabled">Ingeschakeld</string>
<string name="ShareableGroupLinkDialogFragment__disabled">Uitgeschakeld</string>
<string name="ShareableGroupLinkDialogFragment__default">Systeemstandaard</string>
<string name="ShareableGroupLinkDialogFragment__group_link_reset">Groepslink vernieuwd</string>
<string name="ShareableGroupLinkDialogFragment__group_link_reset">Groepsverwijzing vernieuwd</string>
<string name="ShareableGroupLinkDialogFragment__require_an_admin_to_approve_new_members_joining_via_the_group_link">Vereis dat een beheerder nodig is om nieuwe leden goed te keuren.</string>
<string name="ShareableGroupLinkDialogFragment__are_you_sure_you_want_to_reset_the_group_link">Weet je zeker dat je de groepslink wilt vernieuwen? Dan zullen mensen geen lid meer kunnen worden via de huidige link.</string>
<string name="ShareableGroupLinkDialogFragment__are_you_sure_you_want_to_reset_the_group_link">Weet je zeker dat je de groepsverwijzing wilt vernieuwen? Men zal dan niet langer lid van de groep kunnen worden via de huidige verwijzing.</string>
<!--GroupLinkShareQrDialogFragment-->
<string name="GroupLinkShareQrDialogFragment__qr_code">QR code</string>
<string name="GroupLinkShareQrDialogFragment__people_who_scan_this_code_will">Personen die deze code scannen zullen in staat zijn lid te worden van je groep. Beheerders moeten deze personen nog steeds goedkeuren als deze instelling aan staat.</string>
@ -600,7 +600,7 @@
<string name="GroupJoinBottomSheetDialogFragment_request_to_join">Verzoek om lid te worden</string>
<string name="GroupJoinBottomSheetDialogFragment_unable_to_join_group_please_try_again_later">Kan geen lid worden van de groep, probeer het later nog eens</string>
<string name="GroupJoinBottomSheetDialogFragment_encountered_a_network_error">Er is een netwerkfout opgetreden.</string>
<string name="GroupJoinBottomSheetDialogFragment_this_group_link_is_not_active">Deze groepslink is niet actief</string>
<string name="GroupJoinBottomSheetDialogFragment_this_group_link_is_not_active">Deze groepsverwijzing is niet actief</string>
<string name="GroupJoinBottomSheetDialogFragment_unable_to_get_group_information_please_try_again_later">Kan geen informatie over de groep opvragen, probeer het later nog eens</string>
<string name="GroupJoinBottomSheetDialogFragment_direct_join">Wil je lid worden van deze groep en je naam en foto met de andere leden delen?</string>
<string name="GroupJoinBottomSheetDialogFragment_admin_approval_needed">Een beheerder van deze groep moet je verzoek goedkeuren voordat je lid kunt worden van deze groep. Wanneer je verzoekt om lid te worden zullen je naam en foto gedeeld worden met de groepsleden.</string>
@ -609,12 +609,12 @@
<item quantity="other">Groep · %1$d leden</item>
</plurals>
<!--GroupJoinUpdateRequiredBottomSheetDialogFragment-->
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_links_coming_soon">Groepslinks komen binnenkort</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal_to_use_group_links">Werk Signal bij om groepskoppelingen te kunnen gebruiken</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_links_coming_soon">Binnenkort komen er groepsverwijzingen</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal_to_use_group_links">Werk Signal bij om groepsverwijzingen te kunnen gebruiken</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_coming_soon">Lid worden van een groep is nog niet ondersteund in Signal. Deze functie zal in een komende versie uitgeleverd worden.</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_message">De versie van Signal die je gebruikt ondersteunt groepsverwijzingen niet. Werk Signal bij naar de meest recente versie om via een verwijzing lid te kunnen worden van een groep.</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal">Signal bijwerken</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_link_is_not_valid">Ongeldige groepslink</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_link_is_not_valid">Ongeldige groepsverwijzing</string>
<!--GV2 Request confirmation dialog-->
<string name="RequestConfirmationDialog_add_s_to_the_group">“%1$s” toevoegen aan de groep?</string>
<string name="RequestConfirmationDialog_deny_request_from_s">Verzoek van “%1$s” afwijzen?</string>
@ -998,10 +998,10 @@
<!--RecipientProvider-->
<string name="RecipientProvider_unnamed_group">Onbekende groep</string>
<!--RedPhone-->
<string name="RedPhone_answering">Antwoorden</string>
<string name="RedPhone_ending_call">Oproep beëindigen</string>
<string name="RedPhone_dialing">Oproep</string>
<string name="RedPhone_ringing">Bellen …</string>
<string name="RedPhone_answering">Wordt beantwoord </string>
<string name="RedPhone_ending_call">Oproep aan het beëindigen</string>
<string name="RedPhone_dialing">Verbinding aan het maken </string>
<string name="RedPhone_ringing">Aan het bellen …</string>
<string name="RedPhone_busy">Bezet</string>
<string name="RedPhone_connected">Verbonden</string>
<string name="RedPhone_recipient_unavailable">Ontvanger niet beschikbaar</string>
@ -1035,7 +1035,7 @@
<string name="RegistrationActivity_play_services_error">Google Play Services fout</string>
<string name="RegistrationActivity_google_play_services_is_updating_or_unavailable">De Google Play Services is momenteel aan het updaten of is tijdelijk niet beschikbaar. Probeer het nog eens.</string>
<string name="RegistrationActivity_terms_and_privacy">Gebruiksvoorwaarden &amp; privacybeleid</string>
<string name="RegistrationActivity_no_browser">Kan deze koppeling niet openen; geen webbrowser gevonden.</string>
<string name="RegistrationActivity_no_browser">Kan deze verwijzing niet openen; geen webbrowser gevonden.</string>
<string name="RegistrationActivity_more_information">Meer informatie</string>
<string name="RegistrationActivity_less_information">Minder informatie</string>
<string name="RegistrationActivity_signal_needs_access_to_your_contacts_and_media_in_order_to_connect_with_friends">Signal zal je om een aantal toestemmingen vragen: Signal moet je contactenlijst lezen om berichten te kunnen verzenden en om beveiligde oproepen tot stand te kunnen brengen naar je opgeslagen contacten.
@ -1706,7 +1706,7 @@ Signal zal nu toestemming vragen om je contactenlijst te lezen, om na te gaan wi
<string name="preferences__pref_enter_sends_title">Enter-toets verzendt</string>
<string name="preferences__pressing_the_enter_key_will_send_text_messages">Gebruik de Enter-toets voor het verzenden van tekstberichten</string>
<string name="preferences__generate_link_previews">Voorbeeldafbeeldingen genereren</string>
<string name="preferences__retrieve_link_previews_from_websites_for_messages">Sta Signal toe om voor elke koppeling naar een website die je verzendt een voorbeeldafbeelding genereren en bij te voegen. Echter, als je dit inschakelt zouden websites kunnen detecteren dat je ze in je bericht vermeld.</string>
<string name="preferences__retrieve_link_previews_from_websites_for_messages">Sta Signal toe om voor elke verwijzing naar een website die je verzendt een voorbeeldafbeelding genereren en aan je bericht bij te voegen. Echter, als je dit inschakelt zouden websites kunnen detecteren dat je ze in je bericht vermeld.</string>
<string name="preferences__choose_identity">Identiteit kiezen</string>
<string name="preferences__choose_your_contact_entry_from_the_contacts_list">Kies je contactgegevens uit de lijst met contactpersonen.</string>
<string name="preferences__change_passphrase">Wachtwoord wijzigen</string>
@ -1720,9 +1720,9 @@ Signal zal nu toestemming vragen om je contactenlijst te lezen, om na te gaan wi
<string name="preferences__inactivity_timeout_interval">Inactiviteitsduur voor vergrendeling</string>
<string name="preferences__notifications">Meldingen</string>
<string name="preferences__system_notification_settings">Systeemmeldingsinstellingen</string>
<string name="preferences__led_color">Notificatie-LED-kleur</string>
<string name="preferences__led_color">Melding-LED-kleur</string>
<string name="preferences__led_color_unknown">Onbekend</string>
<string name="preferences__pref_led_blink_title">Notificatie-LED-knipperpatroon</string>
<string name="preferences__pref_led_blink_title">Melding-LED-knipperpatroon</string>
<string name="preferences__sound">Geluid</string>
<string name="preferences__silent">Stil</string>
<string name="preferences__repeat_alerts">Herhaal meldingen</string>
@ -1813,7 +1813,7 @@ Signal zal nu toestemming vragen om je contactenlijst te lezen, om na te gaan wi
<string name="preferences_storage__none">Niets</string>
<string name="preferences_storage__s_messages">%1$s berichten</string>
<string name="preferences_storage__custom">Aangepast</string>
<string name="preferences_Storage__custom_conversation_length_limit">Aangepaste gesprekslengtelimiet</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Aangepaste gesprekslengtelimiet</string> -->
<string name="preferences_advanced__use_system_emoji">Gebruik systeem-emoji</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Schakel de ingebouwde emoji-ondersteuning van Signal uit</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Om te voorkomen dat je gesprekspartner je IP-adres kan achterhalen worden Signal-oproepen met niet-contactpersonen altijd omgeleid via de Signal-server. Door deze optie in te schakelen wordt dat ook gedaan voor Signal-oproepen met contacten wie wel in je contactenlijst staan. Dit leidt echter tot een verminderde geluids- en videokwaliteit.</string>
@ -1827,7 +1827,7 @@ Signal zal nu toestemming vragen om je contactenlijst te lezen, om na te gaan wi
<string name="preferences_notifications__in_chat_sounds">Ook geluid voor geopened gesprek</string>
<string name="preferences_notifications__show">Laat zien</string>
<string name="preferences_notifications__calls">Oproepen</string>
<string name="preferences_notifications__ringtone">Beltoon</string>
<string name="preferences_notifications__ringtone">Oproepgeluid</string>
<string name="preferences_chats__show_invitation_prompts">Uitnodigingsvoorstel weergeven</string>
<string name="preferences_chats__display_invitation_prompts_for_contacts_without_signal">Toon boven sms-gesprekken met gesprekspartners die niet op Signal zitten een suggestie om je gesprekspartner uit te nodigen op Signal</string>
<string name="preferences_chats__message_text_size">Tekstgrootte voor berichten</string>
@ -2241,9 +2241,9 @@ Signal zal nu toestemming vragen om je contactenlijst te lezen, om na te gaan wi
<!--GroupLinkBottomSheetDialogFragment-->
<string name="GroupLinkBottomSheet_share_via_signal">Delen via Signal</string>
<string name="GroupLinkBottomSheet_copy">Kopiëren</string>
<string name="GroupLinkBottomSheet_qr_code">QR Code</string>
<string name="GroupLinkBottomSheet_qr_code">QR-code</string>
<string name="GroupLinkBottomSheet_share">Doorsturen via andere app</string>
<string name="GroupLinkBottomSheet_copied_to_clipboard">Gekopieerd naar klembord</string>
<string name="GroupLinkBottomSheet_the_link_is_not_currently_active">De link is momenteel niet actief</string>
<string name="GroupLinkBottomSheet_the_link_is_not_currently_active">De verwijzing is momenteel niet actief</string>
<!--EOF-->
</resources>

View File

@ -1814,7 +1814,7 @@ Ved registrering sender me litt kontaktinformasjon til tenaren. Informasjonen ve
<string name="preferences_storage__none">Inga</string>
<string name="preferences_storage__s_messages">%1$s meldingar</string>
<string name="preferences_storage__custom">Sjølvvald</string>
<string name="preferences_Storage__custom_conversation_length_limit">Sjølvvald lengdgrense for samtalar</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Sjølvvald lengdgrense for samtalar</string> -->
<string name="preferences_advanced__use_system_emoji">Bruk emoji på systemet</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Slå av innebygd emoji-støtte i Signal</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Vidaresend alle samtalar gjennom Signal-tenaren for å unngå å visa IP-adressa di til kontakten din. Dette vil gi dårlegare samtalekvalitet.</string>

View File

@ -1908,7 +1908,7 @@ Otrzymano wiadomość wymiany klucz dla niepoprawnej wersji protokołu.</string>
<string name="preferences_storage__none">Brak</string>
<string name="preferences_storage__s_messages">%1$s wiadomości</string>
<string name="preferences_storage__custom">Własny</string>
<string name="preferences_Storage__custom_conversation_length_limit">Własny limit długości konwersacji</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Własny limit długości konwersacji</string> -->
<string name="preferences_advanced__use_system_emoji">Używaj emoji systemu</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Wyłącz wbudowane wspomaganie emoji Signal</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Przekazuj połączenia za pomocą serwerów Signal, aby uniknąć ujawnienia adresu IP Twoim kontaktom. Pogorszy to jakość połączenia.</string>

View File

@ -1741,6 +1741,7 @@
<string name="preferences__slow">Lento</string>
<string name="preferences__help">Ajuda</string>
<string name="preferences__advanced">Avançadas</string>
<string name="preferences__donate_to_signal">Doar para o Signal</string>
<string name="preferences__privacy">Privacidade</string>
<string name="preferences__mms_user_agent">Agente de usuário MMS</string>
<string name="preferences__advanced_mms_access_point_names">Configurações de MMS manuais</string>
@ -1794,7 +1795,9 @@
<string name="preferences_storage__review_storage">Checar armazenamento</string>
<string name="preferences_storage__delete_older_messages">Excluir as mensagens mais antigas?</string>
<string name="preferences_storage__clear_message_history">Excluir histórico de mensagens?</string>
<string name="preferences_storage__this_will_permanently_delete_all_message_history_and_media">Isto excluirá para sempre do seu dispositivo todo o histórico de mensagens e mídias que são mais antigos que %1$s.</string>
<string name="preferences_storage__this_will_permanently_trim_all_conversations_to_the_d_most_recent_messages">Isto excluirá permanentemente todas as conversas menos as %1$s mensagens mais recentes.</string>
<string name="preferences_storage__this_will_delete_all_message_history_and_media_from_your_device">Isto excluirá para sempre do seu dispositivo todo o histórico de mensagens e mídias.</string>
<string name="preferences_storage__are_you_sure_you_want_to_delete_all_message_history">Tem certeza que quer excluir todo o histórico de mensagens?</string>
<string name="preferences_storage__all_message_history_will_be_permanently_removed_this_action_cannot_be_undone">Todo o histórico de mensagens será excluído permanentemente. Esta ação não pode ser desfeita.</string>
<string name="preferences_storage__delete_all_now">Excluir tudo agora</string>
@ -1805,7 +1808,7 @@
<string name="preferences_storage__none">Nenhum</string>
<string name="preferences_storage__s_messages">%1$s mensagens</string>
<string name="preferences_storage__custom">Personalizado</string>
<string name="preferences_Storage__custom_conversation_length_limit">Limite personalizado de duração da conversa</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Limite personalizado de duração da conversa</string> -->
<string name="preferences_advanced__use_system_emoji">Usar emoji do sistema</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Desabilitar o suporte a emoji embutido do Signal</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Encaminhar todas as chamadas através do servidor Signal para evitar revelar seu endereço IP para seu contato. Habilitar reduzirá a qualidade da chamada.</string>

View File

@ -1909,7 +1909,7 @@
<string name="preferences_storage__none">Нет</string>
<string name="preferences_storage__s_messages">%1$s сообщений</string>
<string name="preferences_storage__custom">Пользовательский</string>
<string name="preferences_Storage__custom_conversation_length_limit">Пользовательский предел длины разговора</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Пользовательский предел длины разговора</string> -->
<string name="preferences_advanced__use_system_emoji">Использовать системные эмодзи</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Отключить встроенные эмодзи Signal</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Пропускать все звонки через сервер Signal, чтобы не раскрывать ваш IP-адрес собеседнику. Качество звонка ухудшится.</string>

View File

@ -1907,7 +1907,7 @@ Prejeto sporočilo za izmenjavo ključev za napačno različico protokola.</stri
<string name="preferences_storage__none">Brez</string>
<string name="preferences_storage__s_messages">%1$s sporočil</string>
<string name="preferences_storage__custom">Po meri</string>
<string name="preferences_Storage__custom_conversation_length_limit">Omejitev dolžine pogovorov</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Omejitev dolžine pogovorov</string> -->
<string name="preferences_advanced__use_system_emoji">Sistemski znaki emoji</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Izklop privzetih znakov emoji aplikacije Signal</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Vsi klici bodo posredovani preko strežnika Signal. S tem boste klicani strani onemogočili, da bi odkrila vaš naslov IP. Kvaliteta klica bo zaradi tega slabša.</string>

View File

@ -141,7 +141,7 @@
<string name="ConfirmIdentityDialog_you_may_wish_to_verify_your_safety_number_with_this_contact">Mund të doni të verifikoni numrin tuaj të sigurisë me këtë kontakt.</string>
<string name="ConfirmIdentityDialog_accept">Pranoje</string>
<!--ContactsCursorLoader-->
<string name="ContactsCursorLoader_recent_chats">Biseda së fundi</string>
<string name="ContactsCursorLoader_recent_chats">Fjalosje së fundi</string>
<string name="ContactsCursorLoader_contacts">Kontakte</string>
<string name="ContactsCursorLoader_groups">Grupe</string>
<string name="ContactsCursorLoader_phone_number_search">Kërkim numri telefoni</string>
@ -449,6 +449,7 @@
<!--RequestingMembersFragment-->
<string name="RequestingMembersFragment_pending_member_requests">Kërkesa anëtarësie pezull</string>
<string name="RequestingMembersFragment_no_member_requests_to_show">Ska kërkesa anëtarësie për tu shfaqur.</string>
<string name="RequestingMembersFragment_explanation">Persona në këtë listë po rreken të bëhen pjesë e këtij grupi përmes lidhjes së grupit.</string>
<string name="RequestingMembersFragment_added_s">U shtua \"%1$s\"</string>
<string name="RequestingMembersFragment_denied_s">U hodh poshtë \"%1$s\"</string>
<!--AddMembersActivity-->
@ -576,13 +577,19 @@ të përditësojnë Signal-in, ose ti hiqni para krijimit të grupit.</item>
<string name="ShareableGroupLinkDialogFragment__manage_and_share">Administroni &amp; ndani me të tjerë</string>
<string name="ShareableGroupLinkDialogFragment__group_link">Lidhje grupi</string>
<string name="ShareableGroupLinkDialogFragment__share">Ndajeni Me të Tjerë</string>
<string name="ShareableGroupLinkDialogFragment__reset_link">Ricaktoni lidhje</string>
<string name="ShareableGroupLinkDialogFragment__member_requests">Kërkesa anëtarësie</string>
<string name="ShareableGroupLinkDialogFragment__approve_new_members">Miratoni anëtarë të rinj</string>
<string name="ShareableGroupLinkDialogFragment__enabled">E aktivizuar</string>
<string name="ShareableGroupLinkDialogFragment__disabled">E çaktivizuar</string>
<string name="ShareableGroupLinkDialogFragment__default">Parazgjedhje</string>
<string name="ShareableGroupLinkDialogFragment__group_link_reset">Ricaktim lidhjeje grupi</string>
<string name="ShareableGroupLinkDialogFragment__require_an_admin_to_approve_new_members_joining_via_the_group_link">Kërko doemos që një përgjegjës të miratojë anëtarë të rinj që vijnë prej një lidhjeje grupi.</string>
<string name="ShareableGroupLinkDialogFragment__are_you_sure_you_want_to_reset_the_group_link">Jeni i sigurt se doni të ricaktohet lidhja e grupit? Njerëzit sdo të jenë më në gjendje të bëhen pjesë e grupit duke përdorur lidhjen e tanishme.</string>
<!--GroupLinkShareQrDialogFragment-->
<string name="GroupLinkShareQrDialogFragment__qr_code">Kod QR</string>
<string name="GroupLinkShareQrDialogFragment__people_who_scan_this_code_will">Njerëzit që skanojnë këtë kod, do të jenë në gjendje të bëhen pjesë e grupit tuaj. Përgjegjësve prapë do tju duhet të miratojnë anëtarë të rinj, nëse e keni të aktivizuar këtë mundësi.</string>
<string name="GroupLinkShareQrDialogFragment__share_code">Ndaj kod me të tjerë</string>
<!--GV2 Invite Revoke confirmation dialog-->
<string name="InviteRevokeConfirmationDialog_revoke_own_single_invite">Doni të shfuqizohet ftesa që u dërgua te %1$s?</string>
<plurals name="InviteRevokeConfirmationDialog_revoke_others_invites">
@ -593,6 +600,7 @@ të përditësojnë Signal-in, ose ti hiqni para krijimit të grupit.</item>
<string name="GroupJoinBottomSheetDialogFragment_you_are_already_a_member">Jeni tashmë anëtar</string>
<string name="GroupJoinBottomSheetDialogFragment_join">Merrni pjesë</string>
<string name="GroupJoinBottomSheetDialogFragment_request_to_join">Kërkoni të bëheni pjesë</string>
<string name="GroupJoinBottomSheetDialogFragment_unable_to_join_group_please_try_again_later">Sarrihet të bëhet pjesë e grupit. Ju lutemi, riprovoni më vonë</string>
<string name="GroupJoinBottomSheetDialogFragment_encountered_a_network_error">U has një gabim rrjeti.</string>
<string name="GroupJoinBottomSheetDialogFragment_this_group_link_is_not_active">Kjo lidhje grupi sështë aktive</string>
<string name="GroupJoinBottomSheetDialogFragment_unable_to_get_group_information_please_try_again_later">Sarrihet të merren të dhëna grupi, ju lutemi, riprovoni më vonë</string>
@ -603,8 +611,12 @@ të përditësojnë Signal-in, ose ti hiqni para krijimit të grupit.</item>
<item quantity="other">Grup · %1$d anëtarë</item>
</plurals>
<!--GroupJoinUpdateRequiredBottomSheetDialogFragment-->
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_links_coming_soon">Së shpejti mbërrijnë lidhje grupesh</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal_to_use_group_links">Që të përdorni lidhje grupi, përditësoni Signal-in</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_coming_soon">Bërja pjesë e një grupi përmes një lidhjeje nuk mbulohet ende nga Signal-i. Kjo veçori do të hidhet në qarkullim në një përditësim të ardhshëm.</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_message">Versioni i Signal-it që po përdorni nuk mbulon lidhje grupesh. Që të bëheni pjesë e një grupi përmes një lidhjeje, përditësojeni me versionin më të ri.</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal">Përditësoni Signal-in</string>
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_link_is_not_valid">Lidhja e grupit sështë e vlefshme </string>
<!--GV2 Request confirmation dialog-->
<string name="RequestConfirmationDialog_add_s_to_the_group">Të shtohet “%1$s” te grupi?</string>
<string name="RequestConfirmationDialog_deny_request_from_s">Të hidhet poshtë kërkesa prej “%1$s”?</string>
@ -838,19 +850,37 @@ të përditësojnë Signal-in, ose ti hiqni para krijimit të grupit.</item>
<string name="MessageRecord_s_changed_who_can_edit_group_membership_to_s">%1$s ndryshoi se cilët mund të përpunojnë anëtarësi grupi te \"%2$s\".</string>
<string name="MessageRecord_who_can_edit_group_membership_has_been_changed_to_s">Te \"%1$s\" është ndryshuas se kush mund të përpunojë anëtarësi te grupi.</string>
<!--GV2 group link invite access level change-->
<string name="MessageRecord_you_turned_on_the_group_link_with_admin_approval_off">Aktivizuat lidhjen e grupit me miratim nga përgjegjësi të çaktivizuar.</string>
<string name="MessageRecord_you_turned_on_the_group_link_with_admin_approval_on">Aktivizuat lidhjen e grupit me miratim nga përgjegjësi të aktivizuar.</string>
<string name="MessageRecord_you_turned_off_the_group_link">Çaktivizuat lidhjen e grupit.</string>
<string name="MessageRecord_s_turned_on_the_group_link_with_admin_approval_off">%1$s aktivizoi lidhjen e grupit me miratim nga përgjegjësi të çaktivizuar.</string>
<string name="MessageRecord_s_turned_on_the_group_link_with_admin_approval_on">%1$s aktivizoi lidhjen e grupit me miratim nga përgjegjësi të aktivizuar.</string>
<string name="MessageRecord_s_turned_off_the_group_link">%1$s çaktivizoi lidhjen e grupit.</string>
<string name="MessageRecord_the_group_link_has_been_turned_on_with_admin_approval_off">Lidhja e grupit është aktivizuar me miratim nga përgjegjësi të çaktivizuar.</string>
<string name="MessageRecord_the_group_link_has_been_turned_on_with_admin_approval_on">Lidhja e grupit është aktivizuar me miratim nga përgjegjësi të aktivizuar.</string>
<string name="MessageRecord_the_group_link_has_been_turned_off">Lidhja e grupit është çaktivizuar.</string>
<!--GV2 group link reset-->
<string name="MessageRecord_you_reset_the_group_link">Ricaktuat lidhjen e grupit.</string>
<string name="MessageRecord_s_reset_the_group_link">%1$s ricaktoi lidhjen e grupit.</string>
<string name="MessageRecord_the_group_link_has_been_reset">Lidhja e grupit është ricaktuar.</string>
<!--GV2 group link joins-->
<string name="MessageRecord_you_joined_the_group_via_the_group_link">U bëtë pjesë e grupit përmes lidhjes së grupit.</string>
<string name="MessageRecord_s_joined_the_group_via_the_group_link">%1$s u bë pjesë e grupit përmes lidhjes së grupit.</string>
<!--GV2 group link requests-->
<string name="MessageRecord_you_sent_a_request_to_join_the_group">Dërguat një kërkesë të bëheni pjesë e grupit.</string>
<string name="MessageRecord_s_requested_to_join_via_the_group_link">%1$s kërkoi të bëhet pjesë e grupit përmes lidhjes së grupit.</string>
<!--GV2 group link approvals-->
<string name="MessageRecord_s_approved_your_request_to_join_the_group">%1$s miratoi kërkesën tuaj për tu bërë pjesë e grupit.</string>
<string name="MessageRecord_s_approved_a_request_to_join_the_group_from_s">%1$s miratoi një kërkesë për tu bërë pjesë e grupit nga %2$s.</string>
<string name="MessageRecord_you_approved_a_request_to_join_the_group_from_s">Miratuat një kërkesë nga %1$s për tu bërë pjesë e grupit.</string>
<string name="MessageRecord_your_request_to_join_the_group_has_been_approved">Kërkesa jua për tu bërë pjesë e grupit u miratua.</string>
<string name="MessageRecord_a_request_to_join_the_group_from_s_has_been_approved">U miratua një kërkesë për tu bërë pjesë e grupit nga %1$s.</string>
<!--GV2 group link deny-->
<string name="MessageRecord_your_request_to_join_the_group_has_been_denied_by_an_admin">Kërkesa juaj për tu bërë pjesë e grupit është hedhur poshtë nga një përgjegjës.</string>
<string name="MessageRecord_s_denied_a_request_to_join_the_group_from_s">%1$s hodhi poshtë një kërkesë për tu bërë pjesë e grupit nga %2$s.</string>
<string name="MessageRecord_a_request_to_join_the_group_from_s_has_been_denied">U hodh poshtë një kërkesë për tu bërë pjesë e grupit nga %1$s.</string>
<string name="MessageRecord_you_canceled_your_request_to_join_the_group">Anuluat kërkesën tuaj për tu bërë pjesë e grupit.</string>
<string name="MessageRecord_s_canceled_their_request_to_join_the_group">%1$s anuloi kërkesën e tij për tu bërë pjesë e grupit.</string>
<!--End of GV2 specific update messages-->
<string name="MessageRecord_your_safety_number_with_s_has_changed">Numri juaj i sigurisë me %s është ndryshuar.</string>
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified">E shënuat numrin tuaj të sigurisë me %s si të verifikuar</string>
@ -1175,6 +1205,7 @@ të përditësojnë Signal-in, ose ti hiqni para krijimit të grupit.</item>
<string name="UsernameEditFragment_usernames_cannot_begin_with_a_number">Emrat e përdoruesve smund të fillojnë me një numër.</string>
<string name="UsernameEditFragment_username_is_invalid">Emri i përdoruesit është i pavlefshëm.</string>
<string name="UsernameEditFragment_usernames_must_be_between_a_and_b_characters">Emrat e përdoruesit duhet të jenë mes %1$d dhe %2$d shenjash.</string>
<string name="UsernameEditFragment_usernames_on_signal_are_optional">Emrat e përdoruesve në Signal janë opsionalë. Nëse vendosni të krijoni një emër përdoruesi, përdorues të tjerë të Signal-it do të jenë në gjendje tju gjejnë me këtë emër përdoruesi dhe të lidhen me ju pa ditur numrin tuaj të telefonit.</string>
<!--VerifyIdentityActivity-->
<string name="VerifyIdentityActivity_your_contact_is_running_an_old_version_of_signal">Kontakti juaj xhiron një version të vjetër të Signal-it. Ju lutemi, kërkojini ta përditësojë, para se të verifikohet numri juaj i sigurisë.</string>
<string name="VerifyIdentityActivity_your_contact_is_running_a_newer_version_of_Signal">Kontakti juaj xhiron një version më të ri të Signal-it, me një format kodi QR të papërputhshëm. Ju lutemi, që të krahasohen, përditësojeni.</string>
@ -1415,6 +1446,7 @@ të përditësojnë Signal-in, ose ti hiqni para krijimit të grupit.</item>
<!--safety_number_change_dialog-->
<string name="safety_number_change_dialog__safety_number_changes">Ndryshime Numri Sigurie</string>
<string name="safety_number_change_dialog__send_anyway">Dërgoje, sido qoftë</string>
<string name="safety_number_change_dialog__call_anyway">Thirre, sido qoftë</string>
<string name="safety_number_change_dialog__the_following_people_may_have_reinstalled_or_changed_devices">Personat vijues mund të kenë riinstaluar ose ndryshuar pajisjet. Për të siguruar privatësi, verifikoni me ta numrin tuaj të sigurisë.</string>
<string name="safety_number_change_dialog__view">Shihni</string>
<string name="safety_number_change_dialog__previous_verified">Verifikuar më herët</string>
@ -1722,6 +1754,8 @@ të përditësojnë Signal-in, ose ti hiqni para krijimit të grupit.</item>
<string name="preferences__chats">Fjalosje dhe media</string>
<string name="preferences__storage">Hapësirë</string>
<string name="preferences__conversation_length_limit">Kufi gjatësie bisedash</string>
<string name="preferences__keep_messages">Mbaji mesazhet</string>
<string name="preferences__clear_message_history">Spastro historik mesazhesh</string>
<string name="preferences__linked_devices">Pajisje të lidhura</string>
<string name="preferences__light_theme">E çelët</string>
<string name="preferences__dark_theme">E errët</string>
@ -1753,21 +1787,37 @@ aktivizoni Kyçje Regjistrimi, teksa PIN-i është i çaktivizuar.</string>
<string name="preferences_chats__when_using_wifi">Kur përdoret Wi-Fi</string>
<string name="preferences_chats__when_roaming">Nën roaming</string>
<string name="preferences_chats__media_auto_download">Vetëshkarkim mediash</string>
<string name="preferences_chats__message_history">Historik mesazhesh</string>
<string name="preferences_storage__storage_usage">Përdorim hapësire</string>
<string name="preferences_storage__photos">Foto</string>
<string name="preferences_storage__videos">Video</string>
<string name="preferences_storage__files">Kartela</string>
<string name="preferences_storage__audio">Audio</string>
<string name="preferences_storage__review_storage">Shqyrtoni hapësirën</string>
<string name="preferences_storage__delete_older_messages">Të fshihen mesazhet e vjetër?</string>
<string name="preferences_storage__clear_message_history">Të spastrohet historiku i mesazheve?</string>
<string name="preferences_storage__this_will_permanently_delete_all_message_history_and_media">Kjo do të sjellë fshirjen përgjithmonë nga pajisja juaj të krejt historikut dhe mediave të mesazheve që janë më të vjetër se %1$s.</string>
<string name="preferences_storage__this_will_permanently_trim_all_conversations_to_the_d_most_recent_messages">Kjo do të qethë përgjithnjë krejt bisedat sa %1$s mesazhet më të freskët.</string>
<string name="preferences_storage__this_will_delete_all_message_history_and_media_from_your_device">Kjo do të sjellë fshirjen përgjithmonë nga pajisja juaj të krejt historikut dhe mediave të mesazheve.</string>
<string name="preferences_storage__are_you_sure_you_want_to_delete_all_message_history">Jeni i sigurt se doni të fshihet krejt historiku i mesazheve?</string>
<string name="preferences_storage__all_message_history_will_be_permanently_removed_this_action_cannot_be_undone">Do të hiqet përgjithnjë krejt historiku i mesazheve. Ky veprim smund të zhbëhet.</string>
<string name="preferences_storage__delete_all_now">Fshije krejt tani</string>
<string name="preferences_storage__forever">Përgjithmonë</string>
<string name="preferences_storage__one_year">1 vit</string>
<string name="preferences_storage__six_months">6 muaj</string>
<string name="preferences_storage__thirty_days">30 ditë</string>
<string name="preferences_storage__none">Asnjë</string>
<string name="preferences_storage__s_messages">%1$s mesazhe</string>
<string name="preferences_storage__custom">Rregullo</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">Kufi vetjak gjatësie mesazhesh</string> -->
<string name="preferences_advanced__use_system_emoji">Përdor emoji të sistemit</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Çaktivizo mbulimin e brendshëm të Signal-it për emoji-t</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Kaloji krejt thirrjet përmes shërbyesit Signal për të shmangur zbulimin e adresës tuaj IP nga kontakti juaj. Aktivizimi do të ulë cilësinë e thirrjes.</string>
<string name="preferences_advanced__always_relay_calls">Kaloji përherë thirrjet përmes releje</string>
<string name="preferences_app_protection__who_can">Cili mund të…</string>
<string name="preferences_app_protection__app_access">Hyrje aplikacioni</string>
<string name="preferences_app_protection__communication">Komunikim</string>
<string name="preferences_chats__chats">Biseda</string>
<string name="preferences_chats__chats">Fjalosje</string>
<string name="preferences_notifications__messages">Mesazhe</string>
<string name="preferences_notifications__events">Veprimtari</string>
<string name="preferences_notifications__in_chat_sounds">Tinguj në fjalosje</string>
@ -1788,6 +1838,8 @@ aktivizoni Kyçje Regjistrimi, teksa PIN-i është i çaktivizuar.</string>
<string name="preferences_notifications__mentions">Përmendje</string>
<string name="preferences_notifications__notify_me">Njoftomë</string>
<string name="preferences_notifications__receive_notifications_when_youre_mentioned_in_muted_chats">Merrni njoftime kur përmendeni në fjalosje të heshtuara</string>
<string name="preferences_setup_a_username">Ujdisë një emër përdoruesi</string>
<string name="configurable_single_select__customize_option">Përshtatë një mundësi</string>
<!--Internal only preferences-->
<!--****************************************-->
<!--menus-->
@ -1831,7 +1883,7 @@ aktivizoni Kyçje Regjistrimi, teksa PIN-i është i çaktivizuar.</string>
<string name="conversation_list_settings_shortcut">Shkurtore rregullimesh</string>
<string name="conversation_list_search_description">Kërko</string>
<string name="conversation_list__pinned">E fiksuar</string>
<string name="conversation_list__chats">Biseda</string>
<string name="conversation_list__chats">Fjalosje</string>
<string name="conversation_list__you_can_only_pin_up_to_d_chats">Mund të fiksoni deri në %1$d fjalosje</string>
<!--conversation_list_item_view-->
<string name="conversation_list_item_view__contact_photo_image">Foto Kontakti</string>
@ -2088,6 +2140,14 @@ spastrohet dhe krejt lënda do të fshihet.</item>
<string name="RegistrationActivity_code_support_subject">Regjistrim Signal-i - Kod Verifikimi për Android</string>
<string name="BackupUtil_never">Kurrë</string>
<string name="BackupUtil_unknown">E panjohur</string>
<string name="preferences_app_protection__see_my_phone_number">Shohë numrin tim të telefonit</string>
<string name="preferences_app_protection__find_me_by_phone_number">Të më gjejë përmes numrit të telefonit</string>
<string name="PhoneNumberPrivacy_everyone">Cilido</string>
<string name="PhoneNumberPrivacy_my_contacts">Kontaktet e mia</string>
<string name="PhoneNumberPrivacy_nobody">Askush</string>
<string name="PhoneNumberPrivacy_everyone_see_description">Numri juaj i telefonit do të jetë i dukshëm për krejt personat dhe grupet të cilëve u dërgoni mesazh.</string>
<string name="PhoneNumberPrivacy_everyone_find_description">Cilido që ka numrin tuaj të telefonit në kontaktet e tij, do tju shohë si një kontakt në Signal. Të tjerët do të jenë në gjendje tju gjejnë përmes kërkimi.</string>
<string name="PhoneNumberPrivacy_my_contacts_see_description">Numrin tuaj të telefonit do ta shohin në Signal vetëm kontaktet tuaj.</string>
<string name="preferences_app_protection__screen_lock">Kyçje ekrani</string>
<string name="preferences_app_protection__lock_signal_access_with_android_screen_lock_or_fingerprint">kyçni hyrjen në Signal përmes kyçje ekrani ose shenja gishtash Android</string>
<string name="preferences_app_protection__screen_lock_inactivity_timeout">Kohë mbarimi plogështie për kyçje ekrani</string>
@ -2167,6 +2227,7 @@ spastrohet dhe krejt lënda do të fshihet.</item>
<string name="RecipientBottomSheet_remove">Hiqe</string>
<string name="RecipientBottomSheet_copied_to_clipboard">U kopjua në të papastër!</string>
<string name="GroupRecipientListItem_admin">Përgjegjës</string>
<string name="GroupRecipientListItem_approve_description">Miratoje</string>
<string name="GroupRecipientListItem_deny_description">Hidhe poshtë</string>
<!--GroupsLearnMoreBottomSheetDialogFragment-->
<string name="GroupsLearnMore_legacy_vs_new_groups">Grupe të Dikurshëm vs. Grupesh të Rinj</string>
@ -2176,8 +2237,11 @@ spastrohet dhe krejt lënda do të fshihet.</item>
<string name="GroupsLearnMore_paragraph_2">Grupet e Dikurshëm smund të shndërrohen në Grupe të Rinj, por mund të krijoni një Grup të ri me të njëjtët anëtarë.</string>
<string name="GroupsLearnMore_paragraph_3">Që të krijoni një Grup të Ri, krejt anëtarët duhet ta përditësojnë Signal-in me versionin më të ri.</string>
<!--GroupLinkBottomSheetDialogFragment-->
<string name="GroupLinkBottomSheet_share_via_signal">Ndajeni përmes Signal-i</string>
<string name="GroupLinkBottomSheet_copy">Kopjoje</string>
<string name="GroupLinkBottomSheet_qr_code">Kod QR</string>
<string name="GroupLinkBottomSheet_share">Ndajeni Me të Tjerë</string>
<string name="GroupLinkBottomSheet_copied_to_clipboard">U kopjua në të papastër!</string>
<string name="GroupLinkBottomSheet_the_link_is_not_currently_active">Lidhja hëpërhë sështë aktive</string>
<!--EOF-->
</resources>

File diff suppressed because one or more lines are too long

View File

@ -1751,7 +1751,7 @@
<string name="preferences_storage__none">靜音</string>
<string name="preferences_storage__s_messages">%1$s則訊息</string>
<string name="preferences_storage__custom">自訂</string>
<string name="preferences_Storage__custom_conversation_length_limit">自定義會話長度限制</string>
<!-- Removed by excludeNonTranslatables <string name="preferences_Storage__custom_conversation_length_limit">自定義會話長度限制</string> -->
<string name="preferences_advanced__use_system_emoji">使用系統表情符號</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">停用 Signal 內建的表情支援</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">透過 Signal 伺服器轉發通話,來避免透露你的 IP 位址給你的聯絡人。啟用時,會降低通話品質。</string>

View File

@ -20,6 +20,8 @@
<attr name="secondary_background" format="reference" />
<attr name="secondary_background_bubble" format="reference" />
<attr name="radio_theme" format="reference" />
<attr name="conversation_list_item_background" format="reference"/>
<attr name="conversation_list_item_contact_color" format="reference|color"/>
<attr name="conversation_list_item_subject_color" format="reference|color"/>

View File

@ -2137,7 +2137,6 @@
<string name="preferences_storage__none">None</string>
<string name="preferences_storage__s_messages">%1$s messages</string>
<string name="preferences_storage__custom">Custom</string>
<string name="preferences_Storage__custom_conversation_length_limit">Custom conversation length limit</string>
<string name="preferences_advanced__use_system_emoji">Use system emoji</string>
<string name="preferences_advanced__disable_signal_built_in_emoji_support">Disable Signal\'s built-in emoji support</string>
<string name="preferences_advanced__relay_all_calls_through_the_signal_server_to_avoid_revealing_your_ip_address">Relay all calls through the Signal server to avoid revealing your IP address to your contact. Enabling will reduce call quality.</string>

View File

@ -501,6 +501,14 @@
<item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay.Signal.Button.Rounded</item>
</style>
<style name="Widget.Signal.CompoundButton.RadioButton" parent="Widget.AppCompat.CompoundButton.RadioButton">
<item name="colorControlNormal">@color/core_grey_20</item>
</style>
<style name="Widget.Signal.CompoundButton.RadioButton.Light">
<item name="colorControlNormal">@color/core_grey_50</item>
</style>
<style name="ShapeAppearanceOverlay.Signal.Button.Rounded" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>

View File

@ -197,6 +197,8 @@
<item name="android:homeAsUpIndicator">@drawable/ic_arrow_left_24</item>
<!--<item name="android:windowContentOverlay">@drawable/compat_actionbar_shadow_background</item>-->
<item name="radio_theme">@style/Widget.Signal.CompoundButton.RadioButton.Light</item>
<item name="kbs_splash_image">@drawable/ic_kbs_splash_light_svg</item>
<item name="kbs_confirm_lottie_loading">@raw/lottie_kbs_loading_light</item>
<item name="kbs_confirm_lottie_success">@raw/lottie_kbs_success_light</item>
@ -532,6 +534,8 @@
<item name="homeAsUpIndicator">@drawable/ic_arrow_left_24</item>
<item name="android:homeAsUpIndicator">@drawable/ic_arrow_left_24</item>
<item name="radio_theme">@style/Widget.Signal.CompoundButton.RadioButton</item>
<item name="tinted_circle_background">@drawable/tinted_circle_dark</item>
<item name="kbs_splash_image">@drawable/ic_kbs_splash_dark_svg</item>

View File

@ -261,19 +261,19 @@ public final class GroupIdTest {
groupId.requireV2();
}
@Test(expected = BadGroupIdException.class)
public void cannot_create_v1_with_a_v2_length() throws IOException, BadGroupIdException {
GroupId.v1(Hex.fromStringCondensed("9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e"));
}
@Test(expected = AssertionError.class)
public void cannot_create_v1_with_a_v2_length() throws IOException {
public void cannot_create_v1_with_a_v2_length_assert() throws IOException {
GroupId.v1orThrow(Hex.fromStringCondensed("9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e"));
}
@Test(expected = BadGroupIdException.class)
public void cannot_create_v2_with_a_v1_length() throws IOException, BadGroupIdException {
GroupId.v2(Hex.fromStringCondensed("000102030405060708090a0b0c0d0e0f"));
}
@Test(expected = AssertionError.class)
public void cannot_create_v2_with_a_v1_length_assert() throws IOException {
GroupId.v2orThrow(Hex.fromStringCondensed("000102030405060708090a0b0c0d0e0f"));
public void cannot_create_v1_with_wrong_length() throws IOException, BadGroupIdException {
GroupId.v1Exact(Hex.fromStringCondensed("000102030405060708090a0b0c0d0e"));
}
@Test
@ -292,6 +292,22 @@ public final class GroupIdTest {
assertTrue(v1.isV1());
}
@Test
public void v1_static_factory() throws BadGroupIdException {
GroupId.V1 v1 = GroupId.v1(new byte[]{ 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8 });
assertEquals("__textsecure_group__!090a0b0c0d0e0f000102030405060708", v1.toString());
assertTrue(v1.isV1());
}
@Test
public void v1Exact_static_factory() throws BadGroupIdException {
GroupId.V1 v1 = GroupId.v1Exact(new byte[]{ 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8 });
assertEquals("__textsecure_group__!090a0b0c0d0e0f000102030405060708", v1.toString());
assertTrue(v1.isV1());
}
@Test
public void parse_bytes_to_v1_via_push() throws BadGroupIdException {
GroupId.V1 v1 = GroupId.push(new byte[]{ 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8 }).requireV1();

View File

@ -1,10 +1,11 @@
package org.thoughtcrime.securesms.storage;
import org.junit.Test;
import org.thoughtcrime.securesms.storage.GroupV1ConflictMerger;
import org.thoughtcrime.securesms.storage.StorageSyncHelper.KeyGenerator;
import org.whispersystems.signalservice.api.storage.SignalGroupV1Record;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import static org.junit.Assert.assertArrayEquals;
@ -14,10 +15,11 @@ import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.thoughtcrime.securesms.testutil.TestHelpers.byteArray;
public class GroupV1ConflictMergerTest {
public final class GroupV1ConflictMergerTest {
private static final byte[] GENERATED_KEY = byteArray(8675309);
private static final KeyGenerator KEY_GENERATOR = mock(KeyGenerator.class);
private static byte[] GENERATED_KEY = byteArray(8675309);
private static KeyGenerator KEY_GENERATOR = mock(KeyGenerator.class);
static {
when(KEY_GENERATOR.generate()).thenReturn(GENERATED_KEY);
}
@ -78,4 +80,31 @@ public class GroupV1ConflictMergerTest {
assertEquals(local, merged);
}
@Test
public void merge_excludeBadGroupId() {
SignalGroupV1Record badRemote = new SignalGroupV1Record.Builder(byteArray(1), badGroupKey(99))
.setBlocked(false)
.setProfileSharingEnabled(true)
.setArchived(true)
.build();
SignalGroupV1Record goodRemote = new SignalGroupV1Record.Builder(byteArray(1), groupKey(99))
.setBlocked(false)
.setProfileSharingEnabled(true)
.setArchived(true)
.build();
Collection<SignalGroupV1Record> invalid = new GroupV1ConflictMerger(Collections.emptyList()).getInvalidEntries(Arrays.asList(badRemote, goodRemote));
assertEquals(Collections.singletonList(badRemote), invalid);
}
private static byte[] groupKey(int value) {
return byteArray(value, 16);
}
private static byte[] badGroupKey(int value) {
return byteArray(value, 32);
}
}

View File

@ -1,11 +1,11 @@
package org.thoughtcrime.securesms.storage;
import org.junit.Test;
import org.signal.zkgroup.InvalidInputException;
import org.signal.zkgroup.groups.GroupMasterKey;
import org.thoughtcrime.securesms.storage.StorageSyncHelper.KeyGenerator;
import org.whispersystems.signalservice.api.storage.SignalGroupV2Record;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import static org.junit.Assert.assertArrayEquals;
@ -15,10 +15,11 @@ import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.thoughtcrime.securesms.testutil.TestHelpers.byteArray;
public class GroupV2ConflictMergerTest {
public final class GroupV2ConflictMergerTest {
private static final byte[] GENERATED_KEY = byteArray(8675309);
private static final KeyGenerator KEY_GENERATOR = mock(KeyGenerator.class);
private static byte[] GENERATED_KEY = byteArray(8675309);
private static KeyGenerator KEY_GENERATOR = mock(KeyGenerator.class);
static {
when(KEY_GENERATOR.generate()).thenReturn(GENERATED_KEY);
}
@ -26,20 +27,20 @@ public class GroupV2ConflictMergerTest {
@Test
public void merge_alwaysPreferRemote_exceptProfileSharingIsEitherOr() {
SignalGroupV2Record remote = new SignalGroupV2Record.Builder(byteArray(1), groupKey(100))
.setBlocked(false)
.setProfileSharingEnabled(false)
.setArchived(false)
.build();
.setBlocked(false)
.setProfileSharingEnabled(false)
.setArchived(false)
.build();
SignalGroupV2Record local = new SignalGroupV2Record.Builder(byteArray(2), groupKey(100))
.setBlocked(true)
.setProfileSharingEnabled(true)
.setArchived(true)
.build();
.setBlocked(true)
.setProfileSharingEnabled(true)
.setArchived(true)
.build();
SignalGroupV2Record merged = new GroupV2ConflictMerger(Collections.singletonList(local)).merge(remote, local, KEY_GENERATOR);
assertArrayEquals(GENERATED_KEY, merged.getId().getRaw());
assertEquals(groupKey(100), merged.getMasterKey());
assertArrayEquals(groupKey(100), merged.getMasterKeyBytes());
assertFalse(merged.isBlocked());
assertFalse(merged.isArchived());
}
@ -80,11 +81,30 @@ public class GroupV2ConflictMergerTest {
assertEquals(local, merged);
}
private static GroupMasterKey groupKey(int value) {
try {
return new GroupMasterKey(byteArray(value, 32));
} catch (InvalidInputException e) {
throw new AssertionError(e);
}
@Test
public void merge_excludeBadGroupId() {
SignalGroupV2Record badRemote = new SignalGroupV2Record.Builder(byteArray(1), badGroupKey(99))
.setBlocked(false)
.setProfileSharingEnabled(true)
.setArchived(true)
.build();
SignalGroupV2Record goodRemote = new SignalGroupV2Record.Builder(byteArray(1), groupKey(99))
.setBlocked(false)
.setProfileSharingEnabled(true)
.setArchived(true)
.build();
Collection<SignalGroupV2Record> invalid = new GroupV2ConflictMerger(Collections.emptyList()).getInvalidEntries(Arrays.asList(badRemote, goodRemote));
assertEquals(Collections.singletonList(badRemote), invalid);
}
private static byte[] groupKey(int value) {
return byteArray(value, 32);
}
private static byte[] badGroupKey(int value) {
return byteArray(value, 16);
}
}

View File

@ -28,9 +28,11 @@ import org.whispersystems.signalservice.api.storage.StorageId;
import org.whispersystems.signalservice.api.util.UuidUtil;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@ -85,20 +87,57 @@ public final class StorageSyncHelperTest {
KeyDifferenceResult result = StorageSyncHelper.findKeyDifference(keyListOf(1, 2, 3), keyListOf(1, 2, 3));
assertTrue(result.getLocalOnlyKeys().isEmpty());
assertTrue(result.getRemoteOnlyKeys().isEmpty());
assertFalse(result.hasTypeMismatches());
}
@Test
public void findKeyDifference_noOverlap() {
KeyDifferenceResult result = StorageSyncHelper.findKeyDifference(keyListOf(1, 2, 3), keyListOf(4, 5, 6));
assertEquals(keyListOf(1, 2, 3), result.getRemoteOnlyKeys());
assertEquals(keyListOf(4, 5, 6), result.getLocalOnlyKeys());
assertContentsEqual(keyListOf(1, 2, 3), result.getRemoteOnlyKeys());
assertContentsEqual(keyListOf(4, 5, 6), result.getLocalOnlyKeys());
assertFalse(result.hasTypeMismatches());
}
@Test
public void findKeyDifference_someOverlap() {
KeyDifferenceResult result = StorageSyncHelper.findKeyDifference(keyListOf(1, 2, 3), keyListOf(2, 3, 4));
assertEquals(keyListOf(1), result.getRemoteOnlyKeys());
assertEquals(keyListOf(4), result.getLocalOnlyKeys());
assertContentsEqual(keyListOf(1), result.getRemoteOnlyKeys());
assertContentsEqual(keyListOf(4), result.getLocalOnlyKeys());
assertFalse(result.hasTypeMismatches());
}
@Test
public void findKeyDifference_typeMismatch_allOverlap() {
KeyDifferenceResult result = StorageSyncHelper.findKeyDifference(keyListOf(new HashMap<Integer, Integer>() {{
put(100, 1);
put(200, 2);
}}),
keyListOf(new HashMap<Integer, Integer>() {{
put(100, 1);
put(200, 1);
}}));
assertTrue(result.getLocalOnlyKeys().isEmpty());
assertTrue(result.getRemoteOnlyKeys().isEmpty());
assertTrue(result.hasTypeMismatches());
}
@Test
public void findKeyDifference_typeMismatch_someOverlap() {
KeyDifferenceResult result = StorageSyncHelper.findKeyDifference(keyListOf(new HashMap<Integer, Integer>() {{
put(100, 1);
put(200, 2);
put(300, 1);
}}),
keyListOf(new HashMap<Integer, Integer>() {{
put(100, 1);
put(200, 1);
put(400, 1);
}}));
assertContentsEqual(Arrays.asList(StorageId.forType(byteArray(300), 1)), result.getRemoteOnlyKeys());
assertContentsEqual(Arrays.asList(StorageId.forType(byteArray(400), 1)), result.getLocalOnlyKeys());
assertTrue(result.hasTypeMismatches());
}
@Test
@ -129,6 +168,34 @@ public final class StorageSyncHelperTest {
assertEquals(setOf(remote1), result.getRemoteDeletes());
}
@Test
public void resolveConflict_contact_deleteBadGv1() {
SignalGroupV1Record remote1 = badGroupV1(1, 1, true, false);
SignalGroupV1Record local1 = groupV1(2, 1, true, true);
MergeResult result = StorageSyncHelper.resolveConflict(recordSetOf(remote1), recordSetOf(local1));
assertTrue(result.getLocalContactInserts().isEmpty());
assertTrue(result.getLocalContactUpdates().isEmpty());
assertEquals(setOf(record(local1)), result.getRemoteInserts());
assertTrue(result.getRemoteUpdates().isEmpty());
assertEquals(setOf(remote1), result.getRemoteDeletes());
}
@Test
public void resolveConflict_contact_deleteBadGv2() {
SignalGroupV2Record remote1 = badGroupV2(1, 2, true, false);
SignalGroupV2Record local1 = groupV2(2, 2, true, false);
MergeResult result = StorageSyncHelper.resolveConflict(recordSetOf(remote1), recordSetOf(local1));
assertTrue(result.getLocalContactInserts().isEmpty());
assertTrue(result.getLocalContactUpdates().isEmpty());
assertEquals(setOf(record(local1)), result.getRemoteInserts());
assertTrue(result.getRemoteUpdates().isEmpty());
assertEquals(setOf(remote1), result.getRemoteDeletes());
}
@Test
public void resolveConflict_contact_sameAsRemote() {
SignalContactRecord remote1 = contact(1, UUID_A, E164_A, "a");
@ -417,7 +484,15 @@ public final class StorageSyncHelperTest {
boolean blocked,
boolean profileSharing)
{
return new SignalGroupV1Record.Builder(byteArray(key), byteArray(groupId)).setBlocked(blocked).setProfileSharingEnabled(profileSharing).build();
return new SignalGroupV1Record.Builder(byteArray(key), byteArray(groupId, 16)).setBlocked(blocked).setProfileSharingEnabled(profileSharing).build();
}
private static SignalGroupV1Record badGroupV1(int key,
int groupId,
boolean blocked,
boolean profileSharing)
{
return new SignalGroupV1Record.Builder(byteArray(key), byteArray(groupId, 42)).setBlocked(blocked).setProfileSharingEnabled(profileSharing).build();
}
private static SignalGroupV2Record groupV2(int key,
@ -425,11 +500,15 @@ public final class StorageSyncHelperTest {
boolean blocked,
boolean profileSharing)
{
try {
return new SignalGroupV2Record.Builder(byteArray(key), new GroupMasterKey(byteArray(groupId, 32))).setBlocked(blocked).setProfileSharingEnabled(profileSharing).build();
} catch (InvalidInputException e) {
throw new AssertionError(e);
}
return new SignalGroupV2Record.Builder(byteArray(key), byteArray(groupId, 32)).setBlocked(blocked).setProfileSharingEnabled(profileSharing).build();
}
private static SignalGroupV2Record badGroupV2(int key,
int groupId,
boolean blocked,
boolean profileSharing)
{
return new SignalGroupV2Record.Builder(byteArray(key), byteArray(groupId, 42)).setBlocked(blocked).setProfileSharingEnabled(profileSharing).build();
}
private static <E extends SignalRecord> StorageSyncHelper.RecordUpdate<E> update(E oldRecord, E newRecord) {
@ -448,6 +527,10 @@ public final class StorageSyncHelperTest {
return Stream.of(byteListOf(vals)).map(b -> StorageId.forType(b, 1)).toList();
}
private static List<StorageId> keyListOf(Map<Integer, Integer> vals) {
return Stream.of(vals).map(e -> StorageId.forType(byteArray(e.getKey()), e.getValue())).toList();
}
private static StorageId contactKey(int val) {
return StorageId.forContact(byteArray(val));
}

View File

@ -470,10 +470,6 @@ public class SignalServiceAccountManager {
String authToken = this.pushServiceSocket.getStorageAuth();
StorageItems items = this.pushServiceSocket.readStorageItems(authToken, operation.build());
if (items.getItemsCount() != storageKeys.size()) {
Log.w(TAG, "Failed to find all remote keys! Requested: " + storageKeys.size() + ", Found: " + items.getItemsCount());
}
for (StorageItem item : items.getItemsList()) {
Integer type = typeMap.get(item.getKey());
if (type != null) {

View File

@ -11,20 +11,16 @@ import java.util.Objects;
public final class SignalGroupV2Record implements SignalRecord {
private final StorageId id;
private final GroupV2Record proto;
private final GroupMasterKey masterKey;
private final boolean hasUnknownFields;
private final StorageId id;
private final GroupV2Record proto;
private final byte[] masterKey;
private final boolean hasUnknownFields;
public SignalGroupV2Record(StorageId id, GroupV2Record proto) {
this.id = id;
this.proto = proto;
this.hasUnknownFields = ProtoUtil.hasUnknownFields(proto);
try {
this.masterKey = new GroupMasterKey(proto.getMasterKey().toByteArray());
} catch (InvalidInputException e) {
throw new AssertionError(e);
}
this.masterKey = proto.getMasterKey().toByteArray();
}
@Override
@ -40,10 +36,18 @@ public final class SignalGroupV2Record implements SignalRecord {
return hasUnknownFields ? proto.toByteArray() : null;
}
public GroupMasterKey getMasterKey() {
public byte[] getMasterKeyBytes() {
return masterKey;
}
public GroupMasterKey getMasterKeyOrThrow() {
try {
return new GroupMasterKey(masterKey);
} catch (InvalidInputException e) {
throw new AssertionError(e);
}
}
public boolean isBlocked() {
return proto.getBlocked();
}
@ -81,10 +85,14 @@ public final class SignalGroupV2Record implements SignalRecord {
private byte[] unknownFields;
public Builder(byte[] rawId, GroupMasterKey masterKey) {
this(rawId, masterKey.serialize());
}
public Builder(byte[] rawId, byte[] masterKey) {
this.id = StorageId.forGroupV2(rawId);
this.builder = GroupV2Record.newBuilder();
builder.setMasterKey(ByteString.copyFrom(masterKey.serialize()));
builder.setMasterKey(ByteString.copyFrom(masterKey));
}
public Builder setUnknownFields(byte[] serializedUnknowns) {