mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Compare commits
2 Commits
release-1.
...
export-acc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dbdd724ad | ||
|
|
0122282a72 |
14
.idea/codeStyles/Project.xml
generated
14
.idea/codeStyles/Project.xml
generated
@@ -28,20 +28,6 @@
|
||||
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
|
||||
</JavaCodeStyleSettings>
|
||||
<JetCodeStyleSettings>
|
||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value />
|
||||
</option>
|
||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||
<value>
|
||||
<package name="" alias="false" withSubpackages="true" />
|
||||
<package name="java" alias="false" withSubpackages="true" />
|
||||
<package name="javax" alias="false" withSubpackages="true" />
|
||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||
<package name="" alias="true" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<XML>
|
||||
|
||||
1
bramble-android/.gitignore
vendored
1
bramble-android/.gitignore
vendored
@@ -3,4 +3,3 @@ gen
|
||||
build
|
||||
.settings
|
||||
src/main/res/raw/*.zip
|
||||
src/main/jniLibs
|
||||
@@ -5,14 +5,14 @@ apply plugin: 'witness'
|
||||
apply from: 'witness.gradle'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.2'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode rootProject.ext.versionCode
|
||||
versionName rootProject.ext.versionName
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 28
|
||||
versionCode 10209
|
||||
versionName "1.2.9"
|
||||
consumerProguardFiles 'proguard-rules.txt'
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
@@ -53,12 +53,10 @@ dependencies {
|
||||
}
|
||||
|
||||
def torBinariesDir = 'src/main/res/raw'
|
||||
def torLibsDir = 'src/main/jniLibs'
|
||||
|
||||
task cleanTorBinaries {
|
||||
doLast {
|
||||
delete fileTree(torBinariesDir) { include '*.zip' }
|
||||
delete fileTree(torLibsDir) { include '**/*.so' }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,36 +67,8 @@ task unpackTorBinaries {
|
||||
copy {
|
||||
from configurations.tor.collect { zipTree(it) }
|
||||
into torBinariesDir
|
||||
include 'geoip.zip'
|
||||
}
|
||||
configurations.tor.each { outer ->
|
||||
zipTree(outer).each { inner ->
|
||||
if (inner.name.endsWith('_arm_pie.zip')) {
|
||||
copy {
|
||||
from zipTree(inner)
|
||||
into torLibsDir
|
||||
rename '(.*)', 'armeabi-v7a/lib$1.so'
|
||||
}
|
||||
} else if (inner.name.endsWith('_arm64_pie.zip')) {
|
||||
copy {
|
||||
from zipTree(inner)
|
||||
into torLibsDir
|
||||
rename '(.*)', 'arm64-v8a/lib$1.so'
|
||||
}
|
||||
} else if (inner.name.endsWith('_x86_pie.zip')) {
|
||||
copy {
|
||||
from zipTree(inner)
|
||||
into torLibsDir
|
||||
rename '(.*)', 'x86/lib$1.so'
|
||||
}
|
||||
} else if (inner.name.endsWith('_x86_64_pie.zip')) {
|
||||
copy {
|
||||
from zipTree(inner)
|
||||
into torLibsDir
|
||||
rename '(.*)', 'x86_64/lib$1.so'
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Remove after next Tor upgrade, which won't include non-PIE binaries
|
||||
include 'geoip.zip', '*_pie.zip'
|
||||
}
|
||||
}
|
||||
dependsOn cleanTorBinaries
|
||||
@@ -106,6 +76,5 @@ task unpackTorBinaries {
|
||||
|
||||
tasks.withType(MergeResources) {
|
||||
inputs.dir torBinariesDir
|
||||
inputs.dir torLibsDir
|
||||
dependsOn unpackTorBinaries
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ class AndroidBluetoothPlugin
|
||||
private final Application app;
|
||||
private final Clock clock;
|
||||
|
||||
private volatile boolean wasEnabledByUs = false;
|
||||
private volatile BluetoothStateReceiver receiver = null;
|
||||
|
||||
// Non-null if the plugin started successfully
|
||||
@@ -132,10 +133,41 @@ class AndroidBluetoothPlugin
|
||||
return adapter != null && adapter.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
void enableAdapter() {
|
||||
if (adapter != null && !adapter.isEnabled()) {
|
||||
if (adapter.enable()) {
|
||||
LOG.info("Enabling Bluetooth");
|
||||
wasEnabledByUs = true;
|
||||
} else {
|
||||
LOG.info("Could not enable Bluetooth");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void disableAdapterIfEnabledByUs() {
|
||||
if (isAdapterEnabled() && wasEnabledByUs) {
|
||||
if (adapter.disable()) LOG.info("Disabling Bluetooth");
|
||||
else LOG.info("Could not disable Bluetooth");
|
||||
wasEnabledByUs = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void setEnabledByUs() {
|
||||
wasEnabledByUs = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
void onAdapterDisabled() {
|
||||
super.onAdapterDisabled();
|
||||
wasEnabledByUs = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
String getBluetoothAddress() {
|
||||
if (adapter == null) return null;
|
||||
String address = AndroidUtils.getBluetoothAddress(app, adapter);
|
||||
return address.isEmpty() ? null : address;
|
||||
}
|
||||
|
||||
@@ -16,42 +16,19 @@ import org.briarproject.bramble.api.system.AndroidWakeLockManager;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.api.system.LocationUtils;
|
||||
import org.briarproject.bramble.api.system.ResourceProvider;
|
||||
import org.briarproject.bramble.util.AndroidUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import javax.net.SocketFactory;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
class AndroidTorPlugin extends TorPlugin {
|
||||
|
||||
private static final List<String> LIBRARY_ARCHITECTURES =
|
||||
asList("armeabi-v7a", "arm64-v8a", "x86", "x86_64");
|
||||
|
||||
private static final String TOR_LIB_NAME = "libtor.so";
|
||||
private static final String OBFS4_LIB_NAME = "libobfs4proxy.so";
|
||||
|
||||
private static final Logger LOG =
|
||||
getLogger(AndroidTorPlugin.class.getName());
|
||||
|
||||
private final Application app;
|
||||
private final AndroidWakeLock wakeLock;
|
||||
private final File torLib, obfs4Lib;
|
||||
|
||||
AndroidTorPlugin(Executor ioExecutor,
|
||||
Executor wakefulIoExecutor,
|
||||
@@ -78,9 +55,6 @@ class AndroidTorPlugin extends TorPlugin {
|
||||
maxIdleTime, torDirectory);
|
||||
this.app = app;
|
||||
wakeLock = wakeLockManager.createWakeLock("TorPlugin");
|
||||
String nativeLibDir = app.getApplicationInfo().nativeLibraryDir;
|
||||
torLib = new File(nativeLibDir, TOR_LIB_NAME);
|
||||
obfs4Lib = new File(nativeLibDir, OBFS4_LIB_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,112 +85,4 @@ class AndroidTorPlugin extends TorPlugin {
|
||||
super.stop();
|
||||
wakeLock.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected File getTorExecutableFile() {
|
||||
return torLib.exists() ? torLib : super.getTorExecutableFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected File getObfs4ExecutableFile() {
|
||||
return obfs4Lib.exists() ? obfs4Lib : super.getObfs4ExecutableFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installTorExecutable() throws IOException {
|
||||
File extracted = super.getTorExecutableFile();
|
||||
if (torLib.exists()) {
|
||||
// If an older version left behind a Tor binary, delete it
|
||||
if (extracted.exists()) {
|
||||
if (extracted.delete()) LOG.info("Deleted Tor binary");
|
||||
else LOG.info("Failed to delete Tor binary");
|
||||
}
|
||||
} else if (SDK_INT < 29) {
|
||||
// The binary wasn't extracted at install time. Try to extract it
|
||||
extractLibraryFromApk(TOR_LIB_NAME, extracted);
|
||||
} else {
|
||||
// No point extracting the binary, we won't be allowed to execute it
|
||||
throw new FileNotFoundException(torLib.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installObfs4Executable() throws IOException {
|
||||
File extracted = super.getObfs4ExecutableFile();
|
||||
if (obfs4Lib.exists()) {
|
||||
// If an older version left behind an obfs4 binary, delete it
|
||||
if (extracted.exists()) {
|
||||
if (extracted.delete()) LOG.info("Deleted obfs4 binary");
|
||||
else LOG.info("Failed to delete obfs4 binary");
|
||||
}
|
||||
} else if (SDK_INT < 29) {
|
||||
// The binary wasn't extracted at install time. Try to extract it
|
||||
extractLibraryFromApk(OBFS4_LIB_NAME, extracted);
|
||||
} else {
|
||||
// No point extracting the binary, we won't be allowed to execute it
|
||||
throw new FileNotFoundException(obfs4Lib.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
private void extractLibraryFromApk(String libName, File dest)
|
||||
throws IOException {
|
||||
File sourceDir = new File(app.getApplicationInfo().sourceDir);
|
||||
if (sourceDir.isFile()) {
|
||||
// Look for other APK files in the same directory, if we're allowed
|
||||
File parent = sourceDir.getParentFile();
|
||||
if (parent != null) sourceDir = parent;
|
||||
}
|
||||
List<String> libPaths = getSupportedLibraryPaths(libName);
|
||||
for (File apk : findApkFiles(sourceDir)) {
|
||||
ZipInputStream zin = new ZipInputStream(new FileInputStream(apk));
|
||||
for (ZipEntry e = zin.getNextEntry(); e != null;
|
||||
e = zin.getNextEntry()) {
|
||||
if (libPaths.contains(e.getName())) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Extracting " + e.getName()
|
||||
+ " from " + apk.getAbsolutePath());
|
||||
}
|
||||
extract(zin, dest); // Zip input stream will be closed
|
||||
return;
|
||||
}
|
||||
}
|
||||
zin.close();
|
||||
}
|
||||
throw new FileNotFoundException(libName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all files with the extension .apk or .APK under the given root.
|
||||
*/
|
||||
private List<File> findApkFiles(File root) {
|
||||
List<File> files = new ArrayList<>();
|
||||
findApkFiles(root, files);
|
||||
return files;
|
||||
}
|
||||
|
||||
private void findApkFiles(File f, List<File> files) {
|
||||
if (f.isFile() && f.getName().toLowerCase().endsWith(".apk")) {
|
||||
files.add(f);
|
||||
} else if (f.isDirectory()) {
|
||||
File[] children = f.listFiles();
|
||||
if (children != null) {
|
||||
for (File child : children) findApkFiles(child, files);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the paths at which libraries with the given name would be found
|
||||
* inside an APK file, for all architectures supported by the device, in
|
||||
* order of preference.
|
||||
*/
|
||||
private List<String> getSupportedLibraryPaths(String libName) {
|
||||
List<String> architectures = new ArrayList<>();
|
||||
for (String abi : AndroidUtils.getSupportedArchitectures()) {
|
||||
if (LIBRARY_ARCHITECTURES.contains(abi)) {
|
||||
architectures.add("lib/" + abi + "/" + libName);
|
||||
}
|
||||
}
|
||||
return architectures;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
/**
|
||||
* Interface for strengthening a password-based key, for example by using a
|
||||
* key stored in a key management service or hardware security module.
|
||||
*
|
||||
* TODO: Remove after a reasonable migration period unless we can work around
|
||||
* Android keymaster bugs. Added 2020-02-24
|
||||
*/
|
||||
@NotNullByDefault
|
||||
public interface KeyStrengthener {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.briarproject.bramble.api.plugin.event;
|
||||
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* An event that informs the Bluetooth plugin that we have enabled the
|
||||
* Bluetooth adapter.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class BluetoothEnabledEvent extends Event {
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.briarproject.bramble.api.plugin.event;
|
||||
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* An event that asks the Bluetooth plugin to disable the Bluetooth adapter if
|
||||
* we previously enabled it.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class DisableBluetoothEvent extends Event {
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.briarproject.bramble.api.plugin.event;
|
||||
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* An event that asks the Bluetooth plugin to enable the Bluetooth adapter.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class EnableBluetoothEvent extends Event {
|
||||
}
|
||||
@@ -179,8 +179,9 @@ class AccountManagerImpl implements AccountManager {
|
||||
@GuardedBy("stateChangeLock")
|
||||
private boolean encryptAndStoreDatabaseKey(SecretKey key, String password) {
|
||||
byte[] plaintext = key.getBytes();
|
||||
byte[] ciphertext = crypto.encryptWithPassword(plaintext, password,
|
||||
databaseConfig.getKeyStrengthener());
|
||||
// Don't use a key strengthener as the Android keymaster isn't reliable
|
||||
byte[] ciphertext =
|
||||
crypto.encryptWithPassword(plaintext, password, null);
|
||||
return storeEncryptedDatabaseKey(toHexString(ciphertext));
|
||||
}
|
||||
|
||||
@@ -197,13 +198,13 @@ class AccountManagerImpl implements AccountManager {
|
||||
@Override
|
||||
public void signIn(String password) throws DecryptionException {
|
||||
synchronized (stateChangeLock) {
|
||||
databaseKey = loadAndDecryptDatabaseKey(password);
|
||||
databaseKey = loadAndDecryptDatabaseKey(password, false);
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("stateChangeLock")
|
||||
private SecretKey loadAndDecryptDatabaseKey(String password)
|
||||
throws DecryptionException {
|
||||
private SecretKey loadAndDecryptDatabaseKey(String password,
|
||||
boolean changing) throws DecryptionException {
|
||||
String hex = loadEncryptedDatabaseKey();
|
||||
if (hex == null) {
|
||||
LOG.warning("Failed to load encrypted database key");
|
||||
@@ -214,11 +215,11 @@ class AccountManagerImpl implements AccountManager {
|
||||
byte[] plaintext = crypto.decryptWithPassword(ciphertext, password,
|
||||
keyStrengthener);
|
||||
SecretKey key = new SecretKey(plaintext);
|
||||
// If the DB key was encrypted with a weak key and a key strengthener
|
||||
// is now available, re-encrypt the DB key with a strengthened key
|
||||
if (keyStrengthener != null &&
|
||||
!crypto.isEncryptedWithStrengthenedKey(ciphertext)) {
|
||||
LOG.info("Re-encrypting database key with strengthened key");
|
||||
// If the DB key was encrypted with a hardware-backed key, re-encrypt
|
||||
// it without the hardware-backed key so keymaster bugs don't delete
|
||||
// the user's account
|
||||
if (!changing && crypto.isEncryptedWithStrengthenedKey(ciphertext)) {
|
||||
LOG.info("Re-encrypting database key without strengthened key");
|
||||
encryptAndStoreDatabaseKey(key, password);
|
||||
}
|
||||
return key;
|
||||
@@ -228,7 +229,7 @@ class AccountManagerImpl implements AccountManager {
|
||||
public void changePassword(String oldPassword, String newPassword)
|
||||
throws DecryptionException {
|
||||
synchronized (stateChangeLock) {
|
||||
SecretKey key = loadAndDecryptDatabaseKey(oldPassword);
|
||||
SecretKey key = loadAndDecryptDatabaseKey(oldPassword, true);
|
||||
encryptAndStoreDatabaseKey(key, newPassword);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.crypto.KeyAgreementCrypto;
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
@@ -9,8 +8,6 @@ import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
|
||||
import org.briarproject.bramble.api.keyagreement.Payload;
|
||||
import org.briarproject.bramble.api.keyagreement.TransportDescriptor;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
||||
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
||||
import org.briarproject.bramble.api.plugin.Plugin;
|
||||
import org.briarproject.bramble.api.plugin.PluginManager;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
@@ -22,9 +19,7 @@ import org.briarproject.bramble.api.record.RecordWriterFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
@@ -33,10 +28,8 @@ import java.util.logging.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.CONNECTION_TIMEOUT;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
|
||||
@@ -48,10 +41,7 @@ class KeyAgreementConnector {
|
||||
}
|
||||
|
||||
private static final Logger LOG =
|
||||
getLogger(KeyAgreementConnector.class.getName());
|
||||
|
||||
private static final List<TransportId> PREFERRED_TRANSPORTS =
|
||||
asList(BluetoothConstants.ID, LanTcpConstants.ID);
|
||||
Logger.getLogger(KeyAgreementConnector.class.getName());
|
||||
|
||||
private final Callbacks callbacks;
|
||||
private final KeyAgreementCrypto keyAgreementCrypto;
|
||||
@@ -115,35 +105,24 @@ class KeyAgreementConnector {
|
||||
this.alice = alice;
|
||||
aliceLatch.countDown();
|
||||
|
||||
// Start connecting over supported transports in order of preference
|
||||
// Start connecting over supported transports
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Starting outgoing BQP connections as "
|
||||
+ (alice ? "Alice" : "Bob"));
|
||||
}
|
||||
Map<TransportId, TransportDescriptor> descriptors = new HashMap<>();
|
||||
for (TransportDescriptor d : remotePayload.getTransportDescriptors()) {
|
||||
descriptors.put(d.getId(), d);
|
||||
}
|
||||
List<Pair<DuplexPlugin, BdfList>> transports = new ArrayList<>();
|
||||
for (TransportId id : PREFERRED_TRANSPORTS) {
|
||||
TransportDescriptor d = descriptors.get(id);
|
||||
Plugin p = pluginManager.getPlugin(id);
|
||||
if (d != null && p instanceof DuplexPlugin) {
|
||||
Plugin p = pluginManager.getPlugin(d.getId());
|
||||
if (p instanceof DuplexPlugin) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Connecting via " + id);
|
||||
transports.add(new Pair<>((DuplexPlugin) p, d.getDescriptor()));
|
||||
LOG.info("Connecting via " + d.getId());
|
||||
DuplexPlugin plugin = (DuplexPlugin) p;
|
||||
byte[] commitment = remotePayload.getCommitment();
|
||||
BdfList descriptor = d.getDescriptor();
|
||||
connectionChooser.submit(new ReadableTask(
|
||||
new ConnectorTask(plugin, commitment, descriptor)));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: If we don't have any transports in common with the peer,
|
||||
// warn the user and give up (#1224)
|
||||
|
||||
if (!transports.isEmpty()) {
|
||||
byte[] commitment = remotePayload.getCommitment();
|
||||
connectionChooser.submit(new ReadableTask(new ConnectorTask(
|
||||
transports, commitment)));
|
||||
}
|
||||
|
||||
// Get chosen connection
|
||||
try {
|
||||
KeyAgreementConnection chosen =
|
||||
@@ -169,13 +148,15 @@ class KeyAgreementConnector {
|
||||
|
||||
private class ConnectorTask implements Callable<KeyAgreementConnection> {
|
||||
|
||||
private final List<Pair<DuplexPlugin, BdfList>> transports;
|
||||
private final byte[] commitment;
|
||||
private final BdfList descriptor;
|
||||
private final DuplexPlugin plugin;
|
||||
|
||||
private ConnectorTask(List<Pair<DuplexPlugin, BdfList>> transports,
|
||||
byte[] commitment) {
|
||||
this.transports = transports;
|
||||
private ConnectorTask(DuplexPlugin plugin, byte[] commitment,
|
||||
BdfList descriptor) {
|
||||
this.plugin = plugin;
|
||||
this.commitment = commitment;
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -183,18 +164,13 @@ class KeyAgreementConnector {
|
||||
public KeyAgreementConnection call() throws Exception {
|
||||
// Repeat attempts until we connect, get stopped, or get interrupted
|
||||
while (!stopped) {
|
||||
for (Pair<DuplexPlugin, BdfList> pair : transports) {
|
||||
if (stopped) return null;
|
||||
DuplexPlugin plugin = pair.getFirst();
|
||||
BdfList descriptor = pair.getSecond();
|
||||
DuplexTransportConnection conn =
|
||||
plugin.createKeyAgreementConnection(commitment,
|
||||
descriptor);
|
||||
if (conn != null) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(plugin.getId() + ": Outgoing connection");
|
||||
return new KeyAgreementConnection(conn, plugin.getId());
|
||||
}
|
||||
DuplexTransportConnection conn =
|
||||
plugin.createKeyAgreementConnection(commitment,
|
||||
descriptor);
|
||||
if (conn != null) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(plugin.getId() + ": Outgoing connection");
|
||||
return new KeyAgreementConnection(conn, plugin.getId());
|
||||
}
|
||||
// Wait 2s before retry (to circumvent transient failures)
|
||||
Thread.sleep(2000);
|
||||
|
||||
@@ -53,7 +53,6 @@ import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.PREF_PLUGIN_ENABLE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
|
||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
@@ -355,10 +354,6 @@ class PluginManagerImpl implements PluginManager, Service {
|
||||
} else if (oldState == ACTIVE) {
|
||||
eventBus.broadcast(new TransportInactiveEvent(id));
|
||||
}
|
||||
} else if (newState == DISABLED) {
|
||||
// Broadcast an event even though the state hasn't changed, as
|
||||
// the reasons for the plugin being disabled may have changed
|
||||
eventBus.broadcast(new TransportStateEvent(id, newState));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ import org.briarproject.bramble.api.plugin.PluginException;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||
import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent;
|
||||
import org.briarproject.bramble.api.plugin.event.DisableBluetoothEvent;
|
||||
import org.briarproject.bramble.api.plugin.event.EnableBluetoothEvent;
|
||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||
import org.briarproject.bramble.api.properties.event.RemoteTransportPropertiesUpdatedEvent;
|
||||
import org.briarproject.bramble.api.rendezvous.KeyMaterialSource;
|
||||
@@ -90,6 +93,12 @@ abstract class BluetoothPlugin<S, SS> implements DuplexPlugin, EventListener {
|
||||
|
||||
abstract boolean isAdapterEnabled();
|
||||
|
||||
abstract void enableAdapter();
|
||||
|
||||
abstract void disableAdapterIfEnabledByUs();
|
||||
|
||||
abstract void setEnabledByUs();
|
||||
|
||||
/**
|
||||
* Returns the local Bluetooth address, or null if no valid address can
|
||||
* be found.
|
||||
@@ -180,7 +189,10 @@ abstract class BluetoothPlugin<S, SS> implements DuplexPlugin, EventListener {
|
||||
throw new PluginException(e);
|
||||
}
|
||||
updateProperties();
|
||||
if (enabledByUser && isAdapterEnabled()) bind();
|
||||
if (enabledByUser) {
|
||||
if (isAdapterEnabled()) bind();
|
||||
else enableAdapter();
|
||||
}
|
||||
}
|
||||
|
||||
private void bind() {
|
||||
@@ -307,6 +319,7 @@ abstract class BluetoothPlugin<S, SS> implements DuplexPlugin, EventListener {
|
||||
public void stop() {
|
||||
SS ss = state.setStopped();
|
||||
tryToClose(ss);
|
||||
disableAdapterIfEnabledByUs();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -436,10 +449,8 @@ abstract class BluetoothPlugin<S, SS> implements DuplexPlugin, EventListener {
|
||||
String uuid = UUID.nameUUIDFromBytes(commitment).toString();
|
||||
DuplexTransportConnection conn;
|
||||
if (descriptor.size() == 1) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Discovering address for key agreement UUID " +
|
||||
uuid);
|
||||
}
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Discovering address for key agreement UUID " + uuid);
|
||||
conn = discoverAndConnect(uuid);
|
||||
} else {
|
||||
String address;
|
||||
@@ -479,7 +490,13 @@ abstract class BluetoothPlugin<S, SS> implements DuplexPlugin, EventListener {
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof SettingsUpdatedEvent) {
|
||||
if (e instanceof EnableBluetoothEvent) {
|
||||
ioExecutor.execute(this::enableAdapter);
|
||||
} else if (e instanceof DisableBluetoothEvent) {
|
||||
ioExecutor.execute(this::disableAdapterIfEnabledByUs);
|
||||
} else if (e instanceof BluetoothEnabledEvent) {
|
||||
setEnabledByUs();
|
||||
} else if (e instanceof SettingsUpdatedEvent) {
|
||||
SettingsUpdatedEvent s = (SettingsUpdatedEvent) e;
|
||||
if (s.getNamespace().equals(ID.getString()))
|
||||
ioExecutor.execute(() -> onSettingsUpdated(s.getSettings()));
|
||||
@@ -505,13 +522,11 @@ abstract class BluetoothPlugin<S, SS> implements DuplexPlugin, EventListener {
|
||||
if (ss != null) {
|
||||
LOG.info("Disabled by user, closing server socket");
|
||||
tryToClose(ss);
|
||||
disableAdapterIfEnabledByUs();
|
||||
} else if (s == INACTIVE) {
|
||||
if (isAdapterEnabled()) {
|
||||
LOG.info("Enabled by user, opening server socket");
|
||||
bind();
|
||||
} else {
|
||||
LOG.info("Enabled by user but adapter is disabled");
|
||||
}
|
||||
LOG.info("Enabled by user, opening server socket");
|
||||
if (isAdapterEnabled()) bind();
|
||||
else enableAdapter();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
private final CircumventionProvider circumventionProvider;
|
||||
private final ResourceProvider resourceProvider;
|
||||
private final int maxLatency, maxIdleTime, socketTimeout;
|
||||
private final File torDirectory, geoIpFile, configFile;
|
||||
private final File torDirectory, torFile, geoIpFile, obfs4File, configFile;
|
||||
private final File doneFile, cookieFile;
|
||||
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||
|
||||
@@ -181,7 +181,9 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
socketTimeout = Integer.MAX_VALUE;
|
||||
else socketTimeout = maxIdleTime * 2;
|
||||
this.torDirectory = torDirectory;
|
||||
torFile = new File(torDirectory, "tor");
|
||||
geoIpFile = new File(torDirectory, "geoip");
|
||||
obfs4File = new File(torDirectory, "obfs4proxy");
|
||||
configFile = new File(torDirectory, "torrc");
|
||||
doneFile = new File(torDirectory, "done");
|
||||
cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
|
||||
@@ -190,14 +192,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
new PoliteExecutor("TorPlugin", ioExecutor, 1);
|
||||
}
|
||||
|
||||
protected File getTorExecutableFile() {
|
||||
return new File(torDirectory, "tor");
|
||||
}
|
||||
|
||||
protected File getObfs4ExecutableFile() {
|
||||
return new File(torDirectory, "obfs4proxy");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportId getId() {
|
||||
return TorConstants.ID;
|
||||
@@ -230,7 +224,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
LOG.warning("Old auth cookie not deleted");
|
||||
// Start a new Tor process
|
||||
LOG.info("Starting Tor");
|
||||
File torFile = getTorExecutableFile();
|
||||
String torPath = torFile.getAbsolutePath();
|
||||
String configPath = configFile.getAbsolutePath();
|
||||
String pid = String.valueOf(getProcessId());
|
||||
@@ -329,43 +322,44 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
}
|
||||
|
||||
private void installAssets() throws PluginException {
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
// The done file may already exist from a previous installation
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
doneFile.delete();
|
||||
installTorExecutable();
|
||||
installObfs4Executable();
|
||||
extract(getGeoIpInputStream(), geoIpFile);
|
||||
extract(getConfigInputStream(), configFile);
|
||||
// Unzip the Tor binary to the filesystem
|
||||
in = getTorInputStream();
|
||||
out = new FileOutputStream(torFile);
|
||||
copyAndClose(in, out);
|
||||
// Make the Tor binary executable
|
||||
if (!torFile.setExecutable(true, true)) throw new IOException();
|
||||
// Unzip the GeoIP database to the filesystem
|
||||
in = getGeoIpInputStream();
|
||||
out = new FileOutputStream(geoIpFile);
|
||||
copyAndClose(in, out);
|
||||
// Unzip the Obfs4 proxy to the filesystem
|
||||
in = getObfs4InputStream();
|
||||
out = new FileOutputStream(obfs4File);
|
||||
copyAndClose(in, out);
|
||||
// Make the Obfs4 proxy executable
|
||||
if (!obfs4File.setExecutable(true, true)) throw new IOException();
|
||||
// Copy the config file to the filesystem
|
||||
in = getConfigInputStream();
|
||||
out = new FileOutputStream(configFile);
|
||||
copyAndClose(in, out);
|
||||
if (!doneFile.createNewFile())
|
||||
LOG.warning("Failed to create done file");
|
||||
} catch (IOException e) {
|
||||
tryToClose(in, LOG, WARNING);
|
||||
tryToClose(out, LOG, WARNING);
|
||||
throw new PluginException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void extract(InputStream in, File dest) throws IOException {
|
||||
OutputStream out = new FileOutputStream(dest);
|
||||
copyAndClose(in, out);
|
||||
}
|
||||
|
||||
protected void installTorExecutable() throws IOException {
|
||||
private InputStream getTorInputStream() throws IOException {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Installing Tor binary for " + architecture);
|
||||
File torFile = getTorExecutableFile();
|
||||
extract(getTorInputStream(), torFile);
|
||||
if (!torFile.setExecutable(true, true)) throw new IOException();
|
||||
}
|
||||
|
||||
protected void installObfs4Executable() throws IOException {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Installing obfs4proxy binary for " + architecture);
|
||||
File obfs4File = getObfs4ExecutableFile();
|
||||
extract(getObfs4InputStream(), obfs4File);
|
||||
if (!obfs4File.setExecutable(true, true)) throw new IOException();
|
||||
}
|
||||
|
||||
private InputStream getTorInputStream() throws IOException {
|
||||
InputStream in = resourceProvider
|
||||
.getResourceInputStream("tor_" + architecture, ".zip");
|
||||
ZipInputStream zin = new ZipInputStream(in);
|
||||
@@ -382,6 +376,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
}
|
||||
|
||||
private InputStream getObfs4InputStream() throws IOException {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Installing obfs4proxy binary for " + architecture);
|
||||
InputStream in = resourceProvider
|
||||
.getResourceInputStream("obfs4proxy_" + architecture, ".zip");
|
||||
ZipInputStream zin = new ZipInputStream(in);
|
||||
@@ -573,7 +569,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
if (enable) {
|
||||
Collection<String> conf = new ArrayList<>();
|
||||
conf.add("UseBridges 1");
|
||||
File obfs4File = getObfs4ExecutableFile();
|
||||
if (needsMeek) {
|
||||
conf.add("ClientTransportPlugin meek_lite exec " +
|
||||
obfs4File.getAbsolutePath());
|
||||
|
||||
@@ -42,7 +42,6 @@ import org.briarproject.bramble.api.rendezvous.event.RendezvousConnectionOpenedE
|
||||
import org.briarproject.bramble.api.rendezvous.event.RendezvousPollEvent;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.api.system.TaskScheduler;
|
||||
import org.briarproject.bramble.api.system.TaskScheduler.Cancellable;
|
||||
import org.briarproject.bramble.api.system.Wakeful;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
@@ -69,7 +68,6 @@ import static org.briarproject.bramble.api.contact.PendingContactState.ADDING_CO
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.FAILED;
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.OFFLINE;
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNull;
|
||||
import static org.briarproject.bramble.rendezvous.RendezvousConstants.POLLING_INTERVAL_MS;
|
||||
import static org.briarproject.bramble.rendezvous.RendezvousConstants.RENDEZVOUS_TIMEOUT_MS;
|
||||
@@ -104,8 +102,6 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
||||
new HashMap<>();
|
||||
@Nullable
|
||||
private KeyPair handshakeKeyPair = null;
|
||||
@Nullable
|
||||
private Cancellable pollTask = null;
|
||||
|
||||
@Inject
|
||||
RendezvousPollerImpl(@IoExecutor Executor ioExecutor,
|
||||
@@ -148,6 +144,8 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
||||
} catch (DbException e) {
|
||||
throw new ServiceException(e);
|
||||
}
|
||||
scheduler.scheduleWithFixedDelay(this::poll, worker,
|
||||
POLLING_INTERVAL_MS, POLLING_INTERVAL_MS, MILLISECONDS);
|
||||
}
|
||||
|
||||
@EventExecutor
|
||||
@@ -188,12 +186,6 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
||||
}
|
||||
if (cs.numEndpoints == 0) broadcastState(p.getId(), OFFLINE);
|
||||
else broadcastState(p.getId(), WAITING_FOR_CONNECTION);
|
||||
if (cryptoStates.size() == 1) {
|
||||
LOG.info("Starting poller");
|
||||
requireNull(pollTask);
|
||||
pollTask = scheduler.scheduleWithFixedDelay(this::poll, worker,
|
||||
POLLING_INTERVAL_MS, POLLING_INTERVAL_MS, MILLISECONDS);
|
||||
}
|
||||
} catch (DbException | GeneralSecurityException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
@@ -216,7 +208,6 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
||||
// Worker
|
||||
@Wakeful
|
||||
private void poll() {
|
||||
LOG.info("Polling");
|
||||
removeExpiredPendingContacts();
|
||||
for (PluginState ps : pluginStates.values()) poll(ps);
|
||||
}
|
||||
@@ -243,11 +234,6 @@ class RendezvousPollerImpl implements RendezvousPoller, Service, EventListener {
|
||||
RendezvousEndpoint endpoint = ps.endpoints.remove(p);
|
||||
if (endpoint != null) tryToClose(endpoint, LOG, INFO);
|
||||
}
|
||||
if (cryptoStates.isEmpty()) {
|
||||
LOG.info("Stopping poller");
|
||||
requireNonNull(pollTask).cancel();
|
||||
pollTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Worker
|
||||
|
||||
@@ -134,7 +134,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
||||
keyStrengthener);
|
||||
will(returnValue(key.getBytes()));
|
||||
oneOf(crypto).isEncryptedWithStrengthenedKey(encryptedKey);
|
||||
will(returnValue(true));
|
||||
will(returnValue(false));
|
||||
}});
|
||||
|
||||
storeDatabaseKey(keyFile, encryptedKeyHex);
|
||||
@@ -160,9 +160,8 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
||||
keyStrengthener);
|
||||
will(returnValue(key.getBytes()));
|
||||
oneOf(crypto).isEncryptedWithStrengthenedKey(encryptedKey);
|
||||
will(returnValue(false));
|
||||
oneOf(crypto).encryptWithPassword(key.getBytes(), password,
|
||||
keyStrengthener);
|
||||
will(returnValue(true));
|
||||
oneOf(crypto).encryptWithPassword(key.getBytes(), password, null);
|
||||
will(returnValue(newEncryptedKey));
|
||||
}});
|
||||
|
||||
@@ -262,8 +261,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(identityManager).registerIdentity(identity);
|
||||
oneOf(crypto).generateSecretKey();
|
||||
will(returnValue(key));
|
||||
oneOf(crypto).encryptWithPassword(key.getBytes(), password,
|
||||
keyStrengthener);
|
||||
oneOf(crypto).encryptWithPassword(key.getBytes(), password, null);
|
||||
will(returnValue(encryptedKey));
|
||||
}});
|
||||
|
||||
@@ -323,10 +321,8 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(crypto).decryptWithPassword(encryptedKey, password,
|
||||
keyStrengthener);
|
||||
will(returnValue(key.getBytes()));
|
||||
oneOf(crypto).isEncryptedWithStrengthenedKey(encryptedKey);
|
||||
will(returnValue(true));
|
||||
oneOf(crypto).encryptWithPassword(key.getBytes(), newPassword,
|
||||
keyStrengthener);
|
||||
null);
|
||||
will(returnValue(newEncryptedKey));
|
||||
}});
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.briarproject.bramble.api.rendezvous.event.RendezvousConnectionOpenedE
|
||||
import org.briarproject.bramble.api.rendezvous.event.RendezvousPollEvent;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.api.system.TaskScheduler;
|
||||
import org.briarproject.bramble.api.system.TaskScheduler.Cancellable;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.CaptureArgumentAction;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
@@ -80,7 +79,6 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
context.mock(KeyMaterialSource.class);
|
||||
private final RendezvousEndpoint rendezvousEndpoint =
|
||||
context.mock(RendezvousEndpoint.class);
|
||||
private final Cancellable cancellable = context.mock(Cancellable.class);
|
||||
|
||||
private final Executor ioExecutor = new ImmediateExecutor();
|
||||
private final PendingContact pendingContact = getPendingContact();
|
||||
@@ -109,7 +107,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
long beforeExpiry = pendingContact.getTimestamp()
|
||||
+ RENDEZVOUS_TIMEOUT_MS - 1000;
|
||||
long afterExpiry = beforeExpiry + POLLING_INTERVAL_MS;
|
||||
AtomicReference<Runnable> capturePollTask;
|
||||
AtomicReference<Runnable> capturePollTask = new AtomicReference<>();
|
||||
|
||||
// Start the service
|
||||
context.checking(new DbExpectations() {{
|
||||
@@ -123,17 +121,21 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
|
||||
PendingContactStateChangedEvent.class, e ->
|
||||
e.getPendingContactState() == OFFLINE)));
|
||||
// Capture the poll task
|
||||
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
||||
with(any(Executor.class)), with(POLLING_INTERVAL_MS),
|
||||
with(POLLING_INTERVAL_MS), with(MILLISECONDS));
|
||||
will(new CaptureArgumentAction<>(capturePollTask, Runnable.class,
|
||||
0));
|
||||
}});
|
||||
|
||||
expectDeriveRendezvousKey();
|
||||
capturePollTask = expectSchedulePolling();
|
||||
|
||||
rendezvousPoller.startService();
|
||||
context.assertIsSatisfied();
|
||||
|
||||
// Run the poll task - pending contact expires, polling is cancelled
|
||||
// Run the poll task - pending contact expires
|
||||
expectPendingContactExpires(afterExpiry);
|
||||
expectCancelPolling();
|
||||
|
||||
capturePollTask.get().run();
|
||||
}
|
||||
@@ -155,6 +157,10 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
|
||||
PendingContactStateChangedEvent.class, e ->
|
||||
e.getPendingContactState() == FAILED)));
|
||||
// Schedule the poll task
|
||||
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
||||
with(any(Executor.class)), with(POLLING_INTERVAL_MS),
|
||||
with(POLLING_INTERVAL_MS), with(MILLISECONDS));
|
||||
}});
|
||||
|
||||
rendezvousPoller.startService();
|
||||
@@ -177,8 +183,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
rendezvousPoller.eventOccurred(new TransportActiveEvent(transportId));
|
||||
context.assertIsSatisfied();
|
||||
|
||||
// Add the pending contact - endpoint should be created and polled,
|
||||
// polling should be scheduled
|
||||
// Add the pending contact - endpoint should be created and polled
|
||||
expectAddPendingContact(beforeExpiry, WAITING_FOR_CONNECTION);
|
||||
expectDeriveRendezvousKey();
|
||||
expectCreateEndpoint();
|
||||
@@ -195,16 +200,12 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
any(ConnectionHandler.class)))));
|
||||
}});
|
||||
|
||||
expectSchedulePolling();
|
||||
|
||||
rendezvousPoller.eventOccurred(
|
||||
new PendingContactAddedEvent(pendingContact));
|
||||
context.assertIsSatisfied();
|
||||
|
||||
// Remove the pending contact - endpoint should be closed,
|
||||
// polling should be cancelled
|
||||
// Remove the pending contact - endpoint should be closed
|
||||
expectCloseEndpoint();
|
||||
expectCancelPolling();
|
||||
|
||||
rendezvousPoller.eventOccurred(
|
||||
new PendingContactRemovedEvent(pendingContact.getId()));
|
||||
@@ -220,10 +221,10 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
long beforeExpiry = pendingContact.getTimestamp()
|
||||
+ RENDEZVOUS_TIMEOUT_MS - 1000;
|
||||
long afterExpiry = beforeExpiry + POLLING_INTERVAL_MS;
|
||||
AtomicReference<Runnable> capturePollTask;
|
||||
|
||||
// Start the service
|
||||
expectStartupWithNoPendingContacts();
|
||||
// Start the service, capturing the poll task
|
||||
AtomicReference<Runnable> capturePollTask =
|
||||
expectStartupWithNoPendingContacts();
|
||||
|
||||
rendezvousPoller.startService();
|
||||
context.assertIsSatisfied();
|
||||
@@ -234,8 +235,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
rendezvousPoller.eventOccurred(new TransportActiveEvent(transportId));
|
||||
context.assertIsSatisfied();
|
||||
|
||||
// Add the pending contact - endpoint should be created and polled,
|
||||
// polling should be scheduled
|
||||
// Add the pending contact - endpoint should be created and polled
|
||||
expectAddPendingContact(beforeExpiry, WAITING_FOR_CONNECTION);
|
||||
expectDeriveRendezvousKey();
|
||||
expectCreateEndpoint();
|
||||
@@ -252,17 +252,13 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
any(ConnectionHandler.class)))));
|
||||
}});
|
||||
|
||||
capturePollTask = expectSchedulePolling();
|
||||
|
||||
rendezvousPoller.eventOccurred(
|
||||
new PendingContactAddedEvent(pendingContact));
|
||||
context.assertIsSatisfied();
|
||||
|
||||
// Run the poll task - pending contact expires, endpoint is closed,
|
||||
// polling is cancelled
|
||||
// Run the poll task - pending contact expires, endpoint is closed
|
||||
expectPendingContactExpires(afterExpiry);
|
||||
expectCloseEndpoint();
|
||||
expectCancelPolling();
|
||||
|
||||
capturePollTask.get().run();
|
||||
context.assertIsSatisfied();
|
||||
@@ -290,7 +286,6 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
// Add the pending contact - no endpoints should be created yet
|
||||
expectAddPendingContact(beforeExpiry, OFFLINE);
|
||||
expectDeriveRendezvousKey();
|
||||
expectSchedulePolling();
|
||||
|
||||
rendezvousPoller.eventOccurred(
|
||||
new PendingContactAddedEvent(pendingContact));
|
||||
@@ -312,8 +307,6 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
context.assertIsSatisfied();
|
||||
|
||||
// Remove the pending contact - endpoint is already closed
|
||||
expectCancelPolling();
|
||||
|
||||
rendezvousPoller.eventOccurred(
|
||||
new PendingContactRemovedEvent(pendingContact.getId()));
|
||||
}
|
||||
@@ -355,9 +348,8 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
rendezvousPoller.startService();
|
||||
context.assertIsSatisfied();
|
||||
|
||||
// Run the poll task - pending contact expires, polling is cancelled
|
||||
// Run the poll task - pending contact expires
|
||||
expectPendingContactExpires(afterExpiry);
|
||||
expectCancelPolling();
|
||||
|
||||
capturePollTask.get().run();
|
||||
context.assertIsSatisfied();
|
||||
@@ -393,9 +385,8 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
new RendezvousConnectionOpenedEvent(pendingContact.getId()));
|
||||
context.assertIsSatisfied();
|
||||
|
||||
// Run the poll task - pending contact expires, polling is cancelled
|
||||
// Run the poll task - pending contact expires
|
||||
expectPendingContactExpires(afterExpiry);
|
||||
expectCancelPolling();
|
||||
|
||||
capturePollTask.get().run();
|
||||
context.assertIsSatisfied();
|
||||
@@ -426,9 +417,8 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
new RendezvousConnectionOpenedEvent(pendingContact.getId()));
|
||||
context.assertIsSatisfied();
|
||||
|
||||
// Run the poll task - pending contact expires, polling is cancelled
|
||||
// Run the poll task - pending contact expires
|
||||
expectPendingContactExpires(afterExpiry);
|
||||
expectCancelPolling();
|
||||
|
||||
capturePollTask.get().run();
|
||||
context.assertIsSatisfied();
|
||||
@@ -457,8 +447,6 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
context.assertIsSatisfied();
|
||||
|
||||
// Pending contact is removed - no event should be broadcast
|
||||
expectCancelPolling();
|
||||
|
||||
rendezvousPoller.eventOccurred(
|
||||
new PendingContactRemovedEvent(pendingContact.getId()));
|
||||
context.assertIsSatisfied();
|
||||
@@ -468,35 +456,25 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
pendingContact.getId(), false));
|
||||
}
|
||||
|
||||
private AtomicReference<Runnable> expectSchedulePolling() {
|
||||
AtomicReference<Runnable> capturePollTask = new AtomicReference<>();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
||||
with(any(Executor.class)), with(POLLING_INTERVAL_MS),
|
||||
with(POLLING_INTERVAL_MS), with(MILLISECONDS));
|
||||
will(doAll(new CaptureArgumentAction<>(capturePollTask,
|
||||
Runnable.class, 0), returnValue(cancellable)));
|
||||
}});
|
||||
|
||||
return capturePollTask;
|
||||
}
|
||||
|
||||
private void expectCancelPolling() {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(cancellable).cancel();
|
||||
}});
|
||||
}
|
||||
|
||||
private void expectStartupWithNoPendingContacts() throws Exception {
|
||||
private AtomicReference<Runnable> expectStartupWithNoPendingContacts()
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
AtomicReference<Runnable> capturePollTask = new AtomicReference<>();
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
// Load the pending contacts
|
||||
oneOf(db).transaction(with(true), withDbRunnable(txn));
|
||||
oneOf(db).getPendingContacts(txn);
|
||||
will(returnValue(emptyList()));
|
||||
// Capture the poll task
|
||||
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
||||
with(any(Executor.class)), with(POLLING_INTERVAL_MS),
|
||||
with(POLLING_INTERVAL_MS), with(MILLISECONDS));
|
||||
will(new CaptureArgumentAction<>(capturePollTask, Runnable.class,
|
||||
0));
|
||||
}});
|
||||
|
||||
return capturePollTask;
|
||||
}
|
||||
|
||||
private void expectAddPendingContact(long now,
|
||||
@@ -552,6 +530,7 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
private AtomicReference<Runnable> expectStartupWithPendingContact(long now)
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
AtomicReference<Runnable> capturePollTask = new AtomicReference<>();
|
||||
|
||||
context.checking(new DbExpectations() {{
|
||||
// Load the pending contacts
|
||||
@@ -564,10 +543,17 @@ public class RendezvousPollerImplTest extends BrambleMockTestCase {
|
||||
oneOf(eventBus).broadcast(with(new PredicateMatcher<>(
|
||||
PendingContactStateChangedEvent.class, e ->
|
||||
e.getPendingContactState() == OFFLINE)));
|
||||
// Capture the poll task
|
||||
oneOf(scheduler).scheduleWithFixedDelay(with(any(Runnable.class)),
|
||||
with(any(Executor.class)), with(POLLING_INTERVAL_MS),
|
||||
with(POLLING_INTERVAL_MS), with(MILLISECONDS));
|
||||
will(new CaptureArgumentAction<>(capturePollTask, Runnable.class,
|
||||
0));
|
||||
}});
|
||||
|
||||
expectDeriveRendezvousKey();
|
||||
return expectSchedulePolling();
|
||||
|
||||
return capturePollTask;
|
||||
}
|
||||
|
||||
private void expectPendingContactExpires(long now) {
|
||||
|
||||
@@ -62,6 +62,22 @@ class JavaBluetoothPlugin
|
||||
return localDevice != null && LocalDevice.isPowerOn();
|
||||
}
|
||||
|
||||
@Override
|
||||
void enableAdapter() {
|
||||
// Nothing we can do on this platform
|
||||
LOG.info("Could not enable Bluetooth");
|
||||
}
|
||||
|
||||
@Override
|
||||
void disableAdapterIfEnabledByUs() {
|
||||
// We didn't enable it so we don't need to disable it
|
||||
}
|
||||
|
||||
@Override
|
||||
void setEnabledByUs() {
|
||||
// Irrelevant on this platform
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
String getBluetoothAddress() {
|
||||
|
||||
@@ -16,14 +16,14 @@ def getStdout = { command, defaultValue ->
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.2'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode rootProject.ext.versionCode
|
||||
versionName rootProject.ext.versionName
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 28
|
||||
versionCode 10209
|
||||
versionName "1.2.9"
|
||||
applicationId "org.briarproject.briar.android"
|
||||
buildConfigField "String", "GitHash",
|
||||
"\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\""
|
||||
|
||||
@@ -13,9 +13,8 @@ import java.util.Random;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import static androidx.test.InstrumentationRegistry.getContext;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.AVAILABLE;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.ERROR;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@@ -28,7 +27,7 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
|
||||
private final ImageHelper imageHelper = new ImageHelperImpl();
|
||||
private final AttachmentRetriever retriever =
|
||||
new AttachmentRetrieverImpl(null, null, dimensions, imageHelper,
|
||||
new AttachmentRetrieverImpl(null, dimensions, imageHelper,
|
||||
new ImageSizeCalculator(imageHelper));
|
||||
|
||||
@Test
|
||||
@@ -36,7 +35,7 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getAssetInputStream("kitten_small.jpg");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(msgId, item.getMessageId());
|
||||
assertEquals(160, item.getWidth());
|
||||
assertEquals(240, item.getHeight());
|
||||
@@ -44,7 +43,7 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
assertEquals(240, item.getThumbnailHeight());
|
||||
assertEquals("image/jpeg", item.getMimeType());
|
||||
assertJpgOrJpeg(item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -52,7 +51,7 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getAssetInputStream("kitten_original.jpg");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(msgId, item.getMessageId());
|
||||
assertEquals(1728, item.getWidth());
|
||||
assertEquals(2592, item.getHeight());
|
||||
@@ -60,7 +59,7 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
assertEquals(dimensions.maxHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/jpeg", item.getMimeType());
|
||||
assertJpgOrJpeg(item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -68,7 +67,7 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/png");
|
||||
InputStream is = getAssetInputStream("kitten.png");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(msgId, item.getMessageId());
|
||||
assertEquals(737, item.getWidth());
|
||||
assertEquals(510, item.getHeight());
|
||||
@@ -76,7 +75,7 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
assertEquals(138, item.getThumbnailHeight());
|
||||
assertEquals("image/png", item.getMimeType());
|
||||
assertEquals("png", item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -84,14 +83,14 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||
InputStream is = getAssetInputStream("uber.gif");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(1, item.getWidth());
|
||||
assertEquals(1, item.getHeight());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -99,14 +98,14 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getAssetInputStream("lottapixel.jpg");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(64250, item.getWidth());
|
||||
assertEquals(64250, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailHeight());
|
||||
assertEquals("image/jpeg", item.getMimeType());
|
||||
assertJpgOrJpeg(item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -114,14 +113,14 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/png");
|
||||
InputStream is = getAssetInputStream("image_io_crash.png");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(1184, item.getWidth());
|
||||
assertEquals(448, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/png", item.getMimeType());
|
||||
assertEquals("png", item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -129,14 +128,14 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||
InputStream is = getAssetInputStream("gimp_crash.gif");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(1, item.getWidth());
|
||||
assertEquals(1, item.getHeight());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -144,14 +143,14 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||
InputStream is = getAssetInputStream("opti_png_afl.gif");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(32, item.getWidth());
|
||||
assertEquals(32, item.getHeight());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -159,8 +158,8 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getAssetInputStream("libraw_error.jpg");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
assertEquals(ERROR, item.getState());
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertTrue(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -168,14 +167,14 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||
InputStream is = getAssetInputStream("animated.gif");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(65535, item.getWidth());
|
||||
assertEquals(65535, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -183,14 +182,14 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||
InputStream is = getAssetInputStream("animated2.gif");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(10000, item.getWidth());
|
||||
assertEquals(10000, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -198,14 +197,14 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||
InputStream is = getAssetInputStream("error_large.gif");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(16384, item.getWidth());
|
||||
assertEquals(16384, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -213,14 +212,14 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getAssetInputStream("error_high.jpg");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(1, item.getWidth());
|
||||
assertEquals(10000, item.getHeight());
|
||||
assertEquals(dimensions.minWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/jpeg", item.getMimeType());
|
||||
assertJpgOrJpeg(item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -228,14 +227,14 @@ public class AttachmentRetrieverIntegrationTest {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getAssetInputStream("error_wide.jpg");
|
||||
Attachment a = new Attachment(h, is);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||
assertEquals(1920, item.getWidth());
|
||||
assertEquals(1, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/jpeg", item.getMimeType());
|
||||
assertJpgOrJpeg(item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
private InputStream getAssetInputStream(String name) throws Exception {
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="org.briarproject.briar">
|
||||
<manifest
|
||||
package="org.briarproject.briar"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.bluetooth"
|
||||
android:required="false" />
|
||||
android:required="false"/>
|
||||
<uses-feature
|
||||
android:name="android.hardware.camera"
|
||||
android:required="false" />
|
||||
android:required="false"/>
|
||||
<uses-feature
|
||||
android:name="android.hardware.touchscreen"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.software.leanback"
|
||||
android:required="false" />
|
||||
android:required="false"/>
|
||||
<uses-feature android:name="android.software.leanback"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
<!--suppress DeprecatedClassUsageInspection -->
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
<uses-permission-sdk-23 android:name="android.permission.USE_BIOMETRIC" />
|
||||
<uses-permission-sdk-23 android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||
<uses-permission-sdk-23 android:name="android.permission.USE_BIOMETRIC"/>
|
||||
<uses-permission-sdk-23 android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
|
||||
<application
|
||||
android:name="org.briarproject.briar.android.BriarApplicationImpl"
|
||||
android:allowBackup="false"
|
||||
android:banner="@mipmap/tv_banner"
|
||||
android:icon="@mipmap/ic_launcher_round"
|
||||
android:label="@string/app_name"
|
||||
android:logo="@mipmap/ic_launcher_round"
|
||||
android:banner="@mipmap/tv_banner"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/BriarTheme"
|
||||
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute"
|
||||
@@ -50,8 +50,8 @@
|
||||
android:name="org.briarproject.briar.android.login.SignInReminderReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
@@ -59,13 +59,14 @@
|
||||
android:name="org.briarproject.briar.android.BriarService"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="org.briarproject.briar.android.BriarService" />
|
||||
<action android:name="org.briarproject.briar.android.BriarService"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name="org.briarproject.briar.android.NotificationCleanupService"
|
||||
android:exported="false"></service>
|
||||
android:exported="false">
|
||||
</service>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.reporting.DevReportActivity"
|
||||
@@ -75,29 +76,32 @@
|
||||
android:label="@string/crash_report_title"
|
||||
android:launchMode="singleInstance"
|
||||
android:theme="@style/BriarTheme.NoActionBar"
|
||||
android:windowSoftInputMode="adjustResize|stateHidden"></activity>
|
||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.splash.ExpiredActivity"
|
||||
android:label="@string/app_name"></activity>
|
||||
android:label="@string/app_name">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.login.StartupActivity"
|
||||
android:label="@string/app_name"></activity>
|
||||
android:label="@string/app_name">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.account.SetupActivity"
|
||||
android:label="@string/setup_title"
|
||||
android:windowSoftInputMode="adjustResize|stateAlwaysVisible"></activity>
|
||||
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.splash.SplashScreenActivity"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/BriarTheme.NoActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
@@ -107,17 +111,17 @@
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/BriarTheme.NoActionBar">
|
||||
<intent-filter android:label="@string/add_contact_remotely_title_case">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data android:scheme="briar" />
|
||||
<data android:scheme="briar"/>
|
||||
</intent-filter>
|
||||
<intent-filter android:label="@string/add_contact_remotely_title_case">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="text/plain" />
|
||||
<action android:name="android.intent.action.SEND"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data android:mimeType="text/plain"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
@@ -129,7 +133,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateUnchanged">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -138,7 +142,7 @@
|
||||
android:theme="@style/BriarTheme.ActionBarOverlay">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.conversation.ConversationActivity" />
|
||||
android:value="org.briarproject.briar.android.conversation.ConversationActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -148,7 +152,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -159,7 +163,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -168,7 +172,7 @@
|
||||
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -177,7 +181,7 @@
|
||||
android:parentActivityName="org.briarproject.briar.android.privategroup.conversation.GroupActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.privategroup.conversation.GroupActivity" />
|
||||
android:value="org.briarproject.briar.android.privategroup.conversation.GroupActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -186,7 +190,7 @@
|
||||
android:parentActivityName="org.briarproject.briar.android.privategroup.conversation.GroupActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.privategroup.conversation.GroupActivity" />
|
||||
android:value="org.briarproject.briar.android.privategroup.conversation.GroupActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -196,7 +200,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.privategroup.conversation.GroupActivity" />
|
||||
android:value="org.briarproject.briar.android.privategroup.conversation.GroupActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -205,7 +209,7 @@
|
||||
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -214,7 +218,7 @@
|
||||
android:parentActivityName="org.briarproject.briar.android.conversation.ConversationActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.conversation.ConversationActivity" />
|
||||
android:value="org.briarproject.briar.android.conversation.ConversationActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -224,7 +228,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -235,7 +239,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -245,7 +249,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.forum.ForumActivity" />
|
||||
android:value="org.briarproject.briar.android.forum.ForumActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -255,7 +259,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.blog.BlogActivity" />
|
||||
android:value="org.briarproject.briar.android.blog.BlogActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -264,7 +268,8 @@
|
||||
android:parentActivityName="org.briarproject.briar.android.forum.ForumActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.forum.ForumActivity" />
|
||||
android:value="org.briarproject.briar.android.forum.ForumActivity"
|
||||
/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -273,7 +278,7 @@
|
||||
android:parentActivityName="org.briarproject.briar.android.blog.BlogActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.blog.BlogActivity" />
|
||||
android:value="org.briarproject.briar.android.blog.BlogActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -282,7 +287,7 @@
|
||||
android:theme="@style/BriarTheme.NoActionBar">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -292,7 +297,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.blog.BlogActivity" />
|
||||
android:value="org.briarproject.briar.android.blog.BlogActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -302,7 +307,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.blog.BlogActivity" />
|
||||
android:value="org.briarproject.briar.android.blog.BlogActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -312,7 +317,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -321,7 +326,7 @@
|
||||
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -331,7 +336,7 @@
|
||||
android:theme="@style/BriarTheme.NoActionBar">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -341,12 +346,13 @@
|
||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.conversation.ConversationActivity" />
|
||||
android:value="org.briarproject.briar.android.conversation.ConversationActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.StartupFailureActivity"
|
||||
android:label="@string/startup_failed_activity_title"></activity>
|
||||
android:label="@string/startup_failed_activity_title">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.settings.SettingsActivity"
|
||||
@@ -355,22 +361,13 @@
|
||||
android:permission="android.permission.READ_NETWORK_USAGE_HISTORY">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<action android:name="android.intent.action.MANAGE_NETWORK_USAGE"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.navdrawer.TransportsActivity"
|
||||
android:label="@string/network_settings_title"
|
||||
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.login.ChangePasswordActivity"
|
||||
android:label="@string/change_password"
|
||||
@@ -378,7 +375,7 @@
|
||||
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.settings.SettingsActivity" />
|
||||
android:value="org.briarproject.briar.android.settings.SettingsActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -387,7 +384,7 @@
|
||||
android:parentActivityName="org.briarproject.briar.android.settings.SettingsActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.settings.SettingsActivity" />
|
||||
android:value="org.briarproject.briar.android.settings.SettingsActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -396,7 +393,7 @@
|
||||
android:parentActivityName="org.briarproject.briar.android.settings.SettingsActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.settings.SettingsActivity" />
|
||||
android:value="org.briarproject.briar.android.settings.SettingsActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -405,35 +402,37 @@
|
||||
android:theme="@style/TranslucentTheme">
|
||||
<!-- this can never have launchMode singleTask or singleInstance! -->
|
||||
<intent-filter>
|
||||
<action android:name="info.guardianproject.panic.action.TRIGGER" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<action android:name="info.guardianproject.panic.action.TRIGGER"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.logout.ExitActivity"
|
||||
android:theme="@android:style/Theme.NoDisplay"></activity>
|
||||
android:theme="@android:style/Theme.NoDisplay">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.logout.HideUiActivity"
|
||||
android:theme="@android:style/Theme.NoDisplay"></activity>
|
||||
android:theme="@android:style/Theme.NoDisplay">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.account.UnlockActivity"
|
||||
android:label="@string/lock_unlock"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/BriarTheme.NoActionBar" />
|
||||
android:theme="@style/BriarTheme.NoActionBar"/>
|
||||
|
||||
<activity
|
||||
android:name=".android.contact.add.remote.AddContactActivity"
|
||||
android:label="@string/add_contact_remotely_title_case"
|
||||
android:theme="@style/BriarTheme"
|
||||
android:windowSoftInputMode="adjustResize|stateHidden" />
|
||||
android:windowSoftInputMode="adjustResize|stateHidden"/>
|
||||
|
||||
<activity
|
||||
android:name=".android.contact.add.remote.PendingContactListActivity"
|
||||
android:label="@string/pending_contact_requests"
|
||||
android:theme="@style/BriarTheme" />
|
||||
android:theme="@style/BriarTheme"/>
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package org.briarproject.briar.android.account;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
|
||||
import static android.os.Environment.DIRECTORY_DOWNLOADS;
|
||||
import static android.os.Environment.getExternalStoragePublicDirectory;
|
||||
import static android.widget.Toast.LENGTH_LONG;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.briar.android.BriarApplication.ENTRY_ACTIVITY;
|
||||
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.SIGN_OUT_URI;
|
||||
|
||||
public class AccountUtils {
|
||||
|
||||
private static final Logger LOG = getLogger(AccountUtils.class.getName());
|
||||
|
||||
private static final String[] BACKUP_DIRS =
|
||||
{"app_db", "app_key", "shared_prefs"};
|
||||
|
||||
public static void exportAccount(Context ctx) {
|
||||
try {
|
||||
File dataDir = getDataDir(ctx);
|
||||
File backupDir = getBackupDir(ctx);
|
||||
for (String name : BACKUP_DIRS) {
|
||||
copyRecursively(new File(dataDir, name),
|
||||
new File(backupDir, name));
|
||||
}
|
||||
Toast.makeText(ctx, "Account exported to "
|
||||
+ backupDir.getCanonicalPath(), LENGTH_LONG).show();
|
||||
} catch (IOException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
Toast.makeText(ctx, "Export failed", LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
public static void importAccount(Context ctx) {
|
||||
try {
|
||||
File dataDir = getDataDir(ctx);
|
||||
File backupDir = getBackupDir(ctx);
|
||||
for (String name : BACKUP_DIRS) {
|
||||
copyRecursively(new File(backupDir, name),
|
||||
new File(dataDir, name));
|
||||
}
|
||||
Toast.makeText(ctx, "Account imported from "
|
||||
+ backupDir.getCanonicalPath(), LENGTH_LONG).show();
|
||||
Intent intent = new Intent(ctx, ENTRY_ACTIVITY);
|
||||
intent.setFlags(FLAG_ACTIVITY_CLEAR_TOP);
|
||||
intent.setData(SIGN_OUT_URI);
|
||||
ctx.startActivity(intent);
|
||||
} catch (IOException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
Toast.makeText(ctx, "Import failed", LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
private static File getDataDir(Context ctx) {
|
||||
return new File(ctx.getApplicationInfo().dataDir);
|
||||
}
|
||||
|
||||
private static File getBackupDir(Context ctx) {
|
||||
File downloads = getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS);
|
||||
return new File(downloads, ctx.getPackageName());
|
||||
}
|
||||
|
||||
private static void copyRecursively(File src, File dest)
|
||||
throws IOException {
|
||||
if (src.isDirectory()) {
|
||||
if (!dest.isDirectory() && !dest.mkdirs()) throw new IOException();
|
||||
File[] children = src.listFiles();
|
||||
if (children == null) throw new IOException();
|
||||
for (File child : children) {
|
||||
copyRecursively(child, new File(dest, child.getName()));
|
||||
}
|
||||
} else if (src.isFile()) {
|
||||
InputStream in = new FileInputStream(src);
|
||||
OutputStream out = new FileOutputStream(dest);
|
||||
copyAndClose(in, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,24 +117,14 @@ public class UnlockActivity extends BaseActivity {
|
||||
|
||||
@RequiresApi(api = 28)
|
||||
private void requestFingerprintUnlock() {
|
||||
BiometricPrompt biometricPrompt;
|
||||
if (SDK_INT >= 29) {
|
||||
biometricPrompt = new Builder(this)
|
||||
.setTitle(getString(R.string.lock_unlock))
|
||||
.setDescription(getString(
|
||||
R.string.lock_unlock_fingerprint_description))
|
||||
.setDeviceCredentialAllowed(true)
|
||||
.build();
|
||||
} else {
|
||||
biometricPrompt = new Builder(this)
|
||||
.setTitle(getString(R.string.lock_unlock))
|
||||
.setDescription(getString(
|
||||
R.string.lock_unlock_fingerprint_description))
|
||||
.setNegativeButton(getString(R.string.lock_unlock_password),
|
||||
getMainExecutor(),
|
||||
(dialog, which) -> requestKeyguardUnlock())
|
||||
.build();
|
||||
}
|
||||
BiometricPrompt biometricPrompt = new Builder(this)
|
||||
.setTitle(getString(R.string.lock_unlock))
|
||||
.setDescription(
|
||||
getString(R.string.lock_unlock_fingerprint_description))
|
||||
.setNegativeButton(getString(R.string.lock_unlock_password),
|
||||
getMainExecutor(),
|
||||
(dialog, which) -> requestKeyguardUnlock())
|
||||
.build();
|
||||
CancellationSignal signal = new CancellationSignal();
|
||||
AuthenticationCallback callback = new AuthenticationCallback() {
|
||||
@Override
|
||||
|
||||
@@ -47,7 +47,6 @@ import org.briarproject.briar.android.login.OpenDatabaseFragment;
|
||||
import org.briarproject.briar.android.login.PasswordFragment;
|
||||
import org.briarproject.briar.android.login.StartupActivity;
|
||||
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
|
||||
import org.briarproject.briar.android.navdrawer.TransportsActivity;
|
||||
import org.briarproject.briar.android.panic.PanicPreferencesActivity;
|
||||
import org.briarproject.briar.android.panic.PanicResponderActivity;
|
||||
import org.briarproject.briar.android.privategroup.conversation.GroupActivity;
|
||||
@@ -164,8 +163,6 @@ public interface ActivityComponent {
|
||||
|
||||
void inject(SettingsActivity activity);
|
||||
|
||||
void inject(TransportsActivity activity);
|
||||
|
||||
void inject(TestDataActivity activity);
|
||||
|
||||
void inject(ChangePasswordActivity activity);
|
||||
|
||||
@@ -34,7 +34,6 @@ import androidx.lifecycle.MutableLiveData;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.ERROR;
|
||||
import static org.briarproject.briar.android.util.UiUtils.observeForeverOnce;
|
||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_IMAGE_SIZE;
|
||||
|
||||
@@ -76,12 +75,8 @@ class AttachmentCreatorImpl implements AttachmentCreator {
|
||||
@UiThread
|
||||
public LiveData<AttachmentResult> storeAttachments(
|
||||
LiveData<GroupId> groupId, Collection<Uri> newUris) {
|
||||
if (task != null || result != null || !uris.isEmpty()) {
|
||||
if (task != null) LOG.warning("Task already exists!");
|
||||
if (result != null) LOG.warning("Result already exists!");
|
||||
if (!uris.isEmpty()) LOG.warning("Uris available: " + uris);
|
||||
if (task != null || result != null || !uris.isEmpty())
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
MutableLiveData<AttachmentResult> result = new MutableLiveData<>();
|
||||
this.result = result;
|
||||
uris.addAll(newUris);
|
||||
@@ -100,12 +95,8 @@ class AttachmentCreatorImpl implements AttachmentCreator {
|
||||
@UiThread
|
||||
public LiveData<AttachmentResult> getLiveAttachments() {
|
||||
MutableLiveData<AttachmentResult> result = this.result;
|
||||
if (task == null || result == null || uris.isEmpty()) {
|
||||
if (task == null) LOG.warning("No Task!");
|
||||
if (result == null) LOG.warning("No Result!");
|
||||
if (uris.isEmpty()) LOG.warning("Uris empty!");
|
||||
if (task == null || result == null || uris.isEmpty())
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
// A task is already running. It will update the result LiveData.
|
||||
// So nothing more to do here.
|
||||
return result;
|
||||
@@ -118,8 +109,8 @@ class AttachmentCreatorImpl implements AttachmentCreator {
|
||||
// get and cache AttachmentItem for ImagePreview
|
||||
try {
|
||||
Attachment a = retriever.getMessageAttachment(h);
|
||||
AttachmentItem item = retriever.createAttachmentItem(a, needsSize);
|
||||
if (item.getState() == ERROR) throw new IOException();
|
||||
AttachmentItem item = retriever.getAttachmentItem(a, needsSize);
|
||||
if (item.hasError()) throw new IOException();
|
||||
AttachmentItemResult itemResult =
|
||||
new AttachmentItemResult(uri, item);
|
||||
itemResults.add(itemResult);
|
||||
@@ -176,13 +167,21 @@ class AttachmentCreatorImpl implements AttachmentCreator {
|
||||
@Override
|
||||
@UiThread
|
||||
public void onAttachmentsSent(MessageId id) {
|
||||
List<AttachmentItem> items = new ArrayList<>(itemResults.size());
|
||||
for (AttachmentItemResult itemResult : itemResults) {
|
||||
// check if we are trying to send attachment items with errors
|
||||
if (itemResult.getItem() == null) throw new IllegalStateException();
|
||||
items.add(itemResult.getItem());
|
||||
}
|
||||
retriever.cachePut(id, items);
|
||||
resetState();
|
||||
}
|
||||
|
||||
@Override
|
||||
@UiThread
|
||||
public void cancel() {
|
||||
if (task != null) task.cancel();
|
||||
if (task == null) throw new AssertionError();
|
||||
task.cancel();
|
||||
deleteUnsentAttachments();
|
||||
resetState();
|
||||
}
|
||||
|
||||
@@ -7,33 +7,24 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.api.messaging.AttachmentHeader;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import static java.lang.System.arraycopy;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.LOADING;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.MISSING;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class AttachmentItem implements Parcelable {
|
||||
|
||||
public enum State {
|
||||
LOADING, MISSING, AVAILABLE, ERROR;
|
||||
|
||||
public boolean isFinal() {
|
||||
return this == AVAILABLE || this == ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
private final AttachmentHeader header;
|
||||
private final int width, height;
|
||||
private final String extension;
|
||||
private final int thumbnailWidth, thumbnailHeight;
|
||||
private final State state;
|
||||
private final boolean hasError;
|
||||
private final long instanceId;
|
||||
|
||||
public static final Creator<AttachmentItem> CREATOR =
|
||||
new Creator<AttachmentItem>() {
|
||||
@@ -48,33 +39,19 @@ public class AttachmentItem implements Parcelable {
|
||||
}
|
||||
};
|
||||
|
||||
private static final AtomicLong NEXT_INSTANCE_ID = new AtomicLong(0);
|
||||
|
||||
AttachmentItem(AttachmentHeader header, int width, int height,
|
||||
String extension, int thumbnailWidth, int thumbnailHeight,
|
||||
State state) {
|
||||
boolean hasError) {
|
||||
this.header = header;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.extension = extension;
|
||||
this.thumbnailWidth = thumbnailWidth;
|
||||
this.thumbnailHeight = thumbnailHeight;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use only for {@link State MISSING} or {@link State LOADING} items.
|
||||
*/
|
||||
AttachmentItem(AttachmentHeader header, int width, int height,
|
||||
State state) {
|
||||
this(header, width, height, "", width, height, state);
|
||||
if (state != MISSING && state != LOADING)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use when the item does not need a size.
|
||||
*/
|
||||
AttachmentItem(AttachmentHeader header, String extension, State state) {
|
||||
this(header, 0, 0, extension, 0, 0, state);
|
||||
this.hasError = hasError;
|
||||
instanceId = NEXT_INSTANCE_ID.getAndIncrement();
|
||||
}
|
||||
|
||||
protected AttachmentItem(Parcel in) {
|
||||
@@ -87,7 +64,8 @@ public class AttachmentItem implements Parcelable {
|
||||
extension = requireNonNull(in.readString());
|
||||
thumbnailWidth = in.readInt();
|
||||
thumbnailHeight = in.readInt();
|
||||
state = State.valueOf(requireNonNull(in.readString()));
|
||||
hasError = in.readByte() != 0;
|
||||
instanceId = in.readLong();
|
||||
header = new AttachmentHeader(messageId, mimeType);
|
||||
}
|
||||
|
||||
@@ -123,16 +101,12 @@ public class AttachmentItem implements Parcelable {
|
||||
return thumbnailHeight;
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
return state;
|
||||
public boolean hasError() {
|
||||
return hasError;
|
||||
}
|
||||
|
||||
public String getTransitionName(MessageId conversationItemId) {
|
||||
int len = MessageId.LENGTH;
|
||||
byte[] instanceId = new byte[len * 2];
|
||||
arraycopy(header.getMessageId().getBytes(), 0, instanceId, 0, len);
|
||||
arraycopy(conversationItemId.getBytes(), 0, instanceId, len, len);
|
||||
return toHexString(instanceId);
|
||||
public String getTransitionName() {
|
||||
return String.valueOf(instanceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -149,23 +123,14 @@ public class AttachmentItem implements Parcelable {
|
||||
dest.writeString(extension);
|
||||
dest.writeInt(thumbnailWidth);
|
||||
dest.writeInt(thumbnailHeight);
|
||||
dest.writeString(state.name());
|
||||
dest.writeByte((byte) (hasError ? 1 : 0));
|
||||
dest.writeLong(instanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to identity if two items are the same,
|
||||
* irrespective of their state or size.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
return o instanceof AttachmentItem &&
|
||||
header.getMessageId().equals(
|
||||
((AttachmentItem) o).header.getMessageId()
|
||||
);
|
||||
instanceId == ((AttachmentItem) o).instanceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return header.getMessageId().hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +1,29 @@
|
||||
package org.briarproject.briar.android.attachment;
|
||||
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.api.messaging.Attachment;
|
||||
import org.briarproject.briar.api.messaging.AttachmentHeader;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||
import org.briarproject.briar.api.messaging.event.AttachmentReceivedEvent;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface AttachmentRetriever {
|
||||
|
||||
@DatabaseExecutor
|
||||
void cachePut(MessageId messageId, List<AttachmentItem> attachments);
|
||||
|
||||
@Nullable
|
||||
List<AttachmentItem> cacheGet(MessageId messageId);
|
||||
|
||||
Attachment getMessageAttachment(AttachmentHeader h) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a list of observable {@link LiveData}
|
||||
* that get updated as the state of their {@link AttachmentItem}s changes.
|
||||
*/
|
||||
List<LiveData<AttachmentItem>> getAttachmentItems(
|
||||
PrivateMessageHeader messageHeader);
|
||||
|
||||
/**
|
||||
* Retrieves item size and adds the item to the cache, if available.
|
||||
* <p>
|
||||
* Use this to eagerly load the attachment size before it gets displayed.
|
||||
* This is needed for messages containing a single attachment.
|
||||
* Messages with more than one attachment use a standard size.
|
||||
*/
|
||||
@DatabaseExecutor
|
||||
void cacheAttachmentItemWithSize(MessageId conversationMessageId,
|
||||
AttachmentHeader h) throws DbException;
|
||||
|
||||
/**
|
||||
* Creates an {@link AttachmentItem} from the {@link Attachment}'s
|
||||
* {@link InputStream} which will be closed when this method returns.
|
||||
*/
|
||||
AttachmentItem createAttachmentItem(Attachment a, boolean needsSize);
|
||||
|
||||
/**
|
||||
* Loads an {@link AttachmentItem}
|
||||
* that arrived via an {@link AttachmentReceivedEvent}
|
||||
* and notifies the associated {@link LiveData}.
|
||||
*
|
||||
* Note that you need to call {@link #getAttachmentItems(PrivateMessageHeader)}
|
||||
* first to get the LiveData.
|
||||
*
|
||||
* It is possible that no LiveData is available,
|
||||
* because the message of the AttachmentItem did not arrive, yet.
|
||||
* In this case, the load wil be deferred until the message arrives.
|
||||
*/
|
||||
@DatabaseExecutor
|
||||
void loadAttachmentItem(MessageId attachmentId);
|
||||
|
||||
AttachmentItem getAttachmentItem(Attachment a, boolean needsSize);
|
||||
}
|
||||
|
||||
@@ -1,39 +1,25 @@
|
||||
package org.briarproject.briar.android.attachment;
|
||||
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.android.attachment.AttachmentItem.State;
|
||||
import org.briarproject.briar.api.messaging.Attachment;
|
||||
import org.briarproject.briar.api.messaging.AttachmentHeader;
|
||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.AVAILABLE;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.ERROR;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.LOADING;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.MISSING;
|
||||
|
||||
@NotNullByDefault
|
||||
class AttachmentRetrieverImpl implements AttachmentRetriever {
|
||||
@@ -41,8 +27,6 @@ class AttachmentRetrieverImpl implements AttachmentRetriever {
|
||||
private static final Logger LOG =
|
||||
getLogger(AttachmentRetrieverImpl.class.getName());
|
||||
|
||||
@DatabaseExecutor
|
||||
private final Executor dbExecutor;
|
||||
private final MessagingManager messagingManager;
|
||||
private final ImageHelper imageHelper;
|
||||
private final ImageSizeCalculator imageSizeCalculator;
|
||||
@@ -50,17 +34,13 @@ class AttachmentRetrieverImpl implements AttachmentRetriever {
|
||||
private final int minWidth, maxWidth;
|
||||
private final int minHeight, maxHeight;
|
||||
|
||||
private final ConcurrentMap<MessageId, MutableLiveData<AttachmentItem>>
|
||||
itemsWithSize = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<MessageId, MutableLiveData<AttachmentItem>>
|
||||
itemsWithoutSize = new ConcurrentHashMap<>();
|
||||
private final Map<MessageId, List<AttachmentItem>> attachmentCache =
|
||||
new ConcurrentHashMap<>();
|
||||
|
||||
@Inject
|
||||
AttachmentRetrieverImpl(@DatabaseExecutor Executor dbExecutor,
|
||||
MessagingManager messagingManager,
|
||||
AttachmentRetrieverImpl(MessagingManager messagingManager,
|
||||
AttachmentDimensions dimensions, ImageHelper imageHelper,
|
||||
ImageSizeCalculator imageSizeCalculator) {
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.messagingManager = messagingManager;
|
||||
this.imageHelper = imageHelper;
|
||||
this.imageSizeCalculator = imageSizeCalculator;
|
||||
@@ -72,143 +52,40 @@ class AttachmentRetrieverImpl implements AttachmentRetriever {
|
||||
}
|
||||
|
||||
@Override
|
||||
@DatabaseExecutor
|
||||
public void cachePut(MessageId messageId,
|
||||
List<AttachmentItem> attachments) {
|
||||
attachmentCache.put(messageId, attachments);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public List<AttachmentItem> cacheGet(MessageId messageId) {
|
||||
return attachmentCache.get(messageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attachment getMessageAttachment(AttachmentHeader h)
|
||||
throws DbException {
|
||||
return messagingManager.getAttachment(h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LiveData<AttachmentItem>> getAttachmentItems(
|
||||
PrivateMessageHeader messageHeader) {
|
||||
List<AttachmentHeader> headers = messageHeader.getAttachmentHeaders();
|
||||
List<LiveData<AttachmentItem>> items = new ArrayList<>(headers.size());
|
||||
boolean needsSize = headers.size() == 1;
|
||||
for (AttachmentHeader h : headers) {
|
||||
// try cache for existing item live data
|
||||
MutableLiveData<AttachmentItem> liveData;
|
||||
if (needsSize) liveData = itemsWithSize.get(h.getMessageId());
|
||||
else {
|
||||
// try items with size first, as they work as well
|
||||
liveData = itemsWithSize.get(h.getMessageId());
|
||||
if (liveData == null)
|
||||
liveData = itemsWithoutSize.get(h.getMessageId());
|
||||
}
|
||||
|
||||
// create new live data with LOADING item if cache miss
|
||||
if (liveData == null) {
|
||||
AttachmentItem item = new AttachmentItem(h,
|
||||
defaultSize, defaultSize, LOADING);
|
||||
liveData = new MutableLiveData<>(item);
|
||||
// add new LiveData to cache, checking for concurrent updates
|
||||
MutableLiveData<AttachmentItem> oldLiveData;
|
||||
if (needsSize) {
|
||||
oldLiveData = itemsWithSize.putIfAbsent(h.getMessageId(),
|
||||
liveData);
|
||||
} else {
|
||||
oldLiveData = itemsWithoutSize.putIfAbsent(h.getMessageId(),
|
||||
liveData);
|
||||
}
|
||||
if (oldLiveData == null) {
|
||||
// kick-off loading of attachment, will post to live data
|
||||
MutableLiveData<AttachmentItem> finalLiveData = liveData;
|
||||
dbExecutor.execute(() ->
|
||||
loadAttachmentItem(h, needsSize, finalLiveData));
|
||||
} else {
|
||||
// Concurrent cache update - use the existing live data
|
||||
liveData = oldLiveData;
|
||||
}
|
||||
}
|
||||
items.add(liveData);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DatabaseExecutor
|
||||
public void cacheAttachmentItemWithSize(MessageId conversationMessageId,
|
||||
AttachmentHeader h) throws DbException {
|
||||
// If a live data is already cached we don't need to do anything
|
||||
if (itemsWithSize.containsKey(h.getMessageId())) return;
|
||||
try {
|
||||
Attachment a = messagingManager.getAttachment(h);
|
||||
AttachmentItem item = createAttachmentItem(a, true);
|
||||
MutableLiveData<AttachmentItem> liveData =
|
||||
new MutableLiveData<>(item);
|
||||
// If a live data was concurrently cached, don't replace it
|
||||
itemsWithSize.putIfAbsent(h.getMessageId(), liveData);
|
||||
} catch (NoSuchMessageException e) {
|
||||
LOG.info("Attachment not received yet");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@DatabaseExecutor
|
||||
public void loadAttachmentItem(MessageId attachmentId) {
|
||||
// try to find LiveData for attachment in both caches
|
||||
MutableLiveData<AttachmentItem> liveData;
|
||||
boolean needsSize = true;
|
||||
liveData = itemsWithSize.get(attachmentId);
|
||||
if (liveData == null) {
|
||||
needsSize = false;
|
||||
liveData = itemsWithoutSize.get(attachmentId);
|
||||
}
|
||||
|
||||
// If no LiveData for the attachment exists,
|
||||
// its message did not yet arrive and we can ignore it for now.
|
||||
if (liveData == null) return;
|
||||
|
||||
// actually load the attachment item
|
||||
AttachmentHeader h = requireNonNull(liveData.getValue()).getHeader();
|
||||
loadAttachmentItem(h, needsSize, liveData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an {@link AttachmentItem} from the database
|
||||
* and notifies the given {@link LiveData}.
|
||||
*/
|
||||
@DatabaseExecutor
|
||||
private void loadAttachmentItem(AttachmentHeader h, boolean needsSize,
|
||||
MutableLiveData<AttachmentItem> liveData) {
|
||||
Attachment a;
|
||||
AttachmentItem item;
|
||||
try {
|
||||
a = messagingManager.getAttachment(h);
|
||||
item = createAttachmentItem(a, needsSize);
|
||||
} catch (NoSuchMessageException e) {
|
||||
LOG.info("Attachment not received yet");
|
||||
item = new AttachmentItem(h, defaultSize, defaultSize, MISSING);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
item = new AttachmentItem(h, "", ERROR);
|
||||
}
|
||||
liveData.postValue(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttachmentItem createAttachmentItem(Attachment a,
|
||||
boolean needsSize) {
|
||||
AttachmentItem item;
|
||||
public AttachmentItem getAttachmentItem(Attachment a, boolean needsSize) {
|
||||
AttachmentHeader h = a.getHeader();
|
||||
if (needsSize) {
|
||||
InputStream is = new BufferedInputStream(a.getStream());
|
||||
Size size = imageSizeCalculator.getSize(is, h.getContentType());
|
||||
tryToClose(is, LOG, WARNING);
|
||||
item = createAttachmentItem(h, size);
|
||||
} else {
|
||||
if (!needsSize) {
|
||||
String extension =
|
||||
imageHelper.getExtensionFromMimeType(h.getContentType());
|
||||
State state = AVAILABLE;
|
||||
boolean hasError = false;
|
||||
if (extension == null) {
|
||||
extension = "";
|
||||
state = ERROR;
|
||||
hasError = true;
|
||||
}
|
||||
item = new AttachmentItem(h, extension, state);
|
||||
return new AttachmentItem(h, 0, 0, extension, 0, 0, hasError);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
private AttachmentItem createAttachmentItem(AttachmentHeader h, Size size) {
|
||||
InputStream is = new BufferedInputStream(a.getStream());
|
||||
Size size = imageSizeCalculator.getSize(is, h.getContentType());
|
||||
|
||||
// calculate thumbnail size
|
||||
Size thumbnailSize = new Size(defaultSize, defaultSize, size.mimeType);
|
||||
if (!size.error) {
|
||||
@@ -227,9 +104,8 @@ class AttachmentRetrieverImpl implements AttachmentRetriever {
|
||||
hasError = true;
|
||||
}
|
||||
if (extension == null) extension = "";
|
||||
State state = hasError ? ERROR : AVAILABLE;
|
||||
return new AttachmentItem(h, size.width, size.height,
|
||||
extension, thumbnailSize.width, thumbnailSize.height, state);
|
||||
return new AttachmentItem(h, size.width, size.height, extension,
|
||||
thumbnailSize.width, thumbnailSize.height, hasError);
|
||||
}
|
||||
|
||||
private Size getThumbnailSize(int width, int height, String mimeType) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.NoSuchContactException;
|
||||
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
@@ -64,16 +65,17 @@ import org.briarproject.briar.api.client.ProtocolStateException;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.conversation.ConversationManager;
|
||||
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
|
||||
import org.briarproject.briar.api.conversation.ConversationMessageVisitor;
|
||||
import org.briarproject.briar.api.conversation.ConversationRequest;
|
||||
import org.briarproject.briar.api.conversation.ConversationResponse;
|
||||
import org.briarproject.briar.api.conversation.DeletionResult;
|
||||
import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent;
|
||||
import org.briarproject.briar.api.forum.ForumSharingManager;
|
||||
import org.briarproject.briar.api.introduction.IntroductionManager;
|
||||
import org.briarproject.briar.api.messaging.Attachment;
|
||||
import org.briarproject.briar.api.messaging.AttachmentHeader;
|
||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||
import org.briarproject.briar.api.messaging.event.AttachmentReceivedEvent;
|
||||
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -95,7 +97,6 @@ import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.app.ActivityOptionsCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
@@ -117,6 +118,8 @@ import static androidx.core.app.ActivityOptionsCompat.makeSceneTransitionAnimati
|
||||
import static androidx.core.view.ViewCompat.setTransitionName;
|
||||
import static androidx.lifecycle.Lifecycle.State.STARTED;
|
||||
import static androidx.recyclerview.widget.SortedList.INVALID_POSITION;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.sort;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.INFO;
|
||||
@@ -133,7 +136,6 @@ import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_INTRO
|
||||
import static org.briarproject.briar.android.conversation.ImageActivity.ATTACHMENTS;
|
||||
import static org.briarproject.briar.android.conversation.ImageActivity.ATTACHMENT_POSITION;
|
||||
import static org.briarproject.briar.android.conversation.ImageActivity.DATE;
|
||||
import static org.briarproject.briar.android.conversation.ImageActivity.ITEM_ID;
|
||||
import static org.briarproject.briar.android.conversation.ImageActivity.NAME;
|
||||
import static org.briarproject.briar.android.util.UiUtils.getAvatarTransitionName;
|
||||
import static org.briarproject.briar.android.util.UiUtils.getBulbTransitionName;
|
||||
@@ -183,6 +185,8 @@ public class ConversationActivity extends BriarActivity
|
||||
volatile GroupInvitationManager groupInvitationManager;
|
||||
|
||||
private final Map<MessageId, String> textCache = new ConcurrentHashMap<>();
|
||||
private final Map<MessageId, PrivateMessageHeader> missingAttachments =
|
||||
new ConcurrentHashMap<>();
|
||||
private final Observer<String> contactNameObserver = name -> {
|
||||
requireNonNull(name);
|
||||
loadMessages();
|
||||
@@ -536,7 +540,6 @@ public class ConversationActivity extends BriarActivity
|
||||
});
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
private void eagerlyLoadMessageSize(PrivateMessageHeader h) {
|
||||
try {
|
||||
MessageId id = h.getId();
|
||||
@@ -553,11 +556,21 @@ public class ConversationActivity extends BriarActivity
|
||||
// images we use a grid so the size is fixed
|
||||
List<AttachmentHeader> headers = h.getAttachmentHeaders();
|
||||
if (headers.size() == 1) {
|
||||
LOG.info("Eagerly loading image size for latest message");
|
||||
AttachmentHeader header = headers.get(0);
|
||||
// get the item to retrieve its size
|
||||
attachmentRetriever
|
||||
.cacheAttachmentItemWithSize(h.getId(), header);
|
||||
List<AttachmentItem> items = attachmentRetriever.cacheGet(id);
|
||||
if (items == null) {
|
||||
LOG.info("Eagerly loading image size for latest message");
|
||||
AttachmentHeader header = headers.get(0);
|
||||
try {
|
||||
Attachment a = attachmentRetriever
|
||||
.getMessageAttachment(header);
|
||||
AttachmentItem item =
|
||||
attachmentRetriever.getAttachmentItem(a, true);
|
||||
attachmentRetriever.cachePut(id, singletonList(item));
|
||||
} catch (NoSuchMessageException e) {
|
||||
LOG.info("Attachment not received yet");
|
||||
missingAttachments.put(header.getMessageId(), h);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
@@ -638,18 +651,59 @@ public class ConversationActivity extends BriarActivity
|
||||
&& adapter.isScrolledToBottom(layoutManager);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void updateMessageAttachment(MessageId m, AttachmentItem item) {
|
||||
Pair<Integer, ConversationMessageItem> pair = adapter.getMessageItem(m);
|
||||
if (pair != null && pair.getSecond().updateAttachments(item)) {
|
||||
boolean scroll = shouldScrollWhenUpdatingMessage();
|
||||
adapter.notifyItemChanged(pair.getFirst());
|
||||
if (scroll) scrollToBottom();
|
||||
}
|
||||
private void loadMessageAttachments(PrivateMessageHeader h) {
|
||||
// TODO: Use placeholders for missing/invalid attachments
|
||||
runOnDbThread(() -> {
|
||||
try {
|
||||
// TODO move getting the items off to IoExecutor, if size == 1
|
||||
List<AttachmentHeader> headers = h.getAttachmentHeaders();
|
||||
boolean needsSize = headers.size() == 1;
|
||||
List<AttachmentItem> items = new ArrayList<>(headers.size());
|
||||
for (AttachmentHeader header : headers) {
|
||||
try {
|
||||
Attachment a = attachmentRetriever
|
||||
.getMessageAttachment(header);
|
||||
AttachmentItem item = attachmentRetriever
|
||||
.getAttachmentItem(a, needsSize);
|
||||
items.add(item);
|
||||
} catch (NoSuchMessageException e) {
|
||||
LOG.info("Attachment not received yet");
|
||||
missingAttachments.put(header.getMessageId(), h);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Don't cache items unless all are present and valid
|
||||
attachmentRetriever.cachePut(h.getId(), items);
|
||||
displayMessageAttachments(h.getId(), items);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void displayMessageAttachments(MessageId m,
|
||||
List<AttachmentItem> items) {
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
Pair<Integer, ConversationMessageItem> pair =
|
||||
adapter.getMessageItem(m);
|
||||
if (pair != null) {
|
||||
boolean scroll = shouldScrollWhenUpdatingMessage();
|
||||
pair.getSecond().setAttachments(items);
|
||||
adapter.notifyItemChanged(pair.getFirst());
|
||||
if (scroll) scrollToBottom();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof AttachmentReceivedEvent) {
|
||||
AttachmentReceivedEvent a = (AttachmentReceivedEvent) e;
|
||||
if (a.getContactId().equals(contactId)) {
|
||||
LOG.info("Attachment received");
|
||||
onAttachmentReceived(a.getMessageId());
|
||||
}
|
||||
}
|
||||
if (e instanceof ContactRemovedEvent) {
|
||||
ContactRemovedEvent c = (ContactRemovedEvent) e;
|
||||
if (c.getContactId().equals(contactId)) {
|
||||
@@ -709,6 +763,15 @@ public class ConversationActivity extends BriarActivity
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void onAttachmentReceived(MessageId attachmentId) {
|
||||
PrivateMessageHeader h = missingAttachments.remove(attachmentId);
|
||||
if (h != null) {
|
||||
LOG.info("Missing attachment received");
|
||||
loadMessageAttachments(h);
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void onNewConversationMessage(ConversationMessageHeader h) {
|
||||
if (h instanceof ConversationRequest ||
|
||||
@@ -717,7 +780,7 @@ public class ConversationActivity extends BriarActivity
|
||||
observeOnce(viewModel.getContactDisplayName(), this,
|
||||
name -> addConversationItem(h.accept(visitor)));
|
||||
} else {
|
||||
// visitor also loads message text and attachments (if existing)
|
||||
// visitor also loads message text (if existing)
|
||||
addConversationItem(h.accept(visitor));
|
||||
}
|
||||
}
|
||||
@@ -1044,9 +1107,8 @@ public class ConversationActivity extends BriarActivity
|
||||
i.putExtra(ATTACHMENT_POSITION, attachments.indexOf(item));
|
||||
i.putExtra(NAME, name);
|
||||
i.putExtra(DATE, messageItem.getTime());
|
||||
i.putExtra(ITEM_ID, messageItem.getId().getBytes());
|
||||
// restoring list position should not trigger android bug #224270
|
||||
String transitionName = item.getTransitionName(messageItem.getId());
|
||||
String transitionName = item.getTransitionName();
|
||||
ActivityOptionsCompat options =
|
||||
makeSceneTransitionAnimation(this, view, transitionName);
|
||||
ActivityCompat.startActivity(this, i, options.toBundle());
|
||||
@@ -1085,41 +1147,15 @@ public class ConversationActivity extends BriarActivity
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by {@link PrivateMessageHeader#accept(ConversationMessageVisitor)}
|
||||
*/
|
||||
@Override
|
||||
public List<AttachmentItem> getAttachmentItems(PrivateMessageHeader h) {
|
||||
List<LiveData<AttachmentItem>> liveDataList =
|
||||
attachmentRetriever.getAttachmentItems(h);
|
||||
List<AttachmentItem> items = new ArrayList<>(liveDataList.size());
|
||||
for (LiveData<AttachmentItem> liveData : liveDataList) {
|
||||
// first remove all our observers to avoid having more than one
|
||||
// in case we reload the conversation, e.g. after deleting messages
|
||||
liveData.removeObservers(this);
|
||||
// add a new observer
|
||||
liveData.observe(this, new AttachmentObserver(h.getId(), liveData));
|
||||
items.add(requireNonNull(liveData.getValue()));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private class AttachmentObserver implements Observer<AttachmentItem> {
|
||||
private final MessageId conversationMessageId;
|
||||
private final LiveData<AttachmentItem> liveData;
|
||||
|
||||
private AttachmentObserver(MessageId conversationMessageId,
|
||||
LiveData<AttachmentItem> liveData) {
|
||||
this.conversationMessageId = conversationMessageId;
|
||||
this.liveData = liveData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChanged(AttachmentItem attachmentItem) {
|
||||
updateMessageAttachment(conversationMessageId, attachmentItem);
|
||||
if (attachmentItem.getState().isFinal())
|
||||
liveData.removeObserver(this);
|
||||
List<AttachmentItem> attachments =
|
||||
attachmentRetriever.cacheGet(h.getId());
|
||||
if (attachments == null) {
|
||||
loadMessageAttachments(h);
|
||||
return emptyList();
|
||||
}
|
||||
return attachments;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,13 +9,12 @@ import java.util.List;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
class ConversationMessageItem extends ConversationItem {
|
||||
|
||||
private final List<AttachmentItem> attachments;
|
||||
private List<AttachmentItem> attachments;
|
||||
|
||||
ConversationMessageItem(@LayoutRes int layoutRes, PrivateMessageHeader h,
|
||||
List<AttachmentItem> attachments) {
|
||||
@@ -27,14 +26,8 @@ class ConversationMessageItem extends ConversationItem {
|
||||
return attachments;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
boolean updateAttachments(AttachmentItem item) {
|
||||
int pos = attachments.indexOf(item);
|
||||
if (pos != -1 && attachments.get(pos).getState() != item.getState()) {
|
||||
attachments.set(pos, item);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
void setAttachments(List<AttachmentItem> attachments) {
|
||||
this.attachments = attachments;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@ import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.NoSuchContactException;
|
||||
import org.briarproject.bramble.api.db.TransactionManager;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.settings.Settings;
|
||||
@@ -33,7 +30,6 @@ import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||
import org.briarproject.briar.api.messaging.event.AttachmentReceivedEvent;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -60,7 +56,7 @@ import static org.briarproject.briar.android.util.UiUtils.observeForeverOnce;
|
||||
|
||||
@NotNullByDefault
|
||||
public class ConversationViewModel extends AndroidViewModel
|
||||
implements EventListener, AttachmentManager {
|
||||
implements AttachmentManager {
|
||||
|
||||
private static Logger LOG =
|
||||
getLogger(ConversationViewModel.class.getName());
|
||||
@@ -73,7 +69,6 @@ public class ConversationViewModel extends AndroidViewModel
|
||||
@DatabaseExecutor
|
||||
private final Executor dbExecutor;
|
||||
private final TransactionManager db;
|
||||
private final EventBus eventBus;
|
||||
private final MessagingManager messagingManager;
|
||||
private final ContactManager contactManager;
|
||||
private final SettingsManager settingsManager;
|
||||
@@ -106,7 +101,6 @@ public class ConversationViewModel extends AndroidViewModel
|
||||
ConversationViewModel(Application application,
|
||||
@DatabaseExecutor Executor dbExecutor,
|
||||
TransactionManager db,
|
||||
EventBus eventBus,
|
||||
MessagingManager messagingManager,
|
||||
ContactManager contactManager,
|
||||
SettingsManager settingsManager,
|
||||
@@ -116,7 +110,6 @@ public class ConversationViewModel extends AndroidViewModel
|
||||
super(application);
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.db = db;
|
||||
this.eventBus = eventBus;
|
||||
this.messagingManager = messagingManager;
|
||||
this.contactManager = contactManager;
|
||||
this.settingsManager = settingsManager;
|
||||
@@ -126,27 +119,12 @@ public class ConversationViewModel extends AndroidViewModel
|
||||
messagingGroupId = Transformations
|
||||
.map(contact, c -> messagingManager.getContactGroup(c).getId());
|
||||
contactDeleted.setValue(false);
|
||||
|
||||
eventBus.addListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
attachmentCreator.cancel(); // also deletes unsent attachments
|
||||
eventBus.removeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof AttachmentReceivedEvent) {
|
||||
AttachmentReceivedEvent a = (AttachmentReceivedEvent) e;
|
||||
if (a.getContactId().equals(contactId)) {
|
||||
LOG.info("Attachment received");
|
||||
dbExecutor.execute(() -> attachmentRetriever
|
||||
.loadAttachmentItem(a.getMessageId()));
|
||||
}
|
||||
}
|
||||
attachmentCreator.deleteUnsentAttachments();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,7 +252,6 @@ public class ConversationViewModel extends AndroidViewModel
|
||||
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void createMessage(GroupId groupId, @Nullable String text,
|
||||
List<AttachmentHeader> headers, long timestamp,
|
||||
boolean hasImageSupport) {
|
||||
@@ -293,7 +270,6 @@ public class ConversationViewModel extends AndroidViewModel
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void storeMessage(PrivateMessage m) {
|
||||
attachmentCreator.onAttachmentsSent(m.getMessage().getId());
|
||||
dbExecutor.execute(() -> {
|
||||
|
||||
@@ -16,7 +16,6 @@ import com.google.android.material.appbar.AppBarLayout;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.activity.BriarActivity;
|
||||
@@ -68,7 +67,6 @@ public class ImageActivity extends BriarActivity
|
||||
final static String ATTACHMENT_POSITION = "position";
|
||||
final static String NAME = "name";
|
||||
final static String DATE = "date";
|
||||
final static String ITEM_ID = "itemId";
|
||||
|
||||
@RequiresApi(api = 16)
|
||||
private final static int UI_FLAGS_DEFAULT =
|
||||
@@ -82,7 +80,6 @@ public class ImageActivity extends BriarActivity
|
||||
private AppBarLayout appBarLayout;
|
||||
private ViewPager viewPager;
|
||||
private List<AttachmentItem> attachments;
|
||||
private MessageId conversationMessageId;
|
||||
|
||||
@Override
|
||||
public void injectActivity(ActivityComponent component) {
|
||||
@@ -101,20 +98,9 @@ public class ImageActivity extends BriarActivity
|
||||
setSceneTransitionAnimation(transition, null, transition);
|
||||
}
|
||||
|
||||
// Intent Extras
|
||||
Intent i = getIntent();
|
||||
attachments =
|
||||
requireNonNull(i.getParcelableArrayListExtra(ATTACHMENTS));
|
||||
int position = i.getIntExtra(ATTACHMENT_POSITION, -1);
|
||||
if (position == -1) throw new IllegalStateException();
|
||||
String name = i.getStringExtra(NAME);
|
||||
long time = i.getLongExtra(DATE, 0);
|
||||
byte[] messageIdBytes = requireNonNull(i.getByteArrayExtra(ITEM_ID));
|
||||
|
||||
// get View Model
|
||||
viewModel = ViewModelProviders.of(this, viewModelFactory)
|
||||
.get(ImageViewModel.class);
|
||||
viewModel.expectAttachments(attachments);
|
||||
viewModel.getSaveState().observeEvent(this,
|
||||
this::onImageSaveStateChanged);
|
||||
|
||||
@@ -138,11 +124,16 @@ public class ImageActivity extends BriarActivity
|
||||
TextView contactName = toolbar.findViewById(R.id.contactName);
|
||||
TextView dateView = toolbar.findViewById(R.id.dateView);
|
||||
|
||||
// Set contact name and message time
|
||||
// Intent Extras
|
||||
Intent i = getIntent();
|
||||
attachments = i.getParcelableArrayListExtra(ATTACHMENTS);
|
||||
int position = i.getIntExtra(ATTACHMENT_POSITION, -1);
|
||||
if (position == -1) throw new IllegalStateException();
|
||||
String name = i.getStringExtra(NAME);
|
||||
long time = i.getLongExtra(DATE, 0);
|
||||
String date = formatDateAbsolute(this, time);
|
||||
contactName.setText(name);
|
||||
dateView.setText(date);
|
||||
conversationMessageId = new MessageId(messageIdBytes);
|
||||
|
||||
// Set up image ViewPager
|
||||
viewPager = findViewById(R.id.viewPager);
|
||||
@@ -329,8 +320,8 @@ public class ImageActivity extends BriarActivity
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
Fragment f = ImageFragment.newInstance(
|
||||
attachments.get(position), conversationMessageId, isFirst);
|
||||
Fragment f = ImageFragment
|
||||
.newInstance(attachments.get(position), isFirst);
|
||||
isFirst = false;
|
||||
return f;
|
||||
}
|
||||
|
||||
@@ -49,8 +49,7 @@ class ImageAdapter extends Adapter<ImageViewHolder> {
|
||||
public ImageViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
|
||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
||||
R.layout.list_item_image, viewGroup, false);
|
||||
requireNonNull(conversationItem);
|
||||
return new ImageViewHolder(v, imageSize, conversationItem.getId());
|
||||
return new ImageViewHolder(v, imageSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,7 +15,6 @@ import com.bumptech.glide.request.target.Target;
|
||||
import com.github.chrisbanes.photoview.PhotoView;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.BaseActivity;
|
||||
import org.briarproject.briar.android.attachment.AttachmentItem;
|
||||
@@ -24,7 +23,6 @@ import org.briarproject.briar.android.conversation.glide.GlideApp;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
@@ -34,36 +32,27 @@ import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.widget.ImageView.ScaleType.FIT_START;
|
||||
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
|
||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.AVAILABLE;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.ERROR;
|
||||
import static org.briarproject.briar.android.conversation.ImageActivity.ATTACHMENT_POSITION;
|
||||
import static org.briarproject.briar.android.conversation.ImageActivity.ITEM_ID;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public class ImageFragment extends Fragment
|
||||
implements RequestListener<Drawable> {
|
||||
public class ImageFragment extends Fragment {
|
||||
|
||||
private final static String IS_FIRST = "isFirst";
|
||||
@DrawableRes
|
||||
private static final int ERROR_RES = R.drawable.ic_image_broken;
|
||||
|
||||
@Inject
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
private AttachmentItem attachment;
|
||||
private boolean isFirst;
|
||||
private MessageId conversationItemId;
|
||||
private ImageViewModel viewModel;
|
||||
private PhotoView photoView;
|
||||
|
||||
static ImageFragment newInstance(AttachmentItem a,
|
||||
MessageId conversationMessageId, boolean isFirst) {
|
||||
static ImageFragment newInstance(AttachmentItem a, boolean isFirst) {
|
||||
ImageFragment f = new ImageFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable(ATTACHMENT_POSITION, a);
|
||||
args.putBoolean(IS_FIRST, isFirst);
|
||||
args.putByteArray(ITEM_ID, conversationMessageId.getBytes());
|
||||
f.setArguments(args);
|
||||
return f;
|
||||
}
|
||||
@@ -81,8 +70,6 @@ public class ImageFragment extends Fragment
|
||||
Bundle args = requireNonNull(getArguments());
|
||||
attachment = requireNonNull(args.getParcelable(ATTACHMENT_POSITION));
|
||||
isFirst = args.getBoolean(IS_FIRST);
|
||||
conversationItemId =
|
||||
new MessageId(requireNonNull(args.getByteArray(ITEM_ID)));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -100,68 +87,50 @@ public class ImageFragment extends Fragment
|
||||
photoView.setScaleLevels(1, 2, 4);
|
||||
photoView.setOnClickListener(view -> viewModel.clickImage());
|
||||
|
||||
if (attachment.getState() == AVAILABLE) {
|
||||
loadImage();
|
||||
// postponed transition will be started when Image was loaded
|
||||
} else if (attachment.getState() == ERROR) {
|
||||
photoView.setImageResource(ERROR_RES);
|
||||
startPostponedTransition();
|
||||
} else {
|
||||
photoView.setImageResource(R.drawable.ic_image_missing);
|
||||
startPostponedTransition();
|
||||
// state is not final, so observe state changes
|
||||
viewModel.getOnAttachmentReceived(attachment.getMessageId())
|
||||
.observeEvent(this, this::onAttachmentReceived);
|
||||
}
|
||||
// Request Listener
|
||||
RequestListener<Drawable> listener = new RequestListener<Drawable>() {
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e,
|
||||
Object model, Target<Drawable> target,
|
||||
boolean isFirstResource) {
|
||||
if (getActivity() != null && isFirst)
|
||||
getActivity().supportStartPostponedEnterTransition();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
if (SDK_INT >= 21 && !(resource instanceof Animatable)) {
|
||||
// set transition name only when not animatable,
|
||||
// because the animation won't start otherwise
|
||||
photoView.setTransitionName(
|
||||
attachment.getTransitionName());
|
||||
}
|
||||
// Move image to the top if overlapping toolbar
|
||||
if (viewModel.isOverlappingToolbar(photoView, resource)) {
|
||||
photoView.setScaleType(FIT_START);
|
||||
}
|
||||
if (getActivity() != null && isFirst) {
|
||||
getActivity().supportStartPostponedEnterTransition();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Load Image
|
||||
GlideApp.with(this)
|
||||
.load(attachment)
|
||||
// TODO allow if size < maxTextureSize ?
|
||||
// .override(SIZE_ORIGINAL)
|
||||
.diskCacheStrategy(NONE)
|
||||
.error(R.drawable.ic_image_broken)
|
||||
.addListener(listener)
|
||||
.into(photoView);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
private void loadImage() {
|
||||
GlideApp.with(this)
|
||||
.load(attachment)
|
||||
// TODO allow if size < maxTextureSize ?
|
||||
// .override(SIZE_ORIGINAL)
|
||||
.diskCacheStrategy(NONE)
|
||||
.error(ERROR_RES)
|
||||
.addListener(this)
|
||||
.into(photoView);
|
||||
}
|
||||
|
||||
private void onAttachmentReceived(Boolean received) {
|
||||
if (received) loadImage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e,
|
||||
Object model, Target<Drawable> target,
|
||||
boolean isFirstResource) {
|
||||
startPostponedTransition();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model,
|
||||
Target<Drawable> target, DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
if (SDK_INT >= 21 && !(resource instanceof Animatable)) {
|
||||
// set transition name only when not animatable,
|
||||
// because the animation won't start otherwise
|
||||
photoView.setTransitionName(
|
||||
attachment.getTransitionName(conversationItemId));
|
||||
}
|
||||
// Move image to the top if overlapping toolbar
|
||||
if (viewModel.isOverlappingToolbar(photoView, resource)) {
|
||||
photoView.setScaleType(FIT_START);
|
||||
}
|
||||
startPostponedTransition();
|
||||
return false;
|
||||
}
|
||||
|
||||
private void startPostponedTransition() {
|
||||
if (getActivity() != null && isFirst) {
|
||||
getActivity().supportStartPostponedEnterTransition();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import android.widget.ImageView;
|
||||
import com.bumptech.glide.load.Transformation;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.attachment.AttachmentItem;
|
||||
import org.briarproject.briar.android.conversation.glide.BriarImageTransformation;
|
||||
@@ -19,12 +18,8 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager.LayoutParams;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.widget.ImageView.ScaleType.CENTER_CROP;
|
||||
import static android.widget.ImageView.ScaleType.FIT_CENTER;
|
||||
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
|
||||
import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.AVAILABLE;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.ERROR;
|
||||
|
||||
@NotNullByDefault
|
||||
class ImageViewHolder extends ViewHolder {
|
||||
@@ -34,33 +29,25 @@ class ImageViewHolder extends ViewHolder {
|
||||
|
||||
protected final ImageView imageView;
|
||||
private final int imageSize;
|
||||
private final MessageId conversationItemId;
|
||||
|
||||
ImageViewHolder(View v, int imageSize, MessageId conversationItemId) {
|
||||
ImageViewHolder(View v, int imageSize) {
|
||||
super(v);
|
||||
imageView = v.findViewById(R.id.imageView);
|
||||
this.imageSize = imageSize;
|
||||
this.conversationItemId = conversationItemId;
|
||||
}
|
||||
|
||||
void bind(AttachmentItem attachment, Radii r, boolean single,
|
||||
boolean needsStretch) {
|
||||
setImageViewDimensions(attachment, single, needsStretch);
|
||||
if (attachment.getState() != AVAILABLE) {
|
||||
GlideApp.with(imageView).clear(imageView);
|
||||
if (attachment.getState() == ERROR) {
|
||||
imageView.setImageResource(ERROR_RES);
|
||||
} else {
|
||||
imageView.setImageResource(R.drawable.ic_image_missing);
|
||||
}
|
||||
imageView.setScaleType(FIT_CENTER);
|
||||
if (attachment.hasError()) {
|
||||
GlideApp.with(imageView)
|
||||
.clear(imageView);
|
||||
imageView.setImageResource(ERROR_RES);
|
||||
} else {
|
||||
setImageViewDimensions(attachment, single, needsStretch);
|
||||
loadImage(attachment, r);
|
||||
imageView.setScaleType(CENTER_CROP);
|
||||
}
|
||||
if (SDK_INT >= 21) {
|
||||
imageView.setTransitionName(
|
||||
attachment.getTransitionName(conversationItemId));
|
||||
if (SDK_INT >= 21) {
|
||||
imageView.setTransitionName(attachment.getTransitionName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,18 +7,13 @@ import android.view.View;
|
||||
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.android.attachment.AttachmentItem;
|
||||
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
||||
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
||||
import org.briarproject.briar.api.messaging.Attachment;
|
||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
import org.briarproject.briar.api.messaging.event.AttachmentReceivedEvent;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -27,8 +22,6 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
@@ -42,28 +35,22 @@ import androidx.lifecycle.AndroidViewModel;
|
||||
import static android.media.MediaScannerConnection.scanFile;
|
||||
import static android.os.Environment.DIRECTORY_PICTURES;
|
||||
import static android.os.Environment.getExternalStoragePublicDirectory;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
|
||||
@NotNullByDefault
|
||||
public class ImageViewModel extends AndroidViewModel implements EventListener {
|
||||
public class ImageViewModel extends AndroidViewModel {
|
||||
|
||||
private static Logger LOG = getLogger(ImageViewModel.class.getName());
|
||||
|
||||
private final MessagingManager messagingManager;
|
||||
private final EventBus eventBus;
|
||||
@DatabaseExecutor
|
||||
private final Executor dbExecutor;
|
||||
@IoExecutor
|
||||
private final Executor ioExecutor;
|
||||
|
||||
private boolean receivedAttachmentsInitialized = false;
|
||||
private HashMap<MessageId, MutableLiveEvent<Boolean>> receivedAttachments =
|
||||
new HashMap<>();
|
||||
|
||||
/**
|
||||
* true means there was an error saving the image, false if image was saved.
|
||||
*/
|
||||
@@ -75,60 +62,13 @@ public class ImageViewModel extends AndroidViewModel implements EventListener {
|
||||
|
||||
@Inject
|
||||
ImageViewModel(Application application,
|
||||
MessagingManager messagingManager, EventBus eventBus,
|
||||
MessagingManager messagingManager,
|
||||
@DatabaseExecutor Executor dbExecutor,
|
||||
@IoExecutor Executor ioExecutor) {
|
||||
super(application);
|
||||
this.messagingManager = messagingManager;
|
||||
this.eventBus = eventBus;
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.ioExecutor = ioExecutor;
|
||||
|
||||
eventBus.addListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
eventBus.removeListener(this);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof AttachmentReceivedEvent) {
|
||||
MessageId id = ((AttachmentReceivedEvent) e).getMessageId();
|
||||
MutableLiveEvent<Boolean> oldEvent;
|
||||
if (receivedAttachmentsInitialized) {
|
||||
oldEvent = receivedAttachments.get(id);
|
||||
if (oldEvent != null) oldEvent.postEvent(true);
|
||||
} else {
|
||||
receivedAttachments.put(id, new MutableLiveEvent<>(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void expectAttachments(List<AttachmentItem> attachments) {
|
||||
for (AttachmentItem item : attachments) {
|
||||
// no need to track items that are in a final state already
|
||||
if (item.getState().isFinal()) continue;
|
||||
// add new live events, if not already added by eventOccurred()
|
||||
MessageId id = item.getMessageId();
|
||||
if (!receivedAttachments.containsKey(id)) {
|
||||
receivedAttachments.put(id, new MutableLiveEvent<>());
|
||||
}
|
||||
}
|
||||
receivedAttachmentsInitialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a LiveData for attachments in a non-final state.
|
||||
* Note that you need to call {@link #expectAttachments(List)} first.
|
||||
*/
|
||||
@UiThread
|
||||
LiveEvent<Boolean> getOnAttachmentReceived(MessageId messageId) {
|
||||
return requireNonNull(receivedAttachments.get(messageId));
|
||||
}
|
||||
|
||||
void clickImage() {
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
@@ -113,7 +114,9 @@ public class ContactExchangeActivity extends KeyAgreementActivity {
|
||||
return getString(R.string.exchanging_contact_details);
|
||||
}
|
||||
|
||||
private void showErrorFragment() {
|
||||
showNextFragment(new ContactExchangeErrorFragment());
|
||||
protected void showErrorFragment() {
|
||||
String errorMsg = getString(R.string.connection_error_explanation);
|
||||
BaseFragment f = ContactExchangeErrorFragment.newInstance(errorMsg);
|
||||
showNextFragment(f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.briar.android.keyagreement;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -19,10 +18,7 @@ import org.briarproject.briar.android.util.UiUtils;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
|
||||
import static android.view.View.GONE;
|
||||
import static org.briarproject.briar.android.util.UiUtils.onSingleLinkClick;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@@ -62,12 +58,13 @@ public class ContactExchangeErrorFragment extends BaseFragment {
|
||||
View v = inflater.inflate(R.layout.fragment_error_contact_exchange,
|
||||
container, false);
|
||||
|
||||
// set optional error message
|
||||
// set humanized error message
|
||||
TextView explanation = v.findViewById(R.id.errorMessage);
|
||||
Bundle args = getArguments();
|
||||
String errorMessage = args == null ? null : args.getString(ERROR_MSG);
|
||||
if (errorMessage == null) explanation.setVisibility(GONE);
|
||||
else explanation.setText(args.getString(ERROR_MSG));
|
||||
if (args == null) {
|
||||
throw new IllegalArgumentException("Use newInstance()");
|
||||
}
|
||||
explanation.setText(args.getString(ERROR_MSG));
|
||||
|
||||
// make feedback link clickable
|
||||
TextView sendFeedback = v.findViewById(R.id.sendFeedback);
|
||||
@@ -76,11 +73,7 @@ public class ContactExchangeErrorFragment extends BaseFragment {
|
||||
// buttons
|
||||
Button tryAgain = v.findViewById(R.id.tryAgainButton);
|
||||
tryAgain.setOnClickListener(view -> {
|
||||
// Recreate the activity so we return to the intro fragment
|
||||
FragmentActivity activity = requireActivity();
|
||||
Intent i = new Intent(activity, ContactExchangeActivity.class);
|
||||
i.setFlags(FLAG_ACTIVITY_CLEAR_TOP);
|
||||
activity.startActivity(i);
|
||||
if (getActivity() != null) getActivity().onBackPressed();
|
||||
});
|
||||
Button cancel = v.findViewById(R.id.cancelButton);
|
||||
cancel.setOnClickListener(view -> finish());
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
||||
import org.briarproject.bramble.api.plugin.Plugin;
|
||||
import org.briarproject.bramble.api.plugin.Plugin.State;
|
||||
import org.briarproject.bramble.api.plugin.PluginManager;
|
||||
import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent;
|
||||
import org.briarproject.bramble.api.plugin.event.TransportStateEvent;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
@@ -26,6 +27,7 @@ import org.briarproject.briar.android.fragment.BaseFragment;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
||||
import org.briarproject.briar.android.keyagreement.IntroFragment.IntroScreenSeenListener;
|
||||
import org.briarproject.briar.android.keyagreement.KeyAgreementFragment.KeyAgreementEventListener;
|
||||
import org.briarproject.briar.android.util.UiUtils;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -45,7 +47,6 @@ import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
|
||||
import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED;
|
||||
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||
@@ -55,7 +56,6 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
|
||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH_DISCOVERABLE;
|
||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA_LOCATION;
|
||||
import static org.briarproject.briar.android.util.UiUtils.getGoToSettingsListener;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
@@ -118,6 +118,13 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
*/
|
||||
private boolean continueClicked = false;
|
||||
|
||||
/**
|
||||
* Records whether the Bluetooth adapter was already enabled before we
|
||||
* asked for Bluetooth discoverability, so we know whether to broadcast a
|
||||
* {@link BluetoothEnabledEvent}.
|
||||
*/
|
||||
private boolean wasAdapterEnabled = false;
|
||||
|
||||
/**
|
||||
* Records whether we've enabled the wifi plugin so we don't enable it more
|
||||
* than once.
|
||||
@@ -134,8 +141,6 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
private Permission locationPermission = Permission.UNKNOWN;
|
||||
private BluetoothDecision bluetoothDecision = BluetoothDecision.UNKNOWN;
|
||||
private BroadcastReceiver bluetoothReceiver = null;
|
||||
private Plugin wifiPlugin = null, bluetoothPlugin = null;
|
||||
private BluetoothAdapter bt = null;
|
||||
|
||||
@Override
|
||||
public void injectActivity(ActivityComponent component) {
|
||||
@@ -155,9 +160,6 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
IntentFilter filter = new IntentFilter(ACTION_SCAN_MODE_CHANGED);
|
||||
bluetoothReceiver = new BluetoothStateReceiver();
|
||||
registerReceiver(bluetoothReceiver, filter);
|
||||
wifiPlugin = pluginManager.getPlugin(LanTcpConstants.ID);
|
||||
bluetoothPlugin = pluginManager.getPlugin(BluetoothConstants.ID);
|
||||
bt = BluetoothAdapter.getDefaultAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -193,7 +195,6 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
showQrCodeFragmentIfAllowed();
|
||||
}
|
||||
|
||||
@SuppressWarnings("StatementWithEmptyBody")
|
||||
private void showQrCodeFragmentIfAllowed() {
|
||||
if (isResumed && continueClicked && areEssentialPermissionsGranted()) {
|
||||
if (isWifiReady() && isBluetoothReady()) {
|
||||
@@ -207,8 +208,6 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
}
|
||||
if (bluetoothDecision == BluetoothDecision.UNKNOWN) {
|
||||
requestBluetoothDiscoverable();
|
||||
} else if (bluetoothDecision == BluetoothDecision.REFUSED) {
|
||||
// Ask again when the user clicks "continue"
|
||||
} else if (shouldEnableBluetooth()) {
|
||||
LOG.info("Enabling Bluetooth plugin");
|
||||
hasEnabledBluetooth = true;
|
||||
@@ -219,50 +218,55 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
}
|
||||
|
||||
private boolean areEssentialPermissionsGranted() {
|
||||
// If the camera permission has been granted, and the location
|
||||
// permission has been granted or permanently denied, we can continue
|
||||
return cameraPermission == Permission.GRANTED &&
|
||||
(SDK_INT < 23 || locationPermission == Permission.GRANTED ||
|
||||
!isBluetoothSupported());
|
||||
}
|
||||
|
||||
private boolean isBluetoothSupported() {
|
||||
return bt != null && bluetoothPlugin != null;
|
||||
(locationPermission == Permission.GRANTED ||
|
||||
locationPermission == Permission.PERMANENTLY_DENIED);
|
||||
}
|
||||
|
||||
private boolean isWifiReady() {
|
||||
if (wifiPlugin == null) return true; // Continue without wifi
|
||||
State state = wifiPlugin.getState();
|
||||
Plugin p = pluginManager.getPlugin(LanTcpConstants.ID);
|
||||
if (p == null) return true; // Continue without wifi
|
||||
State state = p.getState();
|
||||
// Wait for plugin to become enabled
|
||||
return state == ACTIVE || state == INACTIVE;
|
||||
}
|
||||
|
||||
private boolean isBluetoothReady() {
|
||||
if (!isBluetoothSupported()) {
|
||||
if (bluetoothDecision == BluetoothDecision.UNKNOWN ||
|
||||
bluetoothDecision == BluetoothDecision.WAITING) {
|
||||
// Wait for decision
|
||||
return false;
|
||||
}
|
||||
if (bluetoothDecision == BluetoothDecision.NO_ADAPTER
|
||||
|| bluetoothDecision == BluetoothDecision.REFUSED) {
|
||||
// Continue without Bluetooth
|
||||
return true;
|
||||
}
|
||||
if (bluetoothDecision == BluetoothDecision.UNKNOWN ||
|
||||
bluetoothDecision == BluetoothDecision.WAITING ||
|
||||
bluetoothDecision == BluetoothDecision.REFUSED) {
|
||||
// Wait for user to accept
|
||||
return false;
|
||||
}
|
||||
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
||||
if (bt == null) return true; // Continue without Bluetooth
|
||||
if (bt.getScanMode() != SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
|
||||
// Wait for adapter to become discoverable
|
||||
return false;
|
||||
}
|
||||
Plugin p = pluginManager.getPlugin(BluetoothConstants.ID);
|
||||
if (p == null) return true; // Continue without Bluetooth
|
||||
// Wait for plugin to become active
|
||||
return bluetoothPlugin.getState() == ACTIVE;
|
||||
return p.getState() == ACTIVE;
|
||||
}
|
||||
|
||||
private boolean shouldEnableWifi() {
|
||||
if (hasEnabledWifi) return false;
|
||||
if (wifiPlugin == null) return false;
|
||||
State state = wifiPlugin.getState();
|
||||
Plugin p = pluginManager.getPlugin(LanTcpConstants.ID);
|
||||
if (p == null) return false;
|
||||
State state = p.getState();
|
||||
return state == STARTING_STOPPING || state == DISABLED;
|
||||
}
|
||||
|
||||
private void requestBluetoothDiscoverable() {
|
||||
if (!isBluetoothSupported()) {
|
||||
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
||||
if (bt == null) {
|
||||
bluetoothDecision = BluetoothDecision.NO_ADAPTER;
|
||||
showQrCodeFragmentIfAllowed();
|
||||
} else {
|
||||
@@ -270,6 +274,7 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
if (i.resolveActivity(getPackageManager()) != null) {
|
||||
LOG.info("Asking for Bluetooth discoverability");
|
||||
bluetoothDecision = BluetoothDecision.WAITING;
|
||||
wasAdapterEnabled = bt.isEnabled();
|
||||
startActivityForResult(i, REQUEST_BLUETOOTH_DISCOVERABLE);
|
||||
} else {
|
||||
bluetoothDecision = BluetoothDecision.NO_ADAPTER;
|
||||
@@ -281,8 +286,9 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
private boolean shouldEnableBluetooth() {
|
||||
if (bluetoothDecision != BluetoothDecision.ACCEPTED) return false;
|
||||
if (hasEnabledBluetooth) return false;
|
||||
if (!isBluetoothSupported()) return false;
|
||||
State state = bluetoothPlugin.getState();
|
||||
Plugin p = pluginManager.getPlugin(BluetoothConstants.ID);
|
||||
if (p == null) return false;
|
||||
State state = p.getState();
|
||||
return state == STARTING_STOPPING || state == DISABLED;
|
||||
}
|
||||
|
||||
@@ -301,9 +307,6 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
@Override
|
||||
public void showNextScreen() {
|
||||
continueClicked = true;
|
||||
if (bluetoothDecision == BluetoothDecision.REFUSED) {
|
||||
bluetoothDecision = BluetoothDecision.UNKNOWN; // Ask again
|
||||
}
|
||||
if (checkPermissions()) showQrCodeFragmentIfAllowed();
|
||||
}
|
||||
|
||||
@@ -317,6 +320,11 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
} else {
|
||||
LOG.info("Bluetooth discoverability was accepted");
|
||||
bluetoothDecision = BluetoothDecision.ACCEPTED;
|
||||
if (!wasAdapterEnabled) {
|
||||
LOG.info("Bluetooth adapter was enabled by us");
|
||||
eventBus.broadcast(new BluetoothEnabledEvent());
|
||||
wasAdapterEnabled = true;
|
||||
}
|
||||
}
|
||||
showQrCodeFragmentIfAllowed();
|
||||
} else super.onActivityResult(request, result, data);
|
||||
@@ -347,17 +355,17 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
|
||||
private boolean checkPermissions() {
|
||||
if (areEssentialPermissionsGranted()) return true;
|
||||
// If an essential permission has been permanently denied, ask the
|
||||
// If the camera permission has been permanently denied, ask the
|
||||
// user to change the setting
|
||||
if (cameraPermission == Permission.PERMANENTLY_DENIED) {
|
||||
showDenialDialog(R.string.permission_camera_title,
|
||||
R.string.permission_camera_denied_body);
|
||||
return false;
|
||||
}
|
||||
if (isBluetoothSupported() &&
|
||||
locationPermission == Permission.PERMANENTLY_DENIED) {
|
||||
showDenialDialog(R.string.permission_location_title,
|
||||
R.string.permission_location_denied_body);
|
||||
Builder builder = new Builder(this, R.style.BriarDialogTheme);
|
||||
builder.setTitle(R.string.permission_camera_title);
|
||||
builder.setMessage(R.string.permission_camera_denied_body);
|
||||
builder.setPositiveButton(R.string.ok,
|
||||
UiUtils.getGoToSettingsListener(this));
|
||||
builder.setNegativeButton(R.string.cancel,
|
||||
(dialog, which) -> supportFinishAfterTransition());
|
||||
builder.show();
|
||||
return false;
|
||||
}
|
||||
// Should we show the rationale for one or both permissions?
|
||||
@@ -377,16 +385,6 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
return false;
|
||||
}
|
||||
|
||||
private void showDenialDialog(@StringRes int title, @StringRes int body) {
|
||||
Builder builder = new Builder(this, R.style.BriarDialogTheme);
|
||||
builder.setTitle(title);
|
||||
builder.setMessage(body);
|
||||
builder.setPositiveButton(R.string.ok, getGoToSettingsListener(this));
|
||||
builder.setNegativeButton(R.string.cancel,
|
||||
(dialog, which) -> supportFinishAfterTransition());
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void showRationale(@StringRes int title, @StringRes int body) {
|
||||
Builder builder = new Builder(this, R.style.BriarDialogTheme);
|
||||
builder.setTitle(title);
|
||||
@@ -397,13 +395,8 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
}
|
||||
|
||||
private void requestPermissions() {
|
||||
String[] permissions;
|
||||
if (isBluetoothSupported()) {
|
||||
permissions = new String[] {CAMERA, ACCESS_FINE_LOCATION};
|
||||
} else {
|
||||
permissions = new String[] {CAMERA};
|
||||
}
|
||||
ActivityCompat.requestPermissions(this, permissions,
|
||||
ActivityCompat.requestPermissions(this,
|
||||
new String[] {CAMERA, ACCESS_FINE_LOCATION},
|
||||
REQUEST_PERMISSION_CAMERA_LOCATION);
|
||||
}
|
||||
|
||||
@@ -420,15 +413,12 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||
} else {
|
||||
cameraPermission = Permission.PERMANENTLY_DENIED;
|
||||
}
|
||||
if (isBluetoothSupported()) {
|
||||
if (gotPermission(ACCESS_FINE_LOCATION, permissions,
|
||||
grantResults)) {
|
||||
locationPermission = Permission.GRANTED;
|
||||
} else if (shouldShowRationale(ACCESS_FINE_LOCATION)) {
|
||||
locationPermission = Permission.SHOW_RATIONALE;
|
||||
} else {
|
||||
locationPermission = Permission.PERMANENTLY_DENIED;
|
||||
}
|
||||
if (gotPermission(ACCESS_FINE_LOCATION, permissions, grantResults)) {
|
||||
locationPermission = Permission.GRANTED;
|
||||
} else if (shouldShowRationale(ACCESS_FINE_LOCATION)) {
|
||||
locationPermission = Permission.SHOW_RATIONALE;
|
||||
} else {
|
||||
locationPermission = Permission.PERMANENTLY_DENIED;
|
||||
}
|
||||
// If a permission dialog has been shown, showing the QR code fragment
|
||||
// on this call path would cause a crash due to
|
||||
|
||||
@@ -11,7 +11,6 @@ import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
@@ -57,10 +56,8 @@ import androidx.core.content.ContextCompat;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
@@ -78,8 +75,6 @@ import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
|
||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD;
|
||||
import static org.briarproject.briar.android.navdrawer.IntentRouter.handleExternalIntent;
|
||||
import static org.briarproject.briar.android.util.UiUtils.getDaysUntilExpiry;
|
||||
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
|
||||
import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
@@ -102,9 +97,6 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
public static Uri SIGN_OUT_URI =
|
||||
Uri.parse("briar-content://org.briarproject.briar/sign-out");
|
||||
|
||||
private final List<Transport> transports = new ArrayList<>(3);
|
||||
private final MutableLiveData<ImageView> torIcon = new MutableLiveData<>();
|
||||
|
||||
private NavDrawerViewModel navDrawerViewModel;
|
||||
private PluginViewModel pluginViewModel;
|
||||
private ActionBarDrawerToggle drawerToggle;
|
||||
@@ -118,6 +110,7 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
private DrawerLayout drawerLayout;
|
||||
private NavigationView navigation;
|
||||
|
||||
private List<Transport> transports;
|
||||
private BaseAdapter transportsAdapter;
|
||||
|
||||
@Override
|
||||
@@ -148,11 +141,6 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
drawerLayout = findViewById(R.id.drawer_layout);
|
||||
navigation = findViewById(R.id.navigation);
|
||||
GridView transportsView = findViewById(R.id.transportsView);
|
||||
LinearLayout transportsLayout = findViewById(R.id.transports);
|
||||
transportsLayout.setOnClickListener(v -> {
|
||||
LOG.info("Starting transports activity");
|
||||
startActivity(new Intent(this, TransportsActivity.class));
|
||||
});
|
||||
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar actionBar = requireNonNull(getSupportActionBar());
|
||||
@@ -161,23 +149,13 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
|
||||
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
|
||||
R.string.nav_drawer_open_description,
|
||||
R.string.nav_drawer_close_description) {
|
||||
@Override
|
||||
public void onDrawerOpened(View drawerView) {
|
||||
super.onDrawerOpened(drawerView);
|
||||
navDrawerViewModel.checkTransportsOnboarding();
|
||||
}
|
||||
};
|
||||
R.string.nav_drawer_close_description);
|
||||
drawerLayout.addDrawerListener(drawerToggle);
|
||||
navigation.setNavigationItemSelectedListener(this);
|
||||
|
||||
initializeTransports();
|
||||
transportsView.setAdapter(transportsAdapter);
|
||||
|
||||
observeOnce(navDrawerViewModel.showTransportsOnboarding(), this, show ->
|
||||
observeOnce(torIcon, this, imageView ->
|
||||
showTransportsOnboarding(show, imageView)));
|
||||
|
||||
lockManager.isLockable().observe(this, this::setLockVisible);
|
||||
|
||||
if (lifecycleManager.getLifecycleState().isAfter(RUNNING)) {
|
||||
@@ -402,6 +380,8 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
}
|
||||
|
||||
private void initializeTransports() {
|
||||
transports = new ArrayList<>(3);
|
||||
|
||||
transportsAdapter = new BaseAdapter() {
|
||||
|
||||
@Override
|
||||
@@ -442,8 +422,6 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
TextView text = view.findViewById(R.id.textView);
|
||||
text.setText(getString(t.label));
|
||||
|
||||
if (t.id.equals(TorConstants.ID)) torIcon.setValue(icon);
|
||||
|
||||
return view;
|
||||
}
|
||||
};
|
||||
@@ -466,7 +444,7 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
private Transport createTransport(TransportId id,
|
||||
@DrawableRes int iconDrawable, @StringRes int label) {
|
||||
int iconColor = getIconColor(STARTING_STOPPING);
|
||||
Transport transport = new Transport(id, iconDrawable, label, iconColor);
|
||||
Transport transport = new Transport(iconDrawable, label, iconColor);
|
||||
pluginViewModel.getPluginState(id).observe(this, state -> {
|
||||
transport.iconColor = getIconColor(state);
|
||||
transportsAdapter.notifyDataSetChanged();
|
||||
@@ -474,25 +452,8 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
return transport;
|
||||
}
|
||||
|
||||
private void showTransportsOnboarding(boolean show, ImageView imageView) {
|
||||
if (show) {
|
||||
int color = resolveColorAttribute(this, R.attr.colorControlNormal);
|
||||
new MaterialTapTargetPrompt.Builder(NavDrawerActivity.this,
|
||||
R.style.OnboardingDialogTheme).setTarget(imageView)
|
||||
.setPrimaryText(R.string.network_settings_title)
|
||||
.setSecondaryText(R.string.transports_onboarding_text)
|
||||
.setIcon(R.drawable.transport_tor)
|
||||
.setIconDrawableColourFilter(color)
|
||||
.setBackgroundColour(
|
||||
ContextCompat.getColor(this, R.color.briar_primary))
|
||||
.show();
|
||||
navDrawerViewModel.transportsOnboardingShown();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Transport {
|
||||
|
||||
private final TransportId id;
|
||||
@DrawableRes
|
||||
private final int iconDrawable;
|
||||
@StringRes
|
||||
@@ -501,9 +462,8 @@ public class NavDrawerActivity extends BriarActivity implements
|
||||
@ColorRes
|
||||
private int iconColor;
|
||||
|
||||
private Transport(TransportId id, @DrawableRes int iconDrawable,
|
||||
@StringRes int label, @ColorRes int iconColor) {
|
||||
this.id = id;
|
||||
private Transport(@DrawableRes int iconDrawable, @StringRes int label,
|
||||
@ColorRes int iconColor) {
|
||||
this.iconDrawable = iconDrawable;
|
||||
this.label = label;
|
||||
this.iconColor = iconColor;
|
||||
|
||||
@@ -34,8 +34,6 @@ public class NavDrawerViewModel extends AndroidViewModel {
|
||||
getLogger(NavDrawerViewModel.class.getName());
|
||||
|
||||
private static final String EXPIRY_DATE_WARNING = "expiryDateWarning";
|
||||
private static final String SHOW_TRANSPORTS_ONBOARDING =
|
||||
"showTransportsOnboarding";
|
||||
|
||||
@DatabaseExecutor
|
||||
private final Executor dbExecutor;
|
||||
@@ -45,8 +43,6 @@ public class NavDrawerViewModel extends AndroidViewModel {
|
||||
new MutableLiveData<>();
|
||||
private final MutableLiveData<Boolean> shouldAskForDozeWhitelisting =
|
||||
new MutableLiveData<>();
|
||||
private final MutableLiveData<Boolean> showTransportsOnboarding =
|
||||
new MutableLiveData<>();
|
||||
|
||||
@Inject
|
||||
NavDrawerViewModel(Application app, @DatabaseExecutor Executor dbExecutor,
|
||||
@@ -132,39 +128,4 @@ public class NavDrawerViewModel extends AndroidViewModel {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@UiThread
|
||||
LiveData<Boolean> showTransportsOnboarding() {
|
||||
return showTransportsOnboarding;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void checkTransportsOnboarding() {
|
||||
if (showTransportsOnboarding.getValue() != null) return;
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
Settings settings =
|
||||
settingsManager.getSettings(SETTINGS_NAMESPACE);
|
||||
boolean show =
|
||||
settings.getBoolean(SHOW_TRANSPORTS_ONBOARDING, true);
|
||||
showTransportsOnboarding.postValue(show);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void transportsOnboardingShown() {
|
||||
showTransportsOnboarding.setValue(false);
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
Settings settings = new Settings();
|
||||
settings.putBoolean(SHOW_TRANSPORTS_ONBOARDING, false);
|
||||
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,8 @@
|
||||
package org.briarproject.briar.android.navdrawer;
|
||||
|
||||
import android.app.Application;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
import org.briarproject.bramble.api.network.NetworkManager;
|
||||
import org.briarproject.bramble.api.network.NetworkStatus;
|
||||
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
||||
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
||||
@@ -24,44 +12,28 @@ import org.briarproject.bramble.api.plugin.PluginManager;
|
||||
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.plugin.event.TransportStateEvent;
|
||||
import org.briarproject.bramble.api.settings.Settings;
|
||||
import org.briarproject.bramble.api.settings.SettingsManager;
|
||||
import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED;
|
||||
import static android.bluetooth.BluetoothAdapter.EXTRA_STATE;
|
||||
import static android.bluetooth.BluetoothAdapter.STATE_ON;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.PREF_PLUGIN_ENABLE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
|
||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.LogUtils.now;
|
||||
|
||||
@NotNullByDefault
|
||||
public class PluginViewModel extends AndroidViewModel implements EventListener {
|
||||
public class PluginViewModel extends ViewModel implements EventListener {
|
||||
|
||||
private static final Logger LOG =
|
||||
getLogger(PluginViewModel.class.getName());
|
||||
|
||||
private final Application app;
|
||||
private final Executor dbExecutor;
|
||||
private final SettingsManager settingsManager;
|
||||
private final PluginManager pluginManager;
|
||||
private final EventBus eventBus;
|
||||
private final BroadcastReceiver receiver;
|
||||
|
||||
private final MutableLiveData<State> torPluginState =
|
||||
new MutableLiveData<>();
|
||||
@@ -70,68 +42,24 @@ public class PluginViewModel extends AndroidViewModel implements EventListener {
|
||||
private final MutableLiveData<State> btPluginState =
|
||||
new MutableLiveData<>();
|
||||
|
||||
private final MutableLiveData<Boolean> torEnabledSetting =
|
||||
new MutableLiveData<>(false);
|
||||
private final MutableLiveData<Boolean> wifiEnabledSetting =
|
||||
new MutableLiveData<>(false);
|
||||
private final MutableLiveData<Boolean> btEnabledSetting =
|
||||
new MutableLiveData<>(false);
|
||||
|
||||
private final MutableLiveData<NetworkStatus> networkStatus =
|
||||
new MutableLiveData<>();
|
||||
|
||||
private final MutableLiveData<Boolean> bluetoothTurnedOn =
|
||||
new MutableLiveData<>(false);
|
||||
|
||||
@Inject
|
||||
PluginViewModel(Application app, @DatabaseExecutor Executor dbExecutor,
|
||||
SettingsManager settingsManager, PluginManager pluginManager,
|
||||
EventBus eventBus, NetworkManager networkManager) {
|
||||
super(app);
|
||||
this.app = app;
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.settingsManager = settingsManager;
|
||||
PluginViewModel(PluginManager pluginManager, EventBus eventBus) {
|
||||
this.pluginManager = pluginManager;
|
||||
this.eventBus = eventBus;
|
||||
eventBus.addListener(this);
|
||||
receiver = new BluetoothStateReceiver();
|
||||
app.registerReceiver(receiver, new IntentFilter(ACTION_STATE_CHANGED));
|
||||
networkStatus.setValue(networkManager.getNetworkStatus());
|
||||
torPluginState.setValue(getTransportState(TorConstants.ID));
|
||||
wifiPluginState.setValue(getTransportState(LanTcpConstants.ID));
|
||||
btPluginState.setValue(getTransportState(BluetoothConstants.ID));
|
||||
initialiseBluetoothState();
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
eventBus.removeListener(this);
|
||||
app.unregisterReceiver(receiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof NetworkStatusEvent) {
|
||||
networkStatus.setValue(((NetworkStatusEvent) e).getStatus());
|
||||
} else if (e instanceof SettingsUpdatedEvent) {
|
||||
SettingsUpdatedEvent s = (SettingsUpdatedEvent) e;
|
||||
if (s.getNamespace().equals(TorConstants.ID.getString())) {
|
||||
boolean enable = s.getSettings().getBoolean(PREF_PLUGIN_ENABLE,
|
||||
TorConstants.DEFAULT_PREF_PLUGIN_ENABLE);
|
||||
torEnabledSetting.setValue(enable);
|
||||
} else if (s.getNamespace().equals(
|
||||
LanTcpConstants.ID.getString())) {
|
||||
boolean enable = s.getSettings().getBoolean(PREF_PLUGIN_ENABLE,
|
||||
LanTcpConstants.DEFAULT_PREF_PLUGIN_ENABLE);
|
||||
wifiEnabledSetting.setValue(enable);
|
||||
} else if (s.getNamespace().equals(
|
||||
BluetoothConstants.ID.getString())) {
|
||||
boolean enable = s.getSettings().getBoolean(PREF_PLUGIN_ENABLE,
|
||||
BluetoothConstants.DEFAULT_PREF_PLUGIN_ENABLE);
|
||||
btEnabledSetting.setValue(enable);
|
||||
}
|
||||
} else if (e instanceof TransportStateEvent) {
|
||||
if (e instanceof TransportStateEvent) {
|
||||
TransportStateEvent t = (TransportStateEvent) e;
|
||||
TransportId id = t.getTransportId();
|
||||
State state = t.getState();
|
||||
@@ -149,62 +77,6 @@ public class PluginViewModel extends AndroidViewModel implements EventListener {
|
||||
return liveData;
|
||||
}
|
||||
|
||||
LiveData<Boolean> getPluginEnabledSetting(TransportId id) {
|
||||
if (id.equals(TorConstants.ID)) return torEnabledSetting;
|
||||
else if (id.equals(LanTcpConstants.ID)) return wifiEnabledSetting;
|
||||
else if (id.equals(BluetoothConstants.ID)) return btEnabledSetting;
|
||||
else throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
LiveData<NetworkStatus> getNetworkStatus() {
|
||||
return networkStatus;
|
||||
}
|
||||
|
||||
LiveData<Boolean> getBluetoothTurnedOn() {
|
||||
return bluetoothTurnedOn;
|
||||
}
|
||||
|
||||
int getReasonsTorDisabled() {
|
||||
Plugin plugin = pluginManager.getPlugin(TorConstants.ID);
|
||||
return plugin == null ? 0 : plugin.getReasonsDisabled();
|
||||
}
|
||||
|
||||
void enableTransport(TransportId id, boolean enable) {
|
||||
Settings s = new Settings();
|
||||
s.putBoolean(PREF_PLUGIN_ENABLE, enable);
|
||||
mergeSettings(s, id.getString());
|
||||
}
|
||||
|
||||
private void initialiseBluetoothState() {
|
||||
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
||||
if (bt == null) bluetoothTurnedOn.setValue(false);
|
||||
else bluetoothTurnedOn.setValue(bt.getState() == STATE_ON);
|
||||
}
|
||||
|
||||
private void loadSettings() {
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
boolean tor = isPluginEnabled(TorConstants.ID,
|
||||
TorConstants.DEFAULT_PREF_PLUGIN_ENABLE);
|
||||
torEnabledSetting.postValue(tor);
|
||||
boolean wifi = isPluginEnabled(LanTcpConstants.ID,
|
||||
LanTcpConstants.DEFAULT_PREF_PLUGIN_ENABLE);
|
||||
wifiEnabledSetting.postValue(wifi);
|
||||
boolean bt = isPluginEnabled(BluetoothConstants.ID,
|
||||
BluetoothConstants.DEFAULT_PREF_PLUGIN_ENABLE);
|
||||
btEnabledSetting.postValue(bt);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isPluginEnabled(TransportId id, boolean defaultValue)
|
||||
throws DbException {
|
||||
Settings s = settingsManager.getSettings(id.getString());
|
||||
return s.getBoolean(PREF_PLUGIN_ENABLE, defaultValue);
|
||||
}
|
||||
|
||||
private State getTransportState(TransportId id) {
|
||||
Plugin plugin = pluginManager.getPlugin(id);
|
||||
return plugin == null ? STARTING_STOPPING : plugin.getState();
|
||||
@@ -217,26 +89,4 @@ public class PluginViewModel extends AndroidViewModel implements EventListener {
|
||||
else if (id.equals(BluetoothConstants.ID)) return btPluginState;
|
||||
else return null;
|
||||
}
|
||||
|
||||
private void mergeSettings(Settings s, String namespace) {
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
long start = now();
|
||||
settingsManager.mergeSettings(s, namespace);
|
||||
logDuration(LOG, "Merging settings", start);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class BluetoothStateReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
int state = intent.getIntExtra(EXTRA_STATE, 0);
|
||||
if (state == STATE_ON) bluetoothTurnedOn.postValue(true);
|
||||
else bluetoothTurnedOn.postValue(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,360 +0,0 @@
|
||||
package org.briarproject.briar.android.navdrawer;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.briarproject.bramble.api.network.NetworkStatus;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
||||
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
||||
import org.briarproject.bramble.api.plugin.Plugin.State;
|
||||
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.activity.BriarActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.ColorRes;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_BATTERY;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_COUNTRY_BLOCKED;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_MOBILE_DATA;
|
||||
import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class TransportsActivity extends BriarActivity {
|
||||
|
||||
@Inject
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
private final List<Transport> transports = new ArrayList<>(3);
|
||||
|
||||
private PluginViewModel viewModel;
|
||||
private BaseAdapter transportsAdapter;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle state) {
|
||||
super.onCreate(state);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setHomeButtonEnabled(true);
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
setContentView(R.layout.activity_transports);
|
||||
|
||||
ViewModelProvider provider =
|
||||
ViewModelProviders.of(this, viewModelFactory);
|
||||
viewModel = provider.get(PluginViewModel.class);
|
||||
|
||||
GridView grid = findViewById(R.id.grid);
|
||||
initializeCards();
|
||||
grid.setAdapter(transportsAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectActivity(ActivityComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_help) {
|
||||
String text = getString(R.string.transports_help_text);
|
||||
showOnboardingDialog(this, text);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.help_action, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
private void initializeCards() {
|
||||
transportsAdapter = new BaseAdapter() {
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return transports.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport getItem(int position) {
|
||||
return transports.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView,
|
||||
ViewGroup parent) {
|
||||
View view;
|
||||
if (convertView != null) {
|
||||
view = convertView;
|
||||
} else {
|
||||
LayoutInflater inflater = getLayoutInflater();
|
||||
view = inflater.inflate(R.layout.list_item_transport_card,
|
||||
parent, false);
|
||||
}
|
||||
|
||||
Transport t = getItem(position);
|
||||
|
||||
ImageView icon = view.findViewById(R.id.icon);
|
||||
icon.setImageDrawable(ContextCompat.getDrawable(
|
||||
TransportsActivity.this, t.iconDrawable));
|
||||
icon.setColorFilter(ContextCompat.getColor(
|
||||
TransportsActivity.this, t.iconColor));
|
||||
|
||||
TextView title = view.findViewById(R.id.title);
|
||||
title.setText(getString(t.title));
|
||||
|
||||
SwitchCompat switchCompat =
|
||||
view.findViewById(R.id.switchCompat);
|
||||
switchCompat.setText(getString(t.switchLabel));
|
||||
switchCompat.setOnClickListener(v ->
|
||||
viewModel.enableTransport(t.id,
|
||||
switchCompat.isChecked()));
|
||||
switchCompat.setChecked(t.isSwitchChecked);
|
||||
|
||||
TextView summary = view.findViewById(R.id.summary);
|
||||
if (t.summary == 0) {
|
||||
summary.setVisibility(GONE);
|
||||
} else {
|
||||
summary.setText(t.summary);
|
||||
summary.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
TextView deviceStatus = view.findViewById(R.id.deviceStatus);
|
||||
deviceStatus.setText(getBulletString(t.deviceStatus));
|
||||
|
||||
TextView pluginStatus = view.findViewById(R.id.appStatus);
|
||||
pluginStatus.setText(getBulletString(t.pluginStatus));
|
||||
pluginStatus.setVisibility(t.showPluginStatus ? VISIBLE : GONE);
|
||||
|
||||
return view;
|
||||
}
|
||||
};
|
||||
|
||||
Transport tor = createTransport(TorConstants.ID,
|
||||
R.drawable.transport_tor, R.string.transport_tor,
|
||||
R.string.tor_enable_title, R.string.tor_enable_summary,
|
||||
R.string.tor_device_status_offline,
|
||||
R.string.tor_plugin_status_inactive);
|
||||
transports.add(tor);
|
||||
|
||||
Transport wifi = createTransport(LanTcpConstants.ID,
|
||||
R.drawable.transport_lan, R.string.transport_lan_long,
|
||||
R.string.wifi_setting, 0, R.string.lan_device_status_off,
|
||||
R.string.lan_plugin_status_inactive);
|
||||
transports.add(wifi);
|
||||
|
||||
Transport bt = createTransport(BluetoothConstants.ID,
|
||||
R.drawable.transport_bt, R.string.transport_bt,
|
||||
R.string.bluetooth_setting, 0, R.string.bt_device_status_off,
|
||||
R.string.bt_plugin_status_inactive);
|
||||
transports.add(bt);
|
||||
|
||||
viewModel.getNetworkStatus().observe(this, status -> {
|
||||
updateTorResources(tor, status);
|
||||
updateWifiResources(wifi, status);
|
||||
transportsAdapter.notifyDataSetChanged();
|
||||
});
|
||||
|
||||
viewModel.getBluetoothTurnedOn().observe(this, on -> {
|
||||
updateBtResources(bt, on);
|
||||
transportsAdapter.notifyDataSetChanged();
|
||||
});
|
||||
}
|
||||
|
||||
private String getBulletString(@StringRes int resId) {
|
||||
return "\u2022 " + getString(resId);
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
private int getIconColor(State state) {
|
||||
if (state == ACTIVE) return R.color.briar_lime_400;
|
||||
else if (state == ENABLING) return R.color.briar_orange_500;
|
||||
else return android.R.color.tertiary_text_light;
|
||||
}
|
||||
|
||||
private void updateTorResources(Transport tor, NetworkStatus status) {
|
||||
if (status.isConnected()) {
|
||||
if (status.isWifi()) {
|
||||
tor.deviceStatus = R.string.tor_device_status_online_wifi;
|
||||
} else {
|
||||
tor.deviceStatus = R.string.tor_device_status_online_mobile;
|
||||
}
|
||||
tor.showPluginStatus = true;
|
||||
} else {
|
||||
tor.deviceStatus = R.string.tor_device_status_offline;
|
||||
tor.showPluginStatus = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateWifiResources(Transport wifi, NetworkStatus status) {
|
||||
if (status.isWifi()) {
|
||||
wifi.deviceStatus = R.string.lan_device_status_on;
|
||||
wifi.showPluginStatus = true;
|
||||
} else {
|
||||
wifi.deviceStatus = R.string.lan_device_status_off;
|
||||
wifi.showPluginStatus = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBtResources(Transport bt, boolean on) {
|
||||
if (on) {
|
||||
bt.deviceStatus = R.string.bt_device_status_on;
|
||||
bt.showPluginStatus = true;
|
||||
} else {
|
||||
bt.deviceStatus = R.string.bt_device_status_off;
|
||||
bt.showPluginStatus = false;
|
||||
}
|
||||
}
|
||||
|
||||
@StringRes
|
||||
private int getPluginStatus(TransportId id, State state) {
|
||||
if (id.equals(TorConstants.ID)) {
|
||||
return getTorPluginStatus(state);
|
||||
} else if (id.equals(LanTcpConstants.ID)) {
|
||||
return getWifiPluginStatus(state);
|
||||
} else if (id.equals(BluetoothConstants.ID)) {
|
||||
return getBtPluginStatus(state);
|
||||
} else throw new AssertionError();
|
||||
}
|
||||
|
||||
@StringRes
|
||||
private int getTorPluginStatus(State state) {
|
||||
if (state == ENABLING) {
|
||||
return R.string.tor_plugin_status_enabling;
|
||||
} else if (state == ACTIVE) {
|
||||
return R.string.tor_plugin_status_active;
|
||||
} else if (state == DISABLED) {
|
||||
int reasons = viewModel.getReasonsTorDisabled();
|
||||
if ((reasons & REASON_MOBILE_DATA) != 0) {
|
||||
return R.string.tor_plugin_status_disabled_mobile_data;
|
||||
} else if ((reasons & REASON_BATTERY) != 0) {
|
||||
return R.string.tor_plugin_status_disabled_battery;
|
||||
} else if ((reasons & REASON_COUNTRY_BLOCKED) != 0) {
|
||||
return R.string.tor_plugin_status_disabled_country_blocked;
|
||||
} else {
|
||||
return R.string.tor_plugin_status_disabled;
|
||||
}
|
||||
} else {
|
||||
return R.string.tor_plugin_status_inactive;
|
||||
}
|
||||
}
|
||||
|
||||
@StringRes
|
||||
private int getWifiPluginStatus(State state) {
|
||||
if (state == ENABLING) return R.string.lan_plugin_status_enabling;
|
||||
else if (state == ACTIVE) return R.string.lan_plugin_status_active;
|
||||
else if (state == DISABLED) return R.string.lan_plugin_status_disabled;
|
||||
else return R.string.lan_plugin_status_inactive;
|
||||
}
|
||||
|
||||
@StringRes
|
||||
private int getBtPluginStatus(State state) {
|
||||
if (state == ENABLING) return R.string.bt_plugin_status_enabling;
|
||||
else if (state == ACTIVE) return R.string.bt_plugin_status_active;
|
||||
else if (state == DISABLED) return R.string.bt_plugin_status_disabled;
|
||||
else return R.string.bt_plugin_status_inactive;
|
||||
}
|
||||
|
||||
private Transport createTransport(TransportId id,
|
||||
@DrawableRes int iconDrawable, @StringRes int title,
|
||||
@StringRes int switchLabel, @StringRes int summary,
|
||||
@StringRes int deviceStatus, @StringRes int pluginStatus) {
|
||||
int iconColor = getIconColor(STARTING_STOPPING);
|
||||
Transport transport = new Transport(id, iconDrawable, iconColor, title,
|
||||
switchLabel, false, summary, deviceStatus, pluginStatus, false);
|
||||
viewModel.getPluginState(id).observe(this, state -> {
|
||||
transport.iconColor = getIconColor(state);
|
||||
transport.pluginStatus = getPluginStatus(transport.id, state);
|
||||
transportsAdapter.notifyDataSetChanged();
|
||||
});
|
||||
viewModel.getPluginEnabledSetting(id).observe(this, enabled -> {
|
||||
transport.isSwitchChecked = enabled;
|
||||
transportsAdapter.notifyDataSetChanged();
|
||||
});
|
||||
return transport;
|
||||
}
|
||||
|
||||
private static class Transport {
|
||||
|
||||
private final TransportId id;
|
||||
|
||||
@DrawableRes
|
||||
private final int iconDrawable;
|
||||
@StringRes
|
||||
private final int title, switchLabel, summary;
|
||||
|
||||
@ColorRes
|
||||
private int iconColor;
|
||||
@StringRes
|
||||
private int deviceStatus, pluginStatus;
|
||||
private boolean isSwitchChecked, showPluginStatus;
|
||||
|
||||
private Transport(TransportId id,
|
||||
@DrawableRes int iconDrawable,
|
||||
@ColorRes int iconColor,
|
||||
@StringRes int title,
|
||||
@StringRes int switchLabel,
|
||||
boolean isSwitchChecked,
|
||||
@StringRes int summary,
|
||||
@StringRes int deviceStatus,
|
||||
@StringRes int pluginStatus,
|
||||
boolean showPluginStatus) {
|
||||
this.id = id;
|
||||
this.iconDrawable = iconDrawable;
|
||||
this.iconColor = iconColor;
|
||||
this.title = title;
|
||||
this.switchLabel = switchLabel;
|
||||
this.isSwitchChecked = isSwitchChecked;
|
||||
this.summary = summary;
|
||||
this.deviceStatus = deviceStatus;
|
||||
this.pluginStatus = pluginStatus;
|
||||
this.showPluginStatus = showPluginStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import org.briarproject.bramble.plugin.tor.CircumventionProvider;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.Localizer;
|
||||
import org.briarproject.briar.android.account.AccountUtils;
|
||||
import org.briarproject.briar.android.util.UiUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -251,9 +252,23 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
||||
throw new RuntimeException("Boom!");
|
||||
}
|
||||
);
|
||||
findPreference("pref_key_export").setOnPreferenceClickListener(
|
||||
preference -> {
|
||||
AccountUtils.exportAccount(requireContext());
|
||||
return true;
|
||||
}
|
||||
);
|
||||
findPreference("pref_key_import").setOnPreferenceClickListener(
|
||||
preference -> {
|
||||
AccountUtils.importAccount(requireContext());
|
||||
return true;
|
||||
}
|
||||
);
|
||||
} else {
|
||||
findPreference("pref_key_explode").setVisible(false);
|
||||
findPreference("pref_key_test_data").setVisible(false);
|
||||
findPreference("pref_key_export").setVisible(false);
|
||||
findPreference("pref_key_import").setVisible(false);
|
||||
PreferenceGroup testing =
|
||||
findPreference("pref_key_explode").getParent();
|
||||
if (testing == null) throw new AssertionError();
|
||||
|
||||
@@ -79,7 +79,7 @@ public class ImagePreview extends ConstraintLayout {
|
||||
((ImagePreviewAdapter) imageList.getAdapter());
|
||||
int pos = requireNonNull(adapter).loadItemPreview(result);
|
||||
if (pos != NO_POSITION) {
|
||||
imageList.scrollToPosition(pos);
|
||||
imageList.smoothScrollToPosition(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,22 +12,6 @@ import androidx.lifecycle.Observer;
|
||||
@NotNullByDefault
|
||||
public class LiveEvent<T> extends LiveData<LiveEvent.ConsumableEvent<T>> {
|
||||
|
||||
/**
|
||||
* Creates a LiveEvent initialized with the given {@code value}.
|
||||
*
|
||||
* @param value initial value
|
||||
*/
|
||||
public LiveEvent(T value) {
|
||||
super(new ConsumableEvent<>(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a LiveEvent with no value assigned to it.
|
||||
*/
|
||||
public LiveEvent() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void observeEvent(LifecycleOwner owner,
|
||||
LiveEventHandler<T> handler) {
|
||||
LiveEventObserver<T> observer = new LiveEventObserver<>(handler);
|
||||
|
||||
@@ -5,22 +5,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@NotNullByDefault
|
||||
public class MutableLiveEvent<T> extends LiveEvent<T> {
|
||||
|
||||
/**
|
||||
* Creates a MutableLiveEvent initialized with the given {@code value}.
|
||||
*
|
||||
* @param value initial value
|
||||
*/
|
||||
public MutableLiveEvent(T value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a MutableLiveEvent with no value assigned to it.
|
||||
*/
|
||||
public MutableLiveEvent() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void postEvent(T value) {
|
||||
super.postValue(new ConsumableEvent<>(value));
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package org.briarproject.briar.android.widget;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@NotNullByDefault
|
||||
public class TouchInterceptingLinearLayout extends LinearLayout {
|
||||
|
||||
public TouchInterceptingLinearLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public TouchInterceptingLinearLayout(Context context,
|
||||
@Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public TouchInterceptingLinearLayout(Context context,
|
||||
@Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@TargetApi(21)
|
||||
public TouchInterceptingLinearLayout(Context context, AttributeSet attrs,
|
||||
int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent e) {
|
||||
onTouchEvent(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="115dp"
|
||||
android:height="115dp"
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="115dp"
|
||||
android:height="115dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="#808080"
|
||||
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z"/>
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:numColumns="1"
|
||||
android:padding="6dp"
|
||||
android:verticalSpacing="12dp"
|
||||
tools:listitem="@layout/list_item_transport_card" />
|
||||
@@ -24,7 +24,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textIsSelectable="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/include_in_report"
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/BriarCard"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
tools:background="@drawable/transport_tor"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/text_size_large"
|
||||
tools:text="@string/transport_tor" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/switchCompat"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/text_size_medium"
|
||||
android:widgetLayout="@layout/preference_switch_compat"
|
||||
tools:checked="true"
|
||||
tools:text="@string/tor_enable_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginRight="32dp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:visibility="gone"
|
||||
tools:text="@string/tor_enable_summary"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/status_heading"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/deviceStatus"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:text="@string/tor_device_status_online_wifi" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appStatus"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:text="@string/tor_plugin_status_active" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
@@ -26,13 +26,21 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:menu="@menu/navigation_drawer" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider1"
|
||||
style="@style/Divider.Horizontal"
|
||||
android:layout_width="0dp"
|
||||
app:layout_constraintEnd_toEndOf="@+id/navigation"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/navigation" />
|
||||
|
||||
<View
|
||||
android:id="@+id/spacer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/transports"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/navigation"
|
||||
app:layout_constraintTop_toBottomOf="@+id/divider1"
|
||||
app:layout_constraintVertical_weight="1" />
|
||||
|
||||
<include
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.briarproject.briar.android.widget.TouchInterceptingLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:orientation="vertical"
|
||||
tools:showIn="@layout/navigation_menu">
|
||||
|
||||
@@ -17,4 +16,4 @@
|
||||
android:numColumns="3"
|
||||
tools:listitem="@layout/list_item_transport" />
|
||||
|
||||
</org.briarproject.briar.android.widget.TouchInterceptingLinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/nav_btn_settings"
|
||||
android:icon="@drawable/ic_settings_black"
|
||||
android:icon="@drawable/ic_settings_black_24dp"
|
||||
android:title="@string/settings_button"/>
|
||||
<item
|
||||
android:id="@+id/nav_btn_lock"
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
<!--Login-->
|
||||
<string name="enter_password">كلمة السّر</string>
|
||||
<string name="try_again">كلمة السرّ خاطئة, الرجاء المحاولة مجدّدا</string>
|
||||
<string name="dialog_title_cannot_check_password">لا يمكن التحقق من كلمة السر</string>
|
||||
<string name="dialog_message_cannot_check_password">Briar لم يتمكن من التحقق من كلمة المرور. الرجاء إعادة تشغيل جهازك من أجل جل المشكلة</string>
|
||||
<string name="sign_in_button">تسجيل الدخول</string>
|
||||
<string name="forgotten_password">نسيتُ كلمة السر</string>
|
||||
<string name="dialog_title_lost_password">فقدت كلمة السر</string>
|
||||
@@ -65,36 +63,10 @@
|
||||
<string name="lock_button">قفل التطبيق</string>
|
||||
<string name="settings_button">الإعدادات</string>
|
||||
<string name="sign_out_button">تسجيل الخروج</string>
|
||||
<string name="transports_onboarding_text">إلمس هنا من أجل التحكم بطريقةالربط مع جهات الاتصال.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">إنترنت</string>
|
||||
<string name="tor_device_status_online_wifi">جهازك لديه ولوج لشبكة الانترنت عبر ال Wi-Fi </string>
|
||||
<string name="tor_device_status_online_mobile">جهازك لديه ولوج لشبكة الانترنت عبر بيانات الهاتف</string>
|
||||
<string name="tor_device_status_offline">جهازك ليس متصل بالانترنت</string>
|
||||
<string name="tor_plugin_status_enabling">جاري اتصال Briar بالانترنت</string>
|
||||
<string name="tor_plugin_status_active">Briar متصل بالانترنت</string>
|
||||
<string name="tor_plugin_status_inactive">Briar لم يتمكن من الاتصال بالانترنت </string>
|
||||
<string name="tor_plugin_status_disabled">إعدادات Briar لاتسمح بالاتصال بالانترنت</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">إعدادات Briar لاتسمح بالاتصال عن طريق بيانات الهاتف</string>
|
||||
<string name="tor_plugin_status_disabled_battery">إعدادات Briar لاتسمح بالاتصال بالانترنت عند استخدام بطارية الهاتف</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">لايمكن استخدام Briar في هذا البلد</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">واي-فاي</string>
|
||||
<string name="transport_lan_long">نفس شبكة الWi-Fi </string>
|
||||
<string name="lan_device_status_on">جهازك متصل بشبكة الWi-Fi</string>
|
||||
<string name="lan_device_status_off">جهازك ليس متصل بشبكة الWi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">جاري ايصال Briar بشبكة الWi-Fi</string>
|
||||
<string name="lan_plugin_status_active"> Briar متصل بشبكة الWi-Fi</string>
|
||||
<string name="lan_plugin_status_inactive">لم يتمكن Briar من الاتصال بشبكة ال Wi-Fi</string>
|
||||
<string name="lan_plugin_status_disabled">إعدادات Briar لاتسمح بالاتصال بشبكة ال Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">بلوتوث</string>
|
||||
<string name="bt_device_status_on"> البلوتوث مفعّل </string>
|
||||
<string name="bt_device_status_off">البلوتوث مفعّل</string>
|
||||
<string name="bt_plugin_status_enabling">جاري اتصال Briar بالبلوتوث</string>
|
||||
<string name="bt_plugin_status_active">Briar متصل بالبلوتوث</string>
|
||||
<string name="bt_plugin_status_inactive">لم يتمكن Briar من الاتصال بالانترنت</string>
|
||||
<string name="bt_plugin_status_disabled">إعدادات Briar لاتسمح بالاتصال بالبلوتوث</string>
|
||||
<string name="transport_lan">واي-فاي</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">تم تسجيل الخروج من Briar (براير)</string>
|
||||
<string name="reminder_notification_text">الرجاء اللمس لإعادة الدخول</string>
|
||||
@@ -157,7 +129,6 @@
|
||||
<string name="help">مساعدة</string>
|
||||
<string name="sorry">معذرة</string>
|
||||
<string name="error_start_activity">غير متوفّر على نظامكم </string>
|
||||
<string name="status_heading">الحالة:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">لا جهات اتصال للعرض</string>
|
||||
<string name="no_contacts_action">لمس علامة + لإضافة جهة إتصال</string>
|
||||
@@ -215,6 +186,7 @@
|
||||
<string name="connecting_to_device">يتم الإتصال بالجهاز\u2026</string>
|
||||
<string name="authenticating_with_device">يتم التوثيق مع الجهاز\u2026</string>
|
||||
<string name="connection_error_title">لم يمكن الإتصال بجهة إتصالك</string>
|
||||
<string name="connection_error_explanation">رجاءًا التأكد أن كليكما متصل بنفس شبكة الواي فاي.</string>
|
||||
<string name="connection_error_feedback">إذا إستمرت المشكلة، رجاءًا <a href="feedback">أرسل تقرير </a> لمساعدتنا على تحسين التطبيق.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">إضافة جهة اتصال عن بعد </string>
|
||||
@@ -476,20 +448,10 @@
|
||||
<string name="pref_theme_auto">تلقائي (توقيت النهار)</string>
|
||||
<string name="pref_theme_system">النظام الافتراضي</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">شبكات الاتصال</string>
|
||||
<string name="bluetooth_setting">ربط جهات الاتصال عن طريق بلوتوث</string>
|
||||
<string name="wifi_setting">ربط جهات الاتصال عن طريق نفس شبكة الواي فاي</string>
|
||||
<string name="tor_enable_title">ربط شبكات الاتصال عن طريق الانترنت</string>
|
||||
<string name="tor_enable_summary">كل جهات الاتصال تمر عبر شبكة تور من أجل الخصوصية</string>
|
||||
<string name="tor_network_setting">وسيلة الاتصال لشبكة تور</string>
|
||||
<string name="tor_network_setting_automatic">تلقائيًا حسب الموقع</string>
|
||||
<string name="tor_network_setting_without_bridges">استخدام شبكة تور من دون جسور</string>
|
||||
<string name="tor_network_setting_with_bridges">استخدام شبكة تور مع جسور</string>
|
||||
<string name="tor_network_setting_never">لا يمكن الاتصال بالإنترنت</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">تلقائيا: %1$s (في %2$s)</string>
|
||||
<string name="tor_mobile_data_title">إستخدام بيانات الجوال</string>
|
||||
<string name="tor_only_when_charging_title">الاتصال بالإنترنت فقط عن الشحن</string>
|
||||
<string name="tor_only_when_charging_summary">تعطيل الاتصال بالانترنت عند تشغيل الجهاز على البطارية</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">الأمان</string>
|
||||
@@ -599,8 +561,6 @@
|
||||
<string name="lock_unlock_password">استخدام كلمة السر</string>
|
||||
<string name="lock_is_locked">Briar (براير) مقفل</string>
|
||||
<string name="lock_tap_to_unlock">الرجاء اللمس لفك القفل</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">يمكن ل Briar التواصل مع جهات الاتصال عن طريق الانترنت, شكبة ال Wi-Fi أو البلوتوث.n\n\كل وسائل الاتصال عن طريق الانترنت تمر عبر شبكة تور من أجل الخصوصية.n\n\إذا كان من الممكن الوصول إلى شبكة إتصال بعدة طرق فإن Briar سوف يستعملهم جميعاً بالتوازي.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">آليس</string>
|
||||
|
||||
@@ -59,12 +59,10 @@
|
||||
<string name="lock_button">Tətbiqetməni kilidlə</string>
|
||||
<string name="settings_button">Quraşdırmalar</string>
|
||||
<string name="sign_out_button">Çıxış</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Briar-dan çıxdı</string>
|
||||
<string name="reminder_notification_text">Daxil olmağınız üçün toxunun.</string>
|
||||
@@ -111,7 +109,6 @@
|
||||
<string name="help">Yardım</string>
|
||||
<string name="sorry">Bağışlayın</string>
|
||||
<string name="error_start_activity">Sizin sistemdə ələçatmazdır. </string>
|
||||
<string name="status_heading">Status:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Göstərmək üçün əlaqə yoxdur</string>
|
||||
<string name="no_contacts_action">Kontakt əlavə etmək üçün + işarəsinə toxunun</string>
|
||||
@@ -162,6 +159,7 @@
|
||||
<string name="connecting_to_device">Cihaza qoşulma /2026</string>
|
||||
<string name="authenticating_with_device">Cihazla təsdiqlənir \u2026</string>
|
||||
<string name="connection_error_title">Kontaktınıza qoşula bilmədi</string>
|
||||
<string name="connection_error_explanation">Həmin Wi-Fi şəbəkəsinə qoşulduğunuzu yoxlayın.</string>
|
||||
<string name="connection_error_feedback"><a href="feedback">Bu problem davam edərsə, tətbiqin təkmilləşdirilməsinə kömək etmək üçün rəy göndərin.</a></string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Məsafədə kontakt əlavə etmək </string>
|
||||
@@ -475,7 +473,6 @@
|
||||
<string name="lock_unlock_password">Şifrəni istifadə edin</string>
|
||||
<string name="lock_is_locked">Briar kilidləndi</string>
|
||||
<string name="lock_tap_to_unlock">Kilidi açmaq üçün toxunun</string>
|
||||
<!--Connections Screen-->
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alisa</string>
|
||||
|
||||
@@ -53,12 +53,10 @@
|
||||
<string name="lock_button">Zaključaj aplikaciju</string>
|
||||
<string name="settings_button">Podešavanja</string>
|
||||
<string name="sign_out_button">Odjava</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Odjavljeni ste iz Briara</string>
|
||||
<string name="reminder_notification_text">Dotaknite da se prijavite nazad.</string>
|
||||
@@ -88,7 +86,6 @@
|
||||
<string name="fix">Popravi</string>
|
||||
<string name="help">Pomoć</string>
|
||||
<string name="sorry">Izvini</string>
|
||||
<string name="status_heading">Status:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Nema kontakata za prikazivanje</string>
|
||||
<string name="no_contacts_action">Taknite + ikonu da dodate kontakt</string>
|
||||
@@ -134,6 +131,7 @@
|
||||
<string name="connecting_to_device">Povezujem se sa uređajem\u2026</string>
|
||||
<string name="authenticating_with_device">Autentikacija sa uređajem\u2026</string>
|
||||
<string name="connection_error_title">Nije moguće povezivanje sa vašim kontaktom</string>
|
||||
<string name="connection_error_explanation">Provjerite jeste li oboje povezani na ist Wi-Fi mrežu.</string>
|
||||
<string name="connection_error_feedback">Ako se problem ponavlja, Molimo vas <a href="feedback">pošaljite povratne informacije</a> kako bi pomogli poboljšanju aplikacije.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Dodaj udaljeni konktakt</string>
|
||||
@@ -466,7 +464,6 @@
|
||||
<string name="lock_unlock_password">Koristi lozinku</string>
|
||||
<string name="lock_is_locked">Briar je zaključan</string>
|
||||
<string name="lock_tap_to_unlock">Dotakni da otključaš</string>
|
||||
<!--Connections Screen-->
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Fata</string>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<string name="enter_password">Contrasenya</string>
|
||||
<string name="try_again">La contrasenya és incorrecta, torneu a escriure-la</string>
|
||||
<string name="dialog_title_cannot_check_password">No es pot verificar la contrasenya</string>
|
||||
<string name="dialog_message_cannot_check_password">Briar no pot verificar la contrasenya. Proveu de reiniciar el vostre aparell per a solucionar aquest problema.</string>
|
||||
<string name="dialog_message_cannot_check_password">El Briar no pot verificar la contrasenya. Proveu de reiniciar el vostre aparell per a solucionar aquest problema.</string>
|
||||
<string name="sign_in_button">Inicia la sessió</string>
|
||||
<string name="forgotten_password">No recordo la contrasenya</string>
|
||||
<string name="dialog_title_lost_password">Contrasenya perduda</string>
|
||||
@@ -44,9 +44,9 @@
|
||||
<item quantity="other">Aquesta és una versió de prova de Briar. El vostre compte caducarà en %d dies i no es podrà renovar.</item>
|
||||
</plurals>
|
||||
<string name="expiry_date_reached">Aquesta versió de Briar ha caducat.\nGràcies per haver-lo provat!</string>
|
||||
<string name="download_briar">Per continuar utilitzant Briar, baixeu la darrera versió.</string>
|
||||
<string name="download_briar">Per continuar utilitzant el Briar, baixeu la darrera versió.</string>
|
||||
<string name="create_new_account">Haureu de crear un compte nou, però podeu utilitzar el mateix sobrenom.</string>
|
||||
<string name="download_briar_button">Descarrega la darrera versió</string>
|
||||
<string name="download_briar_button">Baixa l\'última versió</string>
|
||||
<string name="startup_open_database">S\'està desxifrant la base de dades...</string>
|
||||
<string name="startup_migrate_database">S\'està actualitzant la base de dades...</string>
|
||||
<string name="startup_compact_database">S\'està compactant la base de dades...</string>
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">Bloqueja l\'aplicació</string>
|
||||
<string name="settings_button">Configuració</string>
|
||||
<string name="sign_out_button">Tanca la sessió </string>
|
||||
<string name="transports_onboarding_text">Toqueu per decidir com es connecta Briar als vostres contactes.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">El mòbil té accés a Internet via WiFi</string>
|
||||
<string name="tor_device_status_online_mobile">El mòbil té accés a Internet via dades</string>
|
||||
<string name="tor_device_status_offline">El mòbil no té accés a Internet</string>
|
||||
<string name="tor_plugin_status_enabling">Briar s\'està connectant a Internet</string>
|
||||
<string name="tor_plugin_status_active">Briar està connectat a Internet</string>
|
||||
<string name="tor_plugin_status_inactive">Briar no pot connectar-se a Internet</string>
|
||||
<string name="tor_plugin_status_disabled">Briar està configurat per a no emprar Internet</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar està configurat per a no emprar dades mòbils</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar està configurat per a no usar Internet mentre funciona amb bateria</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar està configurat per a no emprar Internet en aquest país</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">La mateixa xarxa WiFi</string>
|
||||
<string name="lan_device_status_on">El mòbil està connectat a WiFi</string>
|
||||
<string name="lan_device_status_off">El mòbil no està connectat a WiFi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar s\'està connectant a la xarxa WiFi</string>
|
||||
<string name="lan_plugin_status_active">Briar està connectat a la xarxa WiFi</string>
|
||||
<string name="lan_plugin_status_inactive">Briar no pot connectar-se a la xarxa WiFi</string>
|
||||
<string name="lan_plugin_status_disabled">Briar està configurat per a no emprar la xarxa WiFi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">El Bluetooth del mòbil està apagat</string>
|
||||
<string name="bt_device_status_off">El Bluetooth del mòbil està engegat</string>
|
||||
<string name="bt_plugin_status_enabling">Briar s\'està connectant a Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar està connectat a Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar no pot connectar-se a Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar està configurat per a no emprar Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Heu sortit de Briar</string>
|
||||
<string name="reminder_notification_text">Toqueu per a reiniciar la sessió.</string>
|
||||
@@ -136,8 +110,7 @@
|
||||
<string name="fix">Corregeix</string>
|
||||
<string name="help">Ajuda</string>
|
||||
<string name="sorry">Ens sap greu</string>
|
||||
<string name="error_start_activity">No està disponible en el vostre sistema</string>
|
||||
<string name="status_heading">Estat</string>
|
||||
<string name="error_start_activity">No disponible al vostre sistema</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">No hi ha cap contacte per mostrar</string>
|
||||
<string name="no_contacts_action">Toqueu la icona + per afegir un contacte</string>
|
||||
@@ -152,16 +125,16 @@
|
||||
<string name="set_contact_alias">Canvia el nom del contacte</string>
|
||||
<string name="set_contact_alias_hint">Nom del contacte</string>
|
||||
<string name="set_alias_button">Canvia</string>
|
||||
<string name="delete_all_messages">Esborra tots els missatges</string>
|
||||
<string name="dialog_title_delete_all_messages">Confirmeu l\'esborrat dels missatges</string>
|
||||
<string name="dialog_message_delete_all_messages">Segur que voleu esborrar tots els missatges?</string>
|
||||
<string name="dialog_title_not_all_messages_deleted">No s\'han pogut esborrar tots els missatges</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_both">Els missatges relacionats amb presentacions i invitacions pendents no es poden suprimir fins que finalitzen.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_introductions">Els missatges relacionats amb presentacions pendents no es poden suprimir fins que finalitzen.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_invitations">Els missatges relacionats amb invitacions pendents no es poden suprimir fins que finalitzen.</string>
|
||||
<string name="delete_all_messages">Suprimeix tots els missatges</string>
|
||||
<string name="dialog_title_delete_all_messages">Confirmeu la supressió dels missatges</string>
|
||||
<string name="dialog_message_delete_all_messages">Esteu segur que voleu suprimir tots els missatges?</string>
|
||||
<string name="dialog_title_not_all_messages_deleted">No s\'ha pogut suprimir tots els missatges</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_both">Els missatges relacionats amb introduccions i invitacions pendents no es poden suprimir fins que es finalitzin.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_introductions">Els missatges relacionats amb introduccions pendents no es poden suprimir fins que es finalitzin.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_invitations">Els missatges relacionats amb invitacions pendents no es poden suprimir fins que es finalitzin.</string>
|
||||
<string name="dialog_message_not_deleted_partly_downloaded">Els missatges baixats parcialment no es poden suprimir fins que s\'acabin de baixar.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_both">Per a suprimir una invitació o una presentació, cal que seleccioneu la sol·licitud i la resposta.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_introductions">Per a suprimir una presentació, cal que seleccioneu la sol·licitud i la resposta.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_both">Per a suprimir una invitació o una introducció, cal que seleccioneu la sol·licitdu i la resposta.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_introductions">Per a suprimir una introducció, cal que seleccioneu la sol·licitud i la resposta.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_invitations">Per a suprimir una invitació, cal que seleccioneu la sol·licitud i la resposta.</string>
|
||||
<string name="delete_contact">Suprimeix aquest contacte</string>
|
||||
<string name="dialog_title_delete_contact">Confirmeu la supressió del contacte</string>
|
||||
@@ -196,6 +169,7 @@ Així que l\'actualitzi li veureu una icona diferent .</string>
|
||||
<string name="connecting_to_device">Connectant-se al dispositiu\u2026</string>
|
||||
<string name="authenticating_with_device">Autenticant-se amb el dispositiu\u2026</string>
|
||||
<string name="connection_error_title">No ha pogut connectar-se al vostre contacte</string>
|
||||
<string name="connection_error_explanation">Comproveu que esteu connectats a la mateixa xarxa Wi-Fi.</string>
|
||||
<string name="connection_error_feedback">Si aquest problema persisteix, <a href="feedback">envieu-nos un comentari</a> per ajudar-nos a millorar l\'aplicació.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Afegeix un contacte llunyà</string>
|
||||
@@ -436,20 +410,10 @@ Així que l\'actualitzi li veureu una icona diferent .</string>
|
||||
<string name="pref_theme_auto">Automàtic (segons l\'hora)</string>
|
||||
<string name="pref_theme_system">Valor per defecte del sistema</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Connexions</string>
|
||||
<string name="bluetooth_setting">Connectat als contactes via Bluetooth</string>
|
||||
<string name="wifi_setting">Connectat als contactes en la mateixa xarxa WiFi</string>
|
||||
<string name="tor_enable_title">Connectat als contactes via Internet</string>
|
||||
<string name="tor_enable_summary">Totes les connexions van via la xarxa Tor per augmentar privacitat</string>
|
||||
<string name="tor_network_setting">Mètode de connexió per a la xarxa Tor</string>
|
||||
<string name="tor_network_setting_automatic">Automàtic, basat en la posició</string>
|
||||
<string name="tor_network_setting_without_bridges">Usa la xarxa Tor sense ponts</string>
|
||||
<string name="tor_network_setting_with_bridges">Usa la xarxa Tor amb ponts</string>
|
||||
<string name="tor_network_setting_never">No connectis a Internet</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Automàtic: %1$s (a %2$s)</string>
|
||||
<string name="tor_mobile_data_title">Usa dades mòbils</string>
|
||||
<string name="tor_only_when_charging_title">Només connecta\'t a Internet mentre s\'està carregant </string>
|
||||
<string name="tor_only_when_charging_summary">Desactiva la connexió a Internet quan el dispositiu estigui funcionant amb la bateria</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Seguretat</string>
|
||||
@@ -559,8 +523,6 @@ Així que l\'actualitzi li veureu una icona diferent .</string>
|
||||
<string name="lock_unlock_password">Usa la contrasenya</string>
|
||||
<string name="lock_is_locked">Briar està bloquejat</string>
|
||||
<string name="lock_tap_to_unlock">Toqueu per desbloquejar-lo</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar pot contactar els vostres contactes via Internet, WiFi o Bluetooth.\n\nTotes les connexions d\'Internet van via la xarxa Tor per privacitat.\n\nSi es pot arribar a un contacte per diversos mètodes, Briar els usa tots simultàniament.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alba</string>
|
||||
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">App sperren</string>
|
||||
<string name="settings_button">Einstellungen</string>
|
||||
<string name="sign_out_button">Abmelden</string>
|
||||
<string name="transports_onboarding_text">Hier tippen, um die Verbindung zu deinen Kontakten zu steuern.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">Dein Telefon hat Internetzugang über WLAN</string>
|
||||
<string name="tor_device_status_online_mobile">Dein Telefon hat Internetzugang über mobile Daten</string>
|
||||
<string name="tor_device_status_offline">Dein Telefon hat keinen Internetzugang</string>
|
||||
<string name="tor_plugin_status_enabling">Briar verbindet sich mit dem Internet</string>
|
||||
<string name="tor_plugin_status_active">Briar ist mit dem Internet verbunden</string>
|
||||
<string name="tor_plugin_status_inactive">Briar kann keine Verbindung zum Internet herstellen</string>
|
||||
<string name="tor_plugin_status_disabled">Briar ist so konfiguriert, dass keine Internetverbindung verwendet werden soll</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar ist so konfiguriert, dass keine mobilen Daten verwendet werden sollen</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar ist so konfiguriert, dass im Akkubetrieb das Internet nicht genutzt werden soll</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar ist so konfiguriert, dass keine Internetverbindung in diesem Land verwendet werden soll</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">WLAN</string>
|
||||
<string name="transport_lan_long">Selbes WLAN-Netzwerk</string>
|
||||
<string name="lan_device_status_on">Dein Telefon ist über WLAN verbunden</string>
|
||||
<string name="lan_device_status_off">Dein Telefon ist nicht über WLAN verbunden</string>
|
||||
<string name="lan_plugin_status_enabling">Briar verbindet sich mit dem WLAN-Netzwerk</string>
|
||||
<string name="lan_plugin_status_active">Briar ist mit dem WLAN-Netzwerk verbunden</string>
|
||||
<string name="lan_plugin_status_inactive">Briar kann keine Verbindung zum WLAN-Netzwerk herstellen</string>
|
||||
<string name="lan_plugin_status_disabled">Briar ist so konfiguriert, dass kein WLAN-Netzwerk verwendet werden soll</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Die Bluetooth-Funktion deines Telefons ist eingeschaltet</string>
|
||||
<string name="bt_device_status_off">Die Bluetooth-Funktion deines Telefons ist ausgeschaltet</string>
|
||||
<string name="bt_plugin_status_enabling">Briar verbindet sich über Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar ist über Bluetooth verbunden</string>
|
||||
<string name="bt_plugin_status_inactive">Briar kann keine Verbindung über Bluetooth herstellen</string>
|
||||
<string name="bt_plugin_status_disabled">Briar ist so konfiguriert, dass Bluetooth nicht verwendet werden soll</string>
|
||||
<string name="transport_lan">WLAN</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Von Briar abgemeldet</string>
|
||||
<string name="reminder_notification_text">Tippe, um dich wieder anzumelden.</string>
|
||||
@@ -137,7 +111,6 @@
|
||||
<string name="help">Hilfe</string>
|
||||
<string name="sorry">Entschuldigung</string>
|
||||
<string name="error_start_activity">Nicht Verfügbar für dein System</string>
|
||||
<string name="status_heading">Status:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Keine Kontakte vorhanden</string>
|
||||
<string name="no_contacts_action">Tippe auf das + Symbol, um einen Kontakt hinzuzufügen</string>
|
||||
@@ -154,7 +127,7 @@
|
||||
<string name="set_alias_button">Ändern</string>
|
||||
<string name="delete_all_messages">Alle Nachrichten löschen</string>
|
||||
<string name="dialog_title_delete_all_messages">Löschen der Nachrichten bestätigen</string>
|
||||
<string name="dialog_message_delete_all_messages">Bist du sicher, dass du alle Nachrichten löschen willst?</string>
|
||||
<string name="dialog_message_delete_all_messages">Bist Du sicher, dass Du alle Nachrichten löschen willst?</string>
|
||||
<string name="dialog_title_not_all_messages_deleted">Es konnten nicht alle Nachrichten gelöscht werden</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_both">Nachrichten, die sich auf laufende Einladungen und Kontaktempfehlungen beziehen, können nicht gelöscht werden, bis sie abgeschlossen sind.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_introductions">Nachrichten, die sich auf laufende Kontaktempfehlungen beziehen, können nicht gelöscht werden, bis sie abgeschlossen sind.</string>
|
||||
@@ -195,6 +168,7 @@
|
||||
<string name="connecting_to_device">Verbinde mit Gerät\u2026</string>
|
||||
<string name="authenticating_with_device">Authentifiziere Gerät\u2026</string>
|
||||
<string name="connection_error_title">Keine Verbindung zum Kontakt</string>
|
||||
<string name="connection_error_explanation">Überprüfe, ob ihr beide mit dem selben WLAN-Netzwerk verbunden seid.</string>
|
||||
<string name="connection_error_feedback">Wenn das Problem weiterbesteht, hilf uns die App zu verbessern und <a href="feedback">schicke Feedback</a>.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Kontakt aus der Ferne hinzufügen</string>
|
||||
@@ -210,7 +184,7 @@
|
||||
<string name="add_contact_choose_nickname">Wähle einen Spitznamen</string>
|
||||
<string name="add_contact_choose_a_nickname">Gib einen Spitznamen ein</string>
|
||||
<string name="nickname_intro">Gib deinem Kontakt einen Spitznamen. Nur du kannst ihn sehen.</string>
|
||||
<string name="your_link">Gib diesen Link dem Kontakt, den du hinzufügen möchtest</string>
|
||||
<string name="your_link">Gebe diesen Link dem Kontakt, den du hinzufügen möchtest:</string>
|
||||
<string name="link_clip_label">Briar Link</string>
|
||||
<string name="link_copied_toast">Link kopiert</string>
|
||||
<string name="adding_contact_error">Es gab einen Fehler beim Hinzufügen des Kontaktes.</string>
|
||||
@@ -251,7 +225,7 @@
|
||||
will be used in a dialog button, so if the translation of this string longer than 20 characters,
|
||||
please use "No" instead, and use "Yes" for the "Same Person" button-->
|
||||
<string name="different_person_button">Andere Person</string>
|
||||
<string name="duplicate_link_dialog_text_3">%s und %s haben Dir denselben Link geschickt.\n\nMöglicherweise versucht einer der beiden mehr über deine Kontakte zu erfahren.\n\nDu solltest deswegen niemandem sagen, dass du diesen Link auch von jemand anderem erhalten hast.</string>
|
||||
<string name="duplicate_link_dialog_text_3">%s und %s haben Dir denselben Link geschickt.\n\nMöglicherweise versucht einer der beiden mehr über deine Kontakte zu erfahren.\n\nDu solltest deswegen niemandem sagen, dass Du diesen Link auch von jemand anderem erhalten hast.</string>
|
||||
<string name="pending_contact_updated_toast">Ausstehender Kontakt aktualisiert</string>
|
||||
<!--Introductions-->
|
||||
<string name="introduction_onboarding_title">Mache deine Kontakte untereinander bekannt</string>
|
||||
@@ -436,19 +410,10 @@
|
||||
<string name="pref_theme_system">Systemstandard</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Verbindungen</string>
|
||||
<string name="bluetooth_setting">Verbindung zu den Kontakten über Bluetooth</string>
|
||||
<string name="wifi_setting">Verbindung zu den Kontakten über dasselbe WLAN-Netzwerk</string>
|
||||
<string name="tor_enable_title">Verbindung zu den Kontakten über das Internet</string>
|
||||
<string name="tor_enable_summary">Alle Verbindungen laufen über das Tor-Netzwerk, um den Datenschutz zu gewährleisten</string>
|
||||
<string name="tor_network_setting">Verbindungsmethode mit dem Tor-Netzwerk</string>
|
||||
<string name="tor_network_setting_automatic">Automatisch (standortbasiert)</string>
|
||||
<string name="tor_network_setting_without_bridges">Tor-Netzwerk ohne Bridges nutzen</string>
|
||||
<string name="tor_network_setting_with_bridges">Tor-Netzwerk mit Bridges nutzen</string>
|
||||
<string name="tor_network_setting_never">Keine Verbindung zum Internet herstellen</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Automatisch: %1$s (in %2$s)</string>
|
||||
<string name="tor_mobile_data_title">Mobile Daten benutzen</string>
|
||||
<string name="tor_only_when_charging_title">Verbindung zum Internet nur während des Ladevorgangs</string>
|
||||
<string name="tor_only_when_charging_summary">Deaktiviert die Internetverbindung, wenn das Gerät mit Akku betrieben wird</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Sicherheit</string>
|
||||
@@ -549,7 +514,6 @@
|
||||
<string name="permission_camera_location_title">Kamera und Standort</string>
|
||||
<string name="permission_camera_location_request_body">Um den QR-Code zu scannen, braucht Briar Zugriff auf die Kamera.\n\nUm Bluetooth-Geräte zu finden, braucht Briar Zugriff auf deinen Standort.\n\nBriar speichert weder deinen Standort noch gibt es ihn an andere weiter.</string>
|
||||
<string name="permission_camera_denied_body">Du hast den Zugriff auf die Kamera verweigert, aber das Hinzufügen von Kontakten erfordert die Verwendung der Kamera.\n\nBitte gewähre den Zugriff.</string>
|
||||
<string name="permission_location_denied_body">Du hast den Zugriff auf deinen Standort verweigert, aber Briar benötigt diese Berechtigung, um Bluetooth-Geräte zu erkennen.\n\nBitte gewähre den Zugriff.</string>
|
||||
<string name="qr_code">QR-Code</string>
|
||||
<string name="show_qr_code_fullscreen">QR-Code im Vollbildmodus anzeigen</string>
|
||||
<!--App Locking-->
|
||||
@@ -559,8 +523,6 @@
|
||||
<string name="lock_unlock_password">Passwort benutzen</string>
|
||||
<string name="lock_is_locked">Briar ist gesperrt</string>
|
||||
<string name="lock_tap_to_unlock">Zum Entsperren antippen</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar kann sich über das Internet, WLAN oder Bluetooth mit deinen Kontakten verbinden.\n\nAlle Internetverbindungen laufen über das Tor-Netzwerk, um den Datenschutz zu gewährleisten.\n\nWenn ein Kontakt auf mehreren Wegen erreichbar ist, nutzt Briar diese parallel.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alice</string>
|
||||
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">Bloquear aplicación</string>
|
||||
<string name="settings_button">Configuración</string>
|
||||
<string name="sign_out_button">Cerrar sesión</string>
|
||||
<string name="transports_onboarding_text">Pulsa aquí para controlar cómo se conecta Briar a tus contactos.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">Tu teléfono tiene acceso a Internet vía Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">Tu teléfono tiene acceso a Internet vía datos móviles</string>
|
||||
<string name="tor_device_status_offline">Tu teléfono no tiene acceso a Internet</string>
|
||||
<string name="tor_plugin_status_enabling">Briar está conectando a Internet</string>
|
||||
<string name="tor_plugin_status_active">Briar está conectado a Internet</string>
|
||||
<string name="tor_plugin_status_inactive">Briar no puede conectar a Internet</string>
|
||||
<string name="tor_plugin_status_disabled">Briar está configurado para no usar Internet</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar está configurado para no usar datos móviles</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar está configurado para no usar Internet cuando se esté funcionando en batería</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar está configurado para no usar Internet en este país</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Misma red Wi-Fi</string>
|
||||
<string name="lan_device_status_on">Tu teléfono está conectado al Wi-Fi</string>
|
||||
<string name="lan_device_status_off">Tu teléfono no está conectado al Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar está conectando a la red Wi-Fi</string>
|
||||
<string name="lan_plugin_status_active">Briar está conectado a la red Wi-Fi</string>
|
||||
<string name="lan_plugin_status_inactive">Briar no puede conectar a la red Wi-Fi</string>
|
||||
<string name="lan_plugin_status_disabled">Briar está configurado para no usar a la red Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">El Bluetooth de tu teléfono está encendido</string>
|
||||
<string name="bt_device_status_off">El Bluetooth de tu teléfono está apagado</string>
|
||||
<string name="bt_plugin_status_enabling">Briar está conectando con Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar está conectado con Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar no puede conectar con Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar está configurado para no usar Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Sesión de Briar cerrada</string>
|
||||
<string name="reminder_notification_text">Golpear para reiniciar sesión.</string>
|
||||
@@ -137,7 +111,6 @@
|
||||
<string name="help">Ayuda</string>
|
||||
<string name="sorry">Disculpa</string>
|
||||
<string name="error_start_activity">No disponible en tu sistema</string>
|
||||
<string name="status_heading">Estado:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">No hay contactos para mostrar</string>
|
||||
<string name="no_contacts_action">Golpear el icono + para añadir un contacto</string>
|
||||
@@ -157,12 +130,12 @@
|
||||
<string name="dialog_message_delete_all_messages">¿Estás seguro de que deseas eliminar todos los mensajes?</string>
|
||||
<string name="dialog_title_not_all_messages_deleted">No se pudieron eliminar todos los mensajes.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_both">Los mensajes relacionados con presentaciones o invitaciones en curso no se pueden eliminar hasta que finalicen.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_introductions">Los mensajes relacionados con presentaciones no se pueden eliminar hasta que finalicen.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_introductions">Los mensajes relacionados con presentaciones o invitaciones en curso no se pueden eliminar hasta que finalicen.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_invitations">Los mensajes relacionados a invitaciones en curso no pueden ser borrados hasta su conclusión.</string>
|
||||
<string name="dialog_message_not_deleted_partly_downloaded">Los mensajes parcialmente descargados no se pueden eliminar hasta que haya finalizado la descarga.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_both">Para borrar una invitación o presentación, debes seleccionar la petición y la respuesta.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_introductions">Para eliminar una introducción, debes seleccionar la solicitud y la respuesta.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_invitations">Para eliminar una invitación, debes seleccionar la solicitud y la respuesta.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_introductions">Para eliminar una introducción, debe seleccionar la solicitud y la respuesta.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_invitations">Para eliminar una invitación, debe seleccionar la solicitud y la respuesta.</string>
|
||||
<string name="delete_contact">Eliminar contacto</string>
|
||||
<string name="dialog_title_delete_contact">Confirmar eliminación de contacto</string>
|
||||
<string name="dialog_message_delete_contact">¿Seguro que quieres eliminar este contacto y todos los mensajes intercambiados entre vosotros?</string>
|
||||
@@ -195,6 +168,7 @@
|
||||
<string name="connecting_to_device">Conectando al dispositivo\u2026</string>
|
||||
<string name="authenticating_with_device">Autentificándose con el dispositivo\u2026</string>
|
||||
<string name="connection_error_title">No se pudo conectar a tu contacto</string>
|
||||
<string name="connection_error_explanation">Por favor comprobar que ambos estén conectados a la misma red Wi-Fi.</string>
|
||||
<string name="connection_error_feedback">Si este problema persiste, por favor <a href="feedback">envía tus comentarios</a> para ayudarnos a mejorar la aplicación.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Añadir un Contacto a Distancia</string>
|
||||
@@ -436,19 +410,10 @@
|
||||
<string name="pref_theme_system">Predeterminado del sistema</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Conexiones</string>
|
||||
<string name="bluetooth_setting">Conectar con contactos mediante Bluetooth</string>
|
||||
<string name="wifi_setting">Conectar con contactos en la misma red Wi-Fi</string>
|
||||
<string name="tor_enable_title">Conectar con contactos mediante Internet</string>
|
||||
<string name="tor_enable_summary">Dirigir todas las conexiones a través de la red Tor por privacidad</string>
|
||||
<string name="tor_network_setting">Método de conexión para la red Tor</string>
|
||||
<string name="tor_network_setting_automatic">Automático basado en ubicación</string>
|
||||
<string name="tor_network_setting_without_bridges">Utilizar la red Tor sin puentes</string>
|
||||
<string name="tor_network_setting_with_bridges">Utilizar la red Tor a través de puentes</string>
|
||||
<string name="tor_network_setting_never">Evitar conectar a Internet</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Automática: %1$s (en %2$s)</string>
|
||||
<string name="tor_mobile_data_title">Usar datos móviles</string>
|
||||
<string name="tor_only_when_charging_title">Conectar a Internet solamente mientras se carga el dispositivo</string>
|
||||
<string name="tor_only_when_charging_summary">Deshabilita la conexión a Internet cuando el dispositivo está corriendo con batería.</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Seguridad</string>
|
||||
@@ -549,7 +514,6 @@
|
||||
<string name="permission_camera_location_title">Cámara y ubicación</string>
|
||||
<string name="permission_camera_location_request_body">Para escanear el código QR, Briar necesita acceso a la cámara.\n\nPara descubrir dispositivos Bluetooth, Briar necesita permiso para acceder tu ubicación.\n\nBriar no la almacena o la comparte con nadie.</string>
|
||||
<string name="permission_camera_denied_body">Has denegado el acceso a la cámara, pero para añadir contactos se requiere el uso de la cámara.\n\nPor favor considera la posibilidad de conceder el acceso.</string>
|
||||
<string name="permission_location_denied_body">Has denegado el acceso a tu ubicación, pero Briar necesita este permiso para descubrir dispositivos Bluetooth.\n\nPor favor considera la posibilidad de conceder el acceso.</string>
|
||||
<string name="qr_code">Código QR</string>
|
||||
<string name="show_qr_code_fullscreen">Mostrar código QR a pantalla completa</string>
|
||||
<!--App Locking-->
|
||||
@@ -559,8 +523,6 @@
|
||||
<string name="lock_unlock_password">Usa la contraseña</string>
|
||||
<string name="lock_is_locked">Briar está bloqueado</string>
|
||||
<string name="lock_tap_to_unlock">Golpear para desbloquear</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar puede conectar a tus contactos vía Internet, Wi-Fi o Bluetooth.\n\nTodas las conexiones a Internet van a través de la red Tor por privacidad.\n\nSi un contacto puede ser alcanzado por múltiples métodos, Briar los usa en paralelo.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alicia</string>
|
||||
|
||||
@@ -61,12 +61,10 @@
|
||||
<string name="lock_button">Blokeatu aplikazioa</string>
|
||||
<string name="settings_button">Ezarpenak</string>
|
||||
<string name="sign_out_button">Amaitu saioa</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Briar saioa amaituta</string>
|
||||
<string name="reminder_notification_text">Sakatu saioa berriro hasteko.</string>
|
||||
@@ -113,7 +111,6 @@
|
||||
<string name="help">Laguntza</string>
|
||||
<string name="sorry">Sentitzen dugu</string>
|
||||
<string name="error_start_activity">Ez dago eskuragarri zure sistemarako</string>
|
||||
<string name="status_heading">Egoera:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Ez dago erakusteko kontakturik</string>
|
||||
<string name="no_contacts_action">Sakatu + ikonoa kontaktua gehitzeko</string>
|
||||
@@ -171,6 +168,7 @@
|
||||
<string name="connecting_to_device">Gailura konektatzen\u2026</string>
|
||||
<string name="authenticating_with_device">Gailuarekin autentifikatzen\u2026</string>
|
||||
<string name="connection_error_title">Ezin izan da zure kontaktuarekin konektatu</string>
|
||||
<string name="connection_error_explanation">Egiaztatu biak Wi-Fi sare berera konektatuta zaudetela.</string>
|
||||
<string name="connection_error_feedback">Arazoa mantentzen bada, mesedez <a href="feedback">bidali iruzkin bat</a> aplikazioa hobetzen laguntzeko.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Gehitu urruneko kontaktua</string>
|
||||
@@ -524,7 +522,6 @@
|
||||
<string name="lock_unlock_password">Erabili pasahitza</string>
|
||||
<string name="lock_is_locked">Briar blokeatuta dago</string>
|
||||
<string name="lock_tap_to_unlock">Sakatu desblokeatzeko</string>
|
||||
<!--Connections Screen-->
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Arantza</string>
|
||||
|
||||
@@ -67,23 +67,10 @@
|
||||
<string name="lock_button">قفل کردن برنامه</string>
|
||||
<string name="settings_button">تنظیمات</string>
|
||||
<string name="sign_out_button">خروج</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">اینترنت</string>
|
||||
<string name="tor_plugin_status_enabling">Briar در حال اتصال به اینترنت می باشد</string>
|
||||
<string name="tor_plugin_status_active">Briar به اینترنت متصل شد</string>
|
||||
<string name="tor_plugin_status_inactive">Briar نمی تواند به اینترنت متصل شود</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">وای فای</string>
|
||||
<string name="transport_lan_long">همان شبکه وای-فای</string>
|
||||
<string name="lan_device_status_on">موبایل شما به وای-فای وصل می باشد</string>
|
||||
<string name="lan_device_status_off">موبایل شما به وای-فای وصل نیست</string>
|
||||
<string name="lan_plugin_status_enabling">Briar در حال اتصال به شبکه وای-فای می باشد</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">بلوتوث</string>
|
||||
<string name="bt_device_status_on">بلوتوث موبایل شما روشن می باشد</string>
|
||||
<string name="bt_device_status_off">بلوتوث موبایل شما خاموش می باشد</string>
|
||||
<string name="bt_plugin_status_inactive">Briar نمی تواند به بلوتوث وصل شود</string>
|
||||
<string name="bt_plugin_status_disabled">Briar طوری پیکربندی شده که از بلوتوث استفاده نکند</string>
|
||||
<string name="transport_lan">وای فای</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">از Briar (برایر) خارج شد</string>
|
||||
<string name="reminder_notification_text">برای وارد شدن دوباره ضربه بزنید.</string>
|
||||
@@ -130,7 +117,6 @@
|
||||
<string name="help">راهنما</string>
|
||||
<string name="sorry">پوزش</string>
|
||||
<string name="error_start_activity">برای سیستم شما موجود نمی باشد</string>
|
||||
<string name="status_heading">وضعیت:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">هیچ مخاطبی برای نمایش وجود ندارد</string>
|
||||
<string name="no_contacts_action">برای افزودن مخاطب روی + کلیک کنید</string>
|
||||
@@ -196,6 +182,7 @@
|
||||
<string name="connecting_to_device">اتصال به دستگاهu2026\</string>
|
||||
<string name="authenticating_with_device">تصدیق سازی با دستگاه u2026\</string>
|
||||
<string name="connection_error_title">اتصال به مخاطب شما برقرار نشد</string>
|
||||
<string name="connection_error_explanation">لطفا مطمئن شوید که هر دو شما به شبکه وای فای یکسان متصل هستید.</string>
|
||||
<string name="connection_error_feedback">اگر این مشکل ادامه پیدا کرد، لطفا <a href="feedback">بازخورد ارسال کنید</a> تا به ما در بهبود برنامه کمک کنید.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">افزودن مخاطب از دور</string>
|
||||
@@ -462,20 +449,10 @@
|
||||
<string name="pref_theme_auto">خودکار ( روز)</string>
|
||||
<string name="pref_theme_system">پیش فرض سیستم</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">اتصالات</string>
|
||||
<string name="bluetooth_setting">اتصال به مخاطبان از طریق بلوتوث</string>
|
||||
<string name="wifi_setting">اتصال به مخاطبان روی یک شبکه وای-فای یکسان</string>
|
||||
<string name="tor_enable_title">اتصال به مخاطبان از طریق اینترنت</string>
|
||||
<string name="tor_enable_summary">تمام اتصال ها برای حفظ حریم خصوصی از شبکه تور عبور میکنند</string>
|
||||
<string name="tor_network_setting">روش اتصال برای شبکه تور</string>
|
||||
<string name="tor_network_setting_automatic">خودکار مبتنی بر موقعیت</string>
|
||||
<string name="tor_network_setting_without_bridges">استفاده از شبکه تور بدون پل</string>
|
||||
<string name="tor_network_setting_with_bridges">استفاده از شبکه تور با پل</string>
|
||||
<string name="tor_network_setting_never">به اینترنت وصل نشو</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">خودکار: %1$s(در %2$s)</string>
|
||||
<string name="tor_mobile_data_title">استفاده از داده موبایل</string>
|
||||
<string name="tor_only_when_charging_title">اتصال به اینترنت تنها در هنگام شارژ شدن</string>
|
||||
<string name="tor_only_when_charging_summary">ارتباط اینترنت را هنگامی که دستگاه در حال استفاده از باتری خود می باشد را غیرفعال می کند</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">امنیت</string>
|
||||
@@ -597,7 +574,6 @@ Briar (برایر) موقعیت شما را ذخیره نمیکند و آن
|
||||
<string name="lock_unlock_password">استفاده از گذرواژه</string>
|
||||
<string name="lock_is_locked">Briar (برایر) قفل می باشد</string>
|
||||
<string name="lock_tap_to_unlock">برای آنلاک کردن کلیک کنید</string>
|
||||
<!--Connections Screen-->
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">آلیس</string>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<string name="warning_dozed">%s n’a pas pu fonctionner en arrière-plan</string>
|
||||
<!--Login-->
|
||||
<string name="enter_password">Mot de passe</string>
|
||||
<string name="try_again">Le mot de passe est erroné, réessayez</string>
|
||||
<string name="try_again">Le mot de passe est erroné, ressayez</string>
|
||||
<string name="dialog_title_cannot_check_password">Impossible de vérifier le mot de passe</string>
|
||||
<string name="dialog_message_cannot_check_password">Briar ne peut pas vérifier votre mot de passe. Veuillez essayer de redémarrer votre appareil pour résoudre ce problème.</string>
|
||||
<string name="sign_in_button">Connexion</string>
|
||||
@@ -37,7 +37,7 @@
|
||||
<string name="startup_failed_activity_title">Échec de démarrage de Briar</string>
|
||||
<string name="startup_failed_db_error">Pour quelque raison, votre base de données Briar est corrompue sans espoir de réparation. Votre compte, vos données et tous vos contacts sont perdus. Malheureusement, vous devez réinstaller Briar et créer un nouveau compte en choisissant « J’ai oublié mon mot de passe » dans l’invite de mot de passe.</string>
|
||||
<string name="startup_failed_data_too_old_error">Votre compte a été créé avec une ancienne version de cette appli et ne peut pas être ouvert avec cette version. Vous devez soit réinstaller l’ancienne version, soit créer un nouveau compte en choisissant « J’ai oublié mon mot de passe » dans l’invite de mot de passe.</string>
|
||||
<string name="startup_failed_data_too_new_error">Cette version de l’appli est trop ancienne. Veuillez passer à la version la plus récente et réessayer.</string>
|
||||
<string name="startup_failed_data_too_new_error">Cette version de l’appli est trop ancienne. Veuillez passer à la version la plus récente et ressayer.</string>
|
||||
<string name="startup_failed_service_error">Briar n’a pas pu démarrer un greffon exigé. Réinstaller Briar résout généralement ce problème. Veuillez cependant noter que vous perdrez votre compte et toutes données relatives puisque Briar n’utilise pas de serveurs centralisés sur lesquels enregistrer vos données.</string>
|
||||
<plurals name="expiry_warning">
|
||||
<item quantity="one">Ceci est une version de test de Briar. Votre compte arrivera à expiration dans %d jour et ne peut pas être renouvelé.</item>
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">Verrouiller l’appli</string>
|
||||
<string name="settings_button">Paramètres</string>
|
||||
<string name="sign_out_button">Déconnexion</string>
|
||||
<string name="transports_onboarding_text">Touchez ici pour contrôler comment Briar se connecte à vos contacts.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">Votre téléphone a accès à Internet par le Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">Votre téléphone a accès à Internet par les données mobiles</string>
|
||||
<string name="tor_device_status_offline">Votre téléphone n’a pas accès à Internet</string>
|
||||
<string name="tor_plugin_status_enabling">Briar se connecte à Internet</string>
|
||||
<string name="tor_plugin_status_active">Briar est connecté à Internet</string>
|
||||
<string name="tor_plugin_status_inactive">Briar ne peut pas se connecter à Internet</string>
|
||||
<string name="tor_plugin_status_disabled">Briar est configuré pour ne pas utiliser Internet</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar est configuré pour ne pas utiliser les données mobiles</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar est configuré pour ne pas utiliser Internet si l’appareil utilise sa pile</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar est configuré pour ne pas utiliser Internet dans ce pays</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Même réseau Wi-Fi</string>
|
||||
<string name="lan_device_status_on">Votre téléphone est connecté au Wi-Fi</string>
|
||||
<string name="lan_device_status_off">Votre téléphone n’est pas connecté au Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar se connecte au réseau Wi-Fi</string>
|
||||
<string name="lan_plugin_status_active">Briar est connecté au réseau Wi-Fi</string>
|
||||
<string name="lan_plugin_status_inactive">Briar ne peut pas se connecter au réseau Wi-Fi</string>
|
||||
<string name="lan_plugin_status_disabled">Briar est configuré pour ne pas utiliser le réseau Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Le Bluetooth de votre téléphone est activé</string>
|
||||
<string name="bt_device_status_off">Le Bluetooth de votre téléphone est désactivé</string>
|
||||
<string name="bt_plugin_status_enabling">Briar se connecte au Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar est connecté au Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar ne peut pas se connecter au Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar est configuré pour ne pas utiliser le Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Déconnecté de Briar</string>
|
||||
<string name="reminder_notification_text">Touchez pour vous reconnecter</string>
|
||||
@@ -137,13 +111,12 @@
|
||||
<string name="help">Aide</string>
|
||||
<string name="sorry">Désolé</string>
|
||||
<string name="error_start_activity">N’est pas proposée sur votre système.</string>
|
||||
<string name="status_heading">État :</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Aucun contact à afficher</string>
|
||||
<string name="no_contacts_action">Touchez l’icône + pour ajouter un contact</string>
|
||||
<string name="date_no_private_messages">Aucun message.</string>
|
||||
<string name="no_private_messages">Aucun message à afficher</string>
|
||||
<string name="message_hint">Rédigez un message</string>
|
||||
<string name="message_hint">Rédiger le message</string>
|
||||
<string name="image_caption_hint">Ajouter une légende (facultatif)</string>
|
||||
<string name="image_attach">Joindre une image</string>
|
||||
<string name="image_attach_error">Impossible de joindre une ou des images</string>
|
||||
@@ -171,7 +144,7 @@
|
||||
<string name="you">Vous</string>
|
||||
<string name="save_image">Enregistrer l’image</string>
|
||||
<string name="dialog_title_save_image">Enregistrer l’image ?</string>
|
||||
<string name="dialog_message_save_image">L’enregistrement de cette image permettra aux autres applis d’y accéder.\n\n Voulez-vous vraiment l’enregistrer ?</string>
|
||||
<string name="dialog_message_save_image">L’enregistrement de cette image permettra aux autres applis d’y accéder.\n\n Souhaitez-vous vraiment l’enregistrer ?</string>
|
||||
<string name="save_image_success">L’image a été enregistrée</string>
|
||||
<string name="save_image_error">Impossible d’enregistrer l’image</string>
|
||||
<string name="dialog_title_no_image_support">Les images ne sont pas disponibles</string>
|
||||
@@ -189,12 +162,13 @@
|
||||
<string name="contact_added_toast">Contact ajouté : %s</string>
|
||||
<string name="contact_already_exists">Le contact %s existe déjà</string>
|
||||
<string name="qr_code_invalid">Le code QR est invalide</string>
|
||||
<string name="qr_code_too_old">Le code QR que vous avez balayé provient d’une version plus ancienne de %s.\n\nVeuillez demander à votre contact de passer à la version la plus récente et réessayer.</string>
|
||||
<string name="qr_code_too_new">Le code QR que vous avez balayé provient d’une version plus récente de %s.\n\nVeuillez passer à la version la plus récente et réessayer.</string>
|
||||
<string name="qr_code_too_old">Le code QR que vous avez balayé provient d’une version plus ancienne de %s.\n\nVeuillez demander à votre contact de passer à la version la plus récente et ressayer.</string>
|
||||
<string name="qr_code_too_new">Le code QR que vous avez balayé provient d’une version plus récente de %s.\n\nVeuillez passer à la version la plus récente et ressayer.</string>
|
||||
<string name="camera_error">Erreur de l’appareil photo</string>
|
||||
<string name="connecting_to_device">Connexion à l’appareil\u2026</string>
|
||||
<string name="authenticating_with_device">Autentification avec l’appareil\u2026</string>
|
||||
<string name="connection_error_title">Impossible de se connecter à votre contact</string>
|
||||
<string name="connection_error_explanation">Veuillez vérifier que vous êtes connecté au même réseau Wi-Fi.</string>
|
||||
<string name="connection_error_feedback">Si le problème persiste, veuillez nous <a href="feedback">envoyer une rétroaction</a> pour nous aider à améliorer l\'appli.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Ajouter un contact éloigné</string>
|
||||
@@ -226,7 +200,7 @@
|
||||
<string name="own_link_error">Saisissez le lien de votre contact, pas le vôtre</string>
|
||||
<string name="nickname_missing">Veuillez saisir un pseudonyme</string>
|
||||
<string name="invalid_link">Le lien est invalide</string>
|
||||
<string name="unsupported_link">Ce lien provient d’une version plus récente de Briar. Veuillez passer à la version la plus récente et réessayer.</string>
|
||||
<string name="unsupported_link">Ce lien provient d’une version plus récente de Briar. Veuillez passer à la version la plus récente et ressayer.</string>
|
||||
<string name="intent_own_link">Vous avez ouvert votre propre lien. Utilisez celui du contact que vous souhaitez ajouter.</string>
|
||||
<string name="missing_link">Veuillez saisir un lien</string>
|
||||
<!--This is a numeral indicating the first step in a series of screens-->
|
||||
@@ -265,7 +239,7 @@
|
||||
<string name="introduction_sent">Votre présentation a été envoyée.</string>
|
||||
<string name="introduction_error">Une erreur est survenue lors de la présentation.</string>
|
||||
<string name="introduction_request_sent">Vous avez demandé de présenter %1$s à %2$s.</string>
|
||||
<string name="introduction_request_received">%1$s a demandé de vous présenter à %2$s. Voulez-vous ajouter %2$s à votre liste de contacts ?</string>
|
||||
<string name="introduction_request_received">%1$s a demandé de vous présenter à %2$s. Souhaitez-vous ajouter %2$s à votre liste de contacts ?</string>
|
||||
<string name="introduction_request_exists_received">%1$s a demandé de vous présenter à %2$s, mais %2$s est déjà dans votre liste de contacts. Puisque %1$s pourrait ne pas le savoir, vous pouvez tout de même répondre :</string>
|
||||
<string name="introduction_request_answered_received">%1$s a demandé de vous présenter à %2$s.</string>
|
||||
<string name="introduction_response_accepted_sent">Vous avez accepté d’être présenté à %1$s.</string>
|
||||
@@ -423,7 +397,7 @@
|
||||
<string name="blogs_rss_remove_feed_ok">Supprimer</string>
|
||||
<string name="blogs_rss_feeds_manage_delete_error">Impossible de supprimer le fil !</string>
|
||||
<string name="blogs_rss_feeds_manage_empty_state">Aucun fil RSS à afficher\n\nTouchez l’icône + pour importer un fil</string>
|
||||
<string name="blogs_rss_feeds_manage_error">Un problème est survenu lors du chargement de vos fils. Veuillez réessayer plus tard.</string>
|
||||
<string name="blogs_rss_feeds_manage_error">Un problème est survenu lors du chargement de vos fils. Veuillez ressayer plus tard.</string>
|
||||
<!--Settings Display-->
|
||||
<string name="pref_language_title">Langue et région</string>
|
||||
<string name="pref_language_changed">Ce paramètre prendra effet une fois que vous aurez redémarré Briar. Veuillez vous déconnecter et redémarrer Briar.</string>
|
||||
@@ -549,7 +523,6 @@
|
||||
<string name="permission_camera_location_title">Appareil photo et position</string>
|
||||
<string name="permission_camera_location_request_body">Afin de balayer le code QR, Briar doit accéder à l’appareil photo.\n\nAfin de découvrir des périphériques Bluetooth, Briar doit accéder à votre position.\n\nBriar n’enregistre pas votre position et ne la partage avec personne.</string>
|
||||
<string name="permission_camera_denied_body">Vous avez refusé l’accès à la caméra, mais l’ajout de contacts exige l’utilisation de celle-ci.\n\nVeuillez envisager d’y accorder l’accès.</string>
|
||||
<string name="permission_location_denied_body">Vous avez refusé l’accès à votre position géographique, mais Briar en a besoin pour découvrir les appareils Bluetooth.\n\nVeuillez envisager d’y accorder l’accès.</string>
|
||||
<string name="qr_code">Code QR</string>
|
||||
<string name="show_qr_code_fullscreen">Afficher le code QR en plein écran</string>
|
||||
<!--App Locking-->
|
||||
@@ -559,8 +532,6 @@
|
||||
<string name="lock_unlock_password">Utiliser un mot de passe</string>
|
||||
<string name="lock_is_locked">Briar est verrouillée</string>
|
||||
<string name="lock_tap_to_unlock">Toucher pour déverrouiller</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar peut se connecter à vos contacts par Internet, Wi-Fi ou Bluetooth.\n\nToutes les connections Internet passent par le réseau Tor afin de protéger les données.\n\nSi un contact peut être joint par plusieurs moyens, Briar les utilisera simultanément.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Laurence</string>
|
||||
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">Bloquear App</string>
|
||||
<string name="settings_button">Axustes</string>
|
||||
<string name="sign_out_button">Finalizar sesión</string>
|
||||
<string name="transports_onboarding_text">Toca aquí para controlar o xeito en que Briar conecta cos teus contactos.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">O teu móbil ten acceso a internet por Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">O teu móbil ten acceso a internet por datos móbiles</string>
|
||||
<string name="tor_device_status_offline">O teu móbil non ten acceso a internet</string>
|
||||
<string name="tor_plugin_status_enabling">Briar estase conectando a internet</string>
|
||||
<string name="tor_plugin_status_active">Briar está conectada a internet</string>
|
||||
<string name="tor_plugin_status_inactive">Briar non pode conectarse a internet</string>
|
||||
<string name="tor_plugin_status_disabled">Briar está configurada para non usar internet</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar está configurada para non usar datos móbilies</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar está configurada para non usar internet se está usando batería</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar está configurada para non usar internet neste país</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Mesma rede Wi-Fi</string>
|
||||
<string name="lan_device_status_on">O móbil está conectado á Wi-Fi</string>
|
||||
<string name="lan_device_status_off">O móbil non está conectado á Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar está conectando á rede Wi-Fi</string>
|
||||
<string name="lan_plugin_status_active">Briar está conectada á rede Wi-Fi</string>
|
||||
<string name="lan_plugin_status_inactive">Briar non pode conectar coa rede Wi-Fi</string>
|
||||
<string name="lan_plugin_status_disabled">Briar está configurada para non usar a rede Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">O móbil ten o Bluetooth activado</string>
|
||||
<string name="bt_device_status_off">O móbil ten o Bluetooth desactivado</string>
|
||||
<string name="bt_plugin_status_enabling">Briar está conectando por Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar está conectada ó Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar non pode conectar por Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar está configurada para non usar Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Desconectou de Briar</string>
|
||||
<string name="reminder_notification_text">Toque para voltar a conectar</string>
|
||||
@@ -137,7 +111,6 @@
|
||||
<string name="help">Axuda</string>
|
||||
<string name="sorry">Desculpe</string>
|
||||
<string name="error_start_activity">Non dispoñible para o teu sistema</string>
|
||||
<string name="status_heading">Estado</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Sen contactos para amosar</string>
|
||||
<string name="no_contacts_action">Toque a icona + para engadir un contacto</string>
|
||||
@@ -195,6 +168,7 @@
|
||||
<string name="connecting_to_device">Conectando co dispositivo\u2026</string>
|
||||
<string name="authenticating_with_device">Autenticándose co dispositivo\u2026</string>
|
||||
<string name="connection_error_title">Non se puido conectar co contacto</string>
|
||||
<string name="connection_error_explanation">Por favor, comprobe que ambas están conectadas a mesma rede Wi-Fi.</string>
|
||||
<string name="connection_error_feedback">Si persiste o problema,<a href="feedback">envíe un informe</a> para axudarnos a mellorar a app.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Engadir contacto a distancia</string>
|
||||
@@ -435,20 +409,10 @@
|
||||
<string name="pref_theme_auto">Automático (no día)</string>
|
||||
<string name="pref_theme_system">Por omisión do sistema</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Conexións</string>
|
||||
<string name="bluetooth_setting">Conectar cos contactos vía Bluetooth</string>
|
||||
<string name="wifi_setting">Conectar cos contactos na mesma rede Wi-Fi</string>
|
||||
<string name="tor_enable_title">Conectar cos contactos a través de internet</string>
|
||||
<string name="tor_enable_summary">Todas as conexións a través da rede Tor para ter privacidade</string>
|
||||
<string name="tor_network_setting">Método de conexión á rede Tor</string>
|
||||
<string name="tor_network_setting_automatic">Automática baseada na localización</string>
|
||||
<string name="tor_network_setting_without_bridges">Usar rede Tor sen pontes</string>
|
||||
<string name="tor_network_setting_with_bridges">Usar rede Tor con pontes</string>
|
||||
<string name="tor_network_setting_never">Non conectar a internet</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Automático: %1$s (en %2$s)</string>
|
||||
<string name="tor_mobile_data_title">Utilizar datos móbiles</string>
|
||||
<string name="tor_only_when_charging_title">Conectar a internet só cando carga batería</string>
|
||||
<string name="tor_only_when_charging_summary">Desactiva a conexión a internet cando o dispositivo utiliza a batería</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Seguridade</string>
|
||||
@@ -549,7 +513,6 @@
|
||||
<string name="permission_camera_location_title">Cámara e localización</string>
|
||||
<string name="permission_camera_location_request_body">Para escanear o código QR, Briar precisa acceso a cámara.\n\nPara descubrir dispositivos Bluetooth, Briar precisa permiso a súa localización.\n\nBriar non garda a súa localización nin a comparte con ninguén.</string>
|
||||
<string name="permission_camera_denied_body">Denegou o permiso de acceso a cámara, pero é necesario para engadir contactos.\n\nPor favor, considere conceder o permiso.</string>
|
||||
<string name="permission_location_denied_body">Denegache o acceso á localización, mais Briar precisa este permiso para descubrir dispositivos Bluetooth.\n\nConsidera conceder o permiso.</string>
|
||||
<string name="qr_code">Código QR</string>
|
||||
<string name="show_qr_code_fullscreen">Amosar o código QR a pantalla completa</string>
|
||||
<!--App Locking-->
|
||||
@@ -559,8 +522,6 @@
|
||||
<string name="lock_unlock_password">Utilizar contrasinal</string>
|
||||
<string name="lock_is_locked">Briar está bloqueada</string>
|
||||
<string name="lock_tap_to_unlock">Toque para desbloquear</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar pode conectar cos teus contactos a través de Internet, Wi-Fi ou Bluetooth.\n\nTodas as conexións a internet pasan a través da rede Tor para máis privacidade.\n\nSe un contacto é accesible de múltiples xeitos, Briar usaráos en paralelo.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alice</string>
|
||||
|
||||
@@ -63,36 +63,10 @@
|
||||
<string name="lock_button">נעל יישום</string>
|
||||
<string name="settings_button">הגדרות</string>
|
||||
<string name="sign_out_button">התנתק</string>
|
||||
<string name="transports_onboarding_text">הקש כאן כדי לשלוט איך Briar מתחבר אל אנשי הקשר שלך.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">אינטרנט</string>
|
||||
<string name="tor_device_status_online_wifi">לטלפון שלך יש גישת אינטרנט באמצעות Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">לטלפון שלך יש חיבור אינטרנט באמצעות נתונים סלולריים</string>
|
||||
<string name="tor_device_status_offline">לטלפון שלך אין גישת אינטרנט</string>
|
||||
<string name="tor_plugin_status_enabling">Briar מתחבר אל האינטרנט</string>
|
||||
<string name="tor_plugin_status_active">Briar מחובר אל האינטרנט</string>
|
||||
<string name="tor_plugin_status_inactive">Briar אינו יכול להתחבר אל האינטרנט</string>
|
||||
<string name="tor_plugin_status_disabled">Briar מתוצר לא להשתמש באינטרנט</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar מתוצר לא להשתמש בנתונים סלולריים</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar מתוצר לא להשתמש באינטרנט בעת הרצה על סוללה</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar מתוצר לא להשתמש באינטרנט במדינה זו</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_bt">שן כחולה</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">אותה רשת Wi-Fi</string>
|
||||
<string name="lan_device_status_on">הטלפון שלך מחובר אל Wi-Fi</string>
|
||||
<string name="lan_device_status_off">הטלפון שלך אינו מחובר אל Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar מתחבר אל רשת ה־Wi-Fi</string>
|
||||
<string name="lan_plugin_status_active">Briar מחובר אל רשת ה־Wi-Fi</string>
|
||||
<string name="lan_plugin_status_inactive">Briar אינו יכול להתחבר אל רשת ה־Wi-Fi</string>
|
||||
<string name="lan_plugin_status_disabled">Briar מתוצר לא להשתמש ברשת ה־Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Bluetooth של הטלפון שלך מופעל</string>
|
||||
<string name="bt_device_status_off">Bluetooth של הטלפון שלך מכובה</string>
|
||||
<string name="bt_plugin_status_enabling">Briar מתחבר אל Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar מחובר אל Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar אינו יכול להתחבר אל Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar מתוצר לא להשתמש ב־Bluetooth</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">נותקת מן Briar</string>
|
||||
<string name="reminder_notification_text">הקש כדי להתחבר חזרה.</string>
|
||||
@@ -147,7 +121,6 @@
|
||||
<string name="help">עזרה</string>
|
||||
<string name="sorry">סליחה</string>
|
||||
<string name="error_start_activity">בלתי זמין במערכת שלך</string>
|
||||
<string name="status_heading">מצב</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">אין אנשי קשר להראות</string>
|
||||
<string name="no_contacts_action">הקש על הצלמית + כדי להוסיף איש קשר</string>
|
||||
@@ -205,6 +178,7 @@
|
||||
<string name="connecting_to_device">מתחבר אל מכשיר\u2026</string>
|
||||
<string name="authenticating_with_device">מזדהה מול המכשיר\u2026</string>
|
||||
<string name="connection_error_title">לא היה ניתן להתחבר אל איש הקשר שלך</string>
|
||||
<string name="connection_error_explanation">אנא בדוק ששניכם מחוברים אל אותה רשת Wi-Fi.</string>
|
||||
<string name="connection_error_feedback">אם בעיה נמשכת, אנא <a href="feedback">שלח משוב</a> כדי לעזור לנו לשפר את היישום.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">הוסף איש קשר בקרבה</string>
|
||||
@@ -459,20 +433,10 @@
|
||||
<string name="pref_theme_auto">אוטומטי (שעות יום)</string>
|
||||
<string name="pref_theme_system">ברירת מחדל</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">חיבורים</string>
|
||||
<string name="bluetooth_setting">התחבר אל אנשי קשר באמצעות Bluetooth</string>
|
||||
<string name="wifi_setting">התחבר אל אנשי קשר באותה רשת Wi-Fi</string>
|
||||
<string name="tor_enable_title">התחבר אל אנשי קשר באמצעות האינטרנט</string>
|
||||
<string name="tor_enable_summary">כל החיבורים עוברים דרך רשת Tor למען פרטיות</string>
|
||||
<string name="tor_network_setting">שיטת חיבור עבור רשת Tor</string>
|
||||
<string name="tor_network_setting_automatic">אוטומטי על סמך מיקום</string>
|
||||
<string name="tor_network_setting_without_bridges">השתמש ברשת Tor בלי גשרים</string>
|
||||
<string name="tor_network_setting_with_bridges">השתמש ברשת Tor עם גשרים</string>
|
||||
<string name="tor_network_setting_never">אל תתחבר אל האינטרנט</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">אוטומטי: %1$s (תוך %2$s)</string>
|
||||
<string name="tor_mobile_data_title">השתמש בנתונים סלולריים</string>
|
||||
<string name="tor_only_when_charging_title">התחבר אל האינטרנט רק בעת טעינה</string>
|
||||
<string name="tor_only_when_charging_summary">משבית חיבור אינטרנט כשהמכשיר עובד על סוללה</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">אבטחה</string>
|
||||
@@ -569,7 +533,7 @@
|
||||
<string name="permission_camera_title">הרשאת מצלמה</string>
|
||||
<string name="permission_camera_request_body">כדי לסרוק את קוד ה־QR, היישום Briar צריך גישה אל המצלמה.</string>
|
||||
<string name="permission_location_title">הרשאת מיקום</string>
|
||||
<string name="permission_location_request_body">כדי לגלות מכשירי Bluetooth, היישום Briar צריך הרשאה להשיג גישה אל מיקומך.\n\nBriar אינו מאחסן את מיקומך או משתף אותו עם אף אחד.</string>
|
||||
<string name="permission_location_request_body">כדי לגלות מכשירי שן־כחולה, Briar צריך הרשאה להשיג גישה אל מיקומך.\n\nBriar אינו מאחסן את מיקומך או משתף אותו עם אף אחד.</string>
|
||||
<string name="permission_camera_location_title">מצלמה ומיקום</string>
|
||||
<string name="permission_camera_location_request_body">כדי לסרוק את קוד ה־QR, היישום Briar צריך הרשאה אל המצלמה.\n\nכדי לגלות מכשירי שן־כחולה, Briar צריך הרשאה להשיג גישה אל מיקומך.\n\nBriar אינו מאחסן את מיקומך או משתף אותו עם אף אחד.</string>
|
||||
<string name="permission_camera_denied_body">דחית גישה אל המצלמה, אבל הוספת אנשי קשר דורשת שימוש במצלמה.\n\nאנא שקול הענקת גישה.</string>
|
||||
@@ -582,8 +546,6 @@
|
||||
<string name="lock_unlock_password">השתמש בסיסמה</string>
|
||||
<string name="lock_is_locked">Briar נעול</string>
|
||||
<string name="lock_tap_to_unlock">הקש כדי לבטל נעילה</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar יכול להתחבר אל אנשי הקשר שלך באמצעות האינטרנט, Wi-Fi או Bluetooth.\n\nכל חיבורי האינטרנט עוברים דרך רשת Tor למען פרטיות.\n\nאם איש קשר ניתן להשגה באמצעות שיטות רבות, Briar משתמש בהן במקביל.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">נועה</string>
|
||||
|
||||
@@ -57,12 +57,10 @@
|
||||
<string name="lock_button">लॉक ऐप</string>
|
||||
<string name="settings_button">सेटिंग्स</string>
|
||||
<string name="sign_out_button">साइन आउट</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">इंटरनेट</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">वाई - फाई</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">ब्लूटूथ</string>
|
||||
<string name="transport_lan">वाई - फाई</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Briar से साइन आउट हो रहा है ...</string>
|
||||
<string name="reminder_notification_text">वापस साइन इन करने के लिए टैप करें।</string>
|
||||
@@ -108,7 +106,6 @@
|
||||
<string name="fix">ठीक कर</string>
|
||||
<string name="help">सहायता</string>
|
||||
<string name="sorry">माफ़ कीजिये</string>
|
||||
<string name="status_heading">स्थिति</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">दिखाने के लिए कोई संपर्क नहीं है</string>
|
||||
<string name="no_contacts_action">संपर्क जोड़ने के लिए + आइकन टैप करें</string>
|
||||
@@ -154,6 +151,7 @@
|
||||
<string name="connecting_to_device">उपकरण \ u2026 से कनेक्ट हो रहा है</string>
|
||||
<string name="authenticating_with_device">डिवाइस के साथ प्रमाणीकरण \ u2026</string>
|
||||
<string name="connection_error_title">आपके संपर्क से कनेक्ट नहीं हो सका</string>
|
||||
<string name="connection_error_explanation">कृपया जांचें कि आप दोनों एक ही वाई-फाई नेटवर्क से जुड़े हुए हैं।</string>
|
||||
<string name="connection_error_feedback">यदि यह समस्या बनी रहती है, तो कृपया ऐप को बेहतर बनाने में हमारी सहायता के लिए <a href="feedback">फ़ीडबैक भेजें</a>।</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">दूरी वाले संपर्क जोड़ें</string>
|
||||
@@ -506,7 +504,6 @@
|
||||
<string name="lock_unlock_password">पासवर्ड का प्रयोग करें</string>
|
||||
<string name="lock_is_locked">Briar लॉक है</string>
|
||||
<string name="lock_tap_to_unlock">अनलॉक करने के लिए टैप करें</string>
|
||||
<!--Connections Screen-->
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">ऐलिस</string>
|
||||
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">App zárolása</string>
|
||||
<string name="settings_button">Beállítások</string>
|
||||
<string name="sign_out_button">Kijelentkezés</string>
|
||||
<string name="transports_onboarding_text">Érintse meg itt, hogy beállíthassa, hogyan csatlakozzon a Tor kapcsolataihoz.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">A telefonja Internet hozzáféréssel rendelkezik Wi-Fi-n keresztül</string>
|
||||
<string name="tor_device_status_online_mobile">A telefonja Internet hozzáféréssel rendelkezik mobil hálózaton keresztül</string>
|
||||
<string name="tor_device_status_offline">A telefonja nem rendelkezik Internet hozzáféréssel</string>
|
||||
<string name="tor_plugin_status_enabling">A Briar csatlakozik az Internethez</string>
|
||||
<string name="tor_plugin_status_active">A Briar csatlakoztatva az Internethez</string>
|
||||
<string name="tor_plugin_status_inactive">A Briar nem tud csatlakozni az Internethez</string>
|
||||
<string name="tor_plugin_status_disabled">A Briar Internet nélküli használatra van beállítva</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">A Briar mobil hálózat nélküli használatra van beállítva</string>
|
||||
<string name="tor_plugin_status_disabled_battery">A Briar úgy van beállítva, hogy ne használjon Internetet, ha akkumulátorról megy a telefon</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">A Briar úgy van beállítva, hogy ne használjon Internetet ebben az országban</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Azonos Wi-Fi hálózat</string>
|
||||
<string name="lan_device_status_on">A telefonja Wi-Fi-hez csatlakoztatott.</string>
|
||||
<string name="lan_device_status_off">A telefonja Wi-Fi-hez nem csatlakoztatott.</string>
|
||||
<string name="lan_plugin_status_enabling">A Briar csatlakozik a Wi-Fi hálózathoz</string>
|
||||
<string name="lan_plugin_status_active">A Briar csatlakoztatva a Wi-Fi hálózathoz</string>
|
||||
<string name="lan_plugin_status_inactive">A Briar nem tud csatlakozni a Wi-Fi hálózathoz</string>
|
||||
<string name="lan_plugin_status_disabled">A Briar Wi-Fi nélküli használatra van beállítva</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">A telefonja Bluetooth-ja bekapcsolva</string>
|
||||
<string name="bt_device_status_off">A telefonja Bluetooth-ja kikapcsolva</string>
|
||||
<string name="bt_plugin_status_enabling">A Briar csatlakozik a Bluetooth-hoz</string>
|
||||
<string name="bt_plugin_status_active">A Briar csatlakoztatva a Bluetooth-hoz</string>
|
||||
<string name="bt_plugin_status_inactive">A Briar nem tud csatlakozni a Bluetooth-hoz</string>
|
||||
<string name="bt_plugin_status_disabled">A Briar Bluetooth nélküli használatra van beállítva</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Kilépve a Briar-ból</string>
|
||||
<string name="reminder_notification_text">Érintse meg az újra belépéshez.</string>
|
||||
@@ -137,7 +111,6 @@
|
||||
<string name="help">Súgó</string>
|
||||
<string name="sorry">Sajnáljuk</string>
|
||||
<string name="error_start_activity">Nem elérhető az ön rendszerén</string>
|
||||
<string name="status_heading">Állapot</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Nincs megjeleníthető kapcsolat</string>
|
||||
<string name="no_contacts_action">Érintse meg a + gombot kapcsolatok hozzáadásához</string>
|
||||
@@ -197,6 +170,7 @@ Biztosan szeretné menteni?</string>
|
||||
<string name="connecting_to_device">Csatlakozás az eszközhöz\u2026</string>
|
||||
<string name="authenticating_with_device">Azonosítás az eszközzel\u2026</string>
|
||||
<string name="connection_error_title">Nem sikerült csatlakozni a kapcsolatához</string>
|
||||
<string name="connection_error_explanation">Ellenőrizzék, hogy mindketten ugyanahhoz a Wi-Fi hálózathoz vannak-e csatlakozva.</string>
|
||||
<string name="connection_error_feedback">Ha ez a probléma tartósan fennáll, kérjük <a href="feedback">küldjön visszajelzést</a> nekünk, hogy segítsen fejleszteni az appot.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Távoli kapcsolat hozzá adása</string>
|
||||
@@ -444,19 +418,10 @@ Kapcsolatai, akivel megosztotta ezt a blogot, lehet nem kapnak többé frissít
|
||||
<string name="pref_theme_system">Rendszer alapértelmezett</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Kapcsolatok</string>
|
||||
<string name="bluetooth_setting">Csatlakozás a kapcsolatokhoz Bluetooth-on</string>
|
||||
<string name="wifi_setting">Csatlakozás az egy Wi-Fi hálózaton lévő kapcsolatokhoz</string>
|
||||
<string name="tor_enable_title">Csatlakozás a kapcsolatokhoz Interneten</string>
|
||||
<string name="tor_enable_summary">Minden kapcsolat átmegy a Tor hálózaton az adatvédelem érdekében</string>
|
||||
<string name="tor_network_setting">Kapcsolódási mód a Tor hálózathoz</string>
|
||||
<string name="tor_network_setting_automatic">Automatikusan hely alapján</string>
|
||||
<string name="tor_network_setting_without_bridges">Tor hálózat használata hidak nélkül</string>
|
||||
<string name="tor_network_setting_with_bridges">Tor hálózat használata hidakkal</string>
|
||||
<string name="tor_network_setting_never">Ne csatlakozzon az internethez</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Automatikus: %1$s ( %2$s)</string>
|
||||
<string name="tor_mobile_data_title">Mobil adat használata</string>
|
||||
<string name="tor_only_when_charging_title">Csatlakozás az internethez csak töltés alatt</string>
|
||||
<string name="tor_only_when_charging_summary">Letiltja az internet kapcsolatot, amikor elemről fut az eszköz</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Biztonság</string>
|
||||
@@ -567,8 +532,6 @@ Vigyázat: Ez végleg törli az identitásait, kapcsolatait és üzeneteit</stri
|
||||
<string name="lock_unlock_password">Jelszó használata</string>
|
||||
<string name="lock_is_locked">A Briar zárolt</string>
|
||||
<string name="lock_tap_to_unlock">Érintse meg a zárolás feloldásához</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">A Briar Interneten, Wi-Fi-n vagy Bluetooth-on keresztül csatlakozhat kapcsolataihoz.\n\nAz összes internetkapcsolat a Tor hálózaton megy keresztül megy az adatvédelem érdekében.\n\nHa egy kapcsolatot több módszerrel is el lehet érni, Briar párhuzamosan használja azokat.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alice</string>
|
||||
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">Læsa forriti</string>
|
||||
<string name="settings_button">Stillingar</string>
|
||||
<string name="sign_out_button">Skrá út</string>
|
||||
<string name="transports_onboarding_text">Ýttu hér til að stýra hvernig Briar tengist tengiliðunum þínum.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">Síminn þinn er með aðgang að internetinu í gegnum Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">Síminn þinn er með aðgang að internetinu í gegnum farsímagögn</string>
|
||||
<string name="tor_device_status_offline">Síminn þinn er ekki með aðgang að internetinu</string>
|
||||
<string name="tor_plugin_status_enabling">Briar er að tengjast við internetið</string>
|
||||
<string name="tor_plugin_status_active">Briar er tengt við internetið</string>
|
||||
<string name="tor_plugin_status_inactive">Briar getur ekki tengst við internetið</string>
|
||||
<string name="tor_plugin_status_disabled">Briar er sett upp til að nota ekki internetið</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar er sett upp til að nota ekki farsímagögn</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar er sett upp til að nota ekki internetið þegar keyrt er á rafhlöðu</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar er sett upp til að nota ekki internetið í þessu landi</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Þráðlaust Wi-Fi net</string>
|
||||
<string name="transport_lan_long">Sama þráðlausa Wi-Fi netkerfið</string>
|
||||
<string name="lan_device_status_on">Síminn þinn er tengdur við Wi-Fi</string>
|
||||
<string name="lan_device_status_off">Síminn þinn er ekki tengdur við Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar er að tengjast við Wi-Fi-netið</string>
|
||||
<string name="lan_plugin_status_active">Briar er tengt við við Wi-Fi-netið</string>
|
||||
<string name="lan_plugin_status_inactive">Briar getur ekki tengst við Wi-Fi-netið</string>
|
||||
<string name="lan_plugin_status_disabled">Briar er sett upp til að nota ekki Wi-Fi-netið</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Kveikt er á Bluetooth-kerfi símans</string>
|
||||
<string name="bt_device_status_off">Slökkt er á Bluetooth-kerfi símans</string>
|
||||
<string name="bt_plugin_status_enabling">Briar er að tengjast við Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar er tengt við Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar getur ekki tengst við Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar er sett upp til að nota ekki Bluetooth</string>
|
||||
<string name="transport_lan">Þráðlaust Wi-Fi net</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Skráð út úr Briar</string>
|
||||
<string name="reminder_notification_text">Ýttu til að skrá þig aftur inn.</string>
|
||||
@@ -137,7 +111,6 @@
|
||||
<string name="help">Hjálp</string>
|
||||
<string name="sorry">Því miður</string>
|
||||
<string name="error_start_activity">Er ekki tiltækt fyrir kerfið þitt</string>
|
||||
<string name="status_heading">Staða</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Engir tengiliðir til að birta</string>
|
||||
<string name="no_contacts_action">Ýttu á + táknið til að bæta við tengilið</string>
|
||||
@@ -195,6 +168,7 @@
|
||||
<string name="connecting_to_device">Tengist við tæki\u2026</string>
|
||||
<string name="authenticating_with_device">Auðkenni við tæki\u2026</string>
|
||||
<string name="connection_error_title">Gat ekki tengst við tengiliðinn þinn</string>
|
||||
<string name="connection_error_explanation">Athugaðu hvort þið séuð ekki báðir tengdir við sama þráðlausa Wi-Fi netið.</string>
|
||||
<string name="connection_error_feedback">Ef þetta vandamál er viðvarandi, ættirðu að <a href="feedback">senda umsögn</a> til að hjálpa okkur að bæta forritið.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Bæta við fjarlægum tengilið</string>
|
||||
@@ -435,29 +409,19 @@
|
||||
<string name="pref_theme_auto">Sjálfvirkt (eftir tíma dags)</string>
|
||||
<string name="pref_theme_system">Sjálfgefið í kerfinu</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Tengingar</string>
|
||||
<string name="bluetooth_setting">Tengjast tengiliðum í gegnum Bluetooth</string>
|
||||
<string name="wifi_setting">Tengjast tengiliðum á sama þráðlausa Wi-Fi neti</string>
|
||||
<string name="tor_enable_title">Tengjast tengiliðum í gegnum internetið</string>
|
||||
<string name="tor_enable_summary">Allar tengingar fara í gegnum Tor-netið til að vernda persónuupplýsingar</string>
|
||||
<string name="tor_network_setting">Aðferðir til tengingar við Tor-netið</string>
|
||||
<string name="tor_network_setting_automatic">Sjálfvirkt byggt á staðsetningu</string>
|
||||
<string name="tor_network_setting_without_bridges">Nota Tor-netkerfið án brúa</string>
|
||||
<string name="tor_network_setting_with_bridges">Nota Tor-netkerfið með brúm</string>
|
||||
<string name="tor_network_setting_never">Ekki tengjast við internetið</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Sjálfvirkt: %1$s (eftir %2$s)</string>
|
||||
<string name="tor_mobile_data_title">Nota farsímagagnasamband</string>
|
||||
<string name="tor_only_when_charging_title">Tengjast í gegnum internetið aðeins þegar verið er í hleðslu</string>
|
||||
<string name="tor_only_when_charging_summary">Gerir internettengingu óvirka þegar tækið keyrir á rafhlöðu</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Öryggi</string>
|
||||
<string name="pref_lock_title">Forritslæsing</string>
|
||||
<string name="pref_lock_summary">Notaðu skjálæsingu tækisins til að vernda Briar á meðan þú ert skráð/ur inn</string>
|
||||
<string name="pref_lock_disabled_summary">Til að nota þetta þarftu að setja upp skjálæsingu fyrir tækið þitt</string>
|
||||
<string name="pref_lock_timeout_title">Tímamörk læsingar forrits við aðgerðaleysi</string>
|
||||
<string name="pref_lock_timeout_title">Tímamörk forritslæsingar við aðgerðaleysi</string>
|
||||
<!--The %s placeholder is replaced with the following time spans, e.g. 5 Minutes, 1 Hour-->
|
||||
<string name="pref_lock_timeout_summary">Þegar ekki er verið að nota Briar, læsa því sjálfvirkt eftir %s</string>
|
||||
<string name="pref_lock_timeout_summary">Þehar ekki er verið að nota Briar, læsa því sjálfvirkt eftir %s</string>
|
||||
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
|
||||
<string name="pref_lock_timeout_1">1 mínúta</string>
|
||||
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
|
||||
@@ -558,8 +522,6 @@
|
||||
<string name="lock_unlock_password">Nota lykilorð</string>
|
||||
<string name="lock_is_locked">Briar er læst</string>
|
||||
<string name="lock_tap_to_unlock">Ýttu til að aflæsa</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar getur tengst við tengiliðina þína í gegnum internet, Wi-Fi eða Bluetooth.\n\nAllar internettengingar fara í gegnum Tor-netkerfið til að gæta gagnaleyndar.\n\nEf hægt er að nálgast tengilið með mörgum leiðum, notar Briar þær samhliða.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Lísa</string>
|
||||
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">Blocca app</string>
|
||||
<string name="settings_button">Impostazioni</string>
|
||||
<string name="sign_out_button">Esci</string>
|
||||
<string name="transports_onboarding_text">Tocca qui per controllare come Briar si connette ai tuoi contatti.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">Il tuo telefono ha accesso internet via Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">Il tuo telefono ha accesso internet via dati mobili</string>
|
||||
<string name="tor_device_status_offline">Il tuo telefono non ha accesso internet</string>
|
||||
<string name="tor_plugin_status_enabling">Briar si sta connettendo a internet</string>
|
||||
<string name="tor_plugin_status_active">Briar è connesso a internet</string>
|
||||
<string name="tor_plugin_status_inactive">Briar non riesce a connettersi a internet</string>
|
||||
<string name="tor_plugin_status_disabled">Briar è configurato per non usare internet</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar è configurato per non usare i dati mobili</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar è configurato per non usare internet quando funziona a batteria</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar è configurato per non usare internet in questa nazione</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Stessa rete Wi-Fi</string>
|
||||
<string name="lan_device_status_on">Il tuo telefono è connesso al Wi-Fi</string>
|
||||
<string name="lan_device_status_off">Il tuo telefono non è connesso al Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar si sta connettendo alla rete Wi-Fi</string>
|
||||
<string name="lan_plugin_status_active">Briar è connesso alla rete Wi-Fi</string>
|
||||
<string name="lan_plugin_status_inactive">Briar non riesce a connettersi alla rete Wi-Fi</string>
|
||||
<string name="lan_plugin_status_disabled">Briar è configurato per non usare la rete Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Il Bluetooth del tuo telefono è acceso</string>
|
||||
<string name="bt_device_status_off">Il Bluetooth del tuo telefono è spento</string>
|
||||
<string name="bt_plugin_status_enabling">Briar si sta connettendo al Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar è connesso al Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar non riesce a connettersi al Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar è configurato per non usare il Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Uscito da Briar</string>
|
||||
<string name="reminder_notification_text">Tocca per riaccedere.</string>
|
||||
@@ -137,7 +111,6 @@
|
||||
<string name="help">Aiuto</string>
|
||||
<string name="sorry">Scusa</string>
|
||||
<string name="error_start_activity">Non disponibile sul tuo sistema</string>
|
||||
<string name="status_heading">Stato</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Nessun contatto da mostrare</string>
|
||||
<string name="no_contacts_action">Tocca l\'icona + per aggiungere un contatto</string>
|
||||
@@ -195,6 +168,7 @@
|
||||
<string name="connecting_to_device">Connessione al dispositivo\u2026</string>
|
||||
<string name="authenticating_with_device">Autenticazione con il dispositivo\u2026</string>
|
||||
<string name="connection_error_title">Impossibile connettersi al tuo contatto</string>
|
||||
<string name="connection_error_explanation">Verifica di essere entrambi connessi alla stessa rete Wi-Fi.</string>
|
||||
<string name="connection_error_feedback">Se il problema persiste, <a href="feedback">invia un feedback</a> per aiutarci a migliorare l\'app.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Aggiungi contatto distante</string>
|
||||
@@ -436,19 +410,10 @@
|
||||
<string name="pref_theme_system">Predefinito di sistema</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Connessioni</string>
|
||||
<string name="bluetooth_setting">Connetti ai contatti attraverso Bluetooth</string>
|
||||
<string name="wifi_setting">Connetti ai contatti nella stessa rete Wi-Fi</string>
|
||||
<string name="tor_enable_title">Connetti ai contatti attraverso internet</string>
|
||||
<string name="tor_enable_summary">Tutte le connessioni passano attraverso la rete Tor per privacy</string>
|
||||
<string name="tor_network_setting">Metodo di connessione per la rete Tor</string>
|
||||
<string name="tor_network_setting_automatic">Automatico basato sulla posizione</string>
|
||||
<string name="tor_network_setting_without_bridges">Usa la rete Tor senza bridge</string>
|
||||
<string name="tor_network_setting_with_bridges">Usa la rete Tor con bridge</string>
|
||||
<string name="tor_network_setting_never">Non connettere a internet</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Automatico: %1$s (in %2$s)</string>
|
||||
<string name="tor_mobile_data_title">Usa dati mobili</string>
|
||||
<string name="tor_only_when_charging_title">Connetti a internet solo durante la ricarica</string>
|
||||
<string name="tor_only_when_charging_summary">Disattiva la connessione internet quando il dispositivo funziona a batteria</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Sicurezza</string>
|
||||
@@ -558,8 +523,6 @@
|
||||
<string name="lock_unlock_password">Usa password</string>
|
||||
<string name="lock_is_locked">Briar è bloccato</string>
|
||||
<string name="lock_tap_to_unlock">Tocca per sbloccare</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar può connettersi ai tuoi contatti tramite internet, Wi-Fi o Bluetooth.\n\nTutte le connessioni internet passano attraverso la rete Tor per privacy.\n\nSe un contatto può essere raggiunto con più metodi, Briar li usa in parallelo.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alice</string>
|
||||
|
||||
@@ -56,12 +56,10 @@
|
||||
<string name="lock_button">アプリをロック</string>
|
||||
<string name="settings_button">設定</string>
|
||||
<string name="sign_out_button">サインアウト</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">インターネット</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Briarからサインアウト</string>
|
||||
<string name="reminder_notification_text">タップして再ログインします。</string>
|
||||
@@ -103,7 +101,6 @@
|
||||
<string name="fix">修復する</string>
|
||||
<string name="help">ヘルプ</string>
|
||||
<string name="sorry">すみません</string>
|
||||
<string name="status_heading">状態</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">表示する連絡先がありません</string>
|
||||
<string name="no_contacts_action">「+」アイコンをタップして連絡先を追加</string>
|
||||
@@ -149,6 +146,7 @@
|
||||
<string name="connecting_to_device">デバイスに接続中\u2026</string>
|
||||
<string name="authenticating_with_device">デバイス同士での認証中\u2026</string>
|
||||
<string name="connection_error_title">連絡先に接続できませんでした</string>
|
||||
<string name="connection_error_explanation">あなたと連絡相手、両方が同じWi-Fiネットワークに接続していることを確認してください。</string>
|
||||
<string name="connection_error_feedback">この問題が解決しない場合、アプリを改善するために<a href="feedback">フィードバック</a>を送信してください。</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">離れた場所にいる相手を連絡先に追加</string>
|
||||
@@ -497,7 +495,6 @@
|
||||
<string name="lock_unlock_password">パスワードを使用</string>
|
||||
<string name="lock_is_locked">Briarはロックされています</string>
|
||||
<string name="lock_tap_to_unlock">タップしてロック解除</string>
|
||||
<!--Connections Screen-->
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">アリス</string>
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
<!--Login-->
|
||||
<string name="enter_password">비밀번호</string>
|
||||
<string name="try_again">잘못된 비밀번호입니다. 다시 시도하세요.</string>
|
||||
<string name="dialog_title_cannot_check_password">비밀번호를 확인할 수 없습니다</string>
|
||||
<string name="dialog_message_cannot_check_password">비밀번호를 확인할 수 없었습니다. 이 문제를 해결하기 위해 기기를 재시작 해 보세요.</string>
|
||||
<string name="sign_in_button">로그인</string>
|
||||
<string name="forgotten_password">비밀번호를 잊어버렸습니다</string>
|
||||
<string name="dialog_title_lost_password">비밀번호 분실</string>
|
||||
@@ -43,9 +41,7 @@
|
||||
<item quantity="other">이 Briar는 테스트용입니다. %d일 내에 계정이 만료되고 다시 되돌리지 못합니다.</item>
|
||||
</plurals>
|
||||
<string name="expiry_date_reached">이 소프트웨어는 만료되었습니다. \ n 테스트 해 주셔서 감사합니다!</string>
|
||||
<string name="download_briar">Briar를 계속 이용하기 위해서는 최신 버전을 다운로드 해 주세요.</string>
|
||||
<string name="create_new_account">새로운 계정을 만들어야 하지만, 같은 별명을 사용할 수 있습니다.</string>
|
||||
<string name="download_briar_button">최신 버전 다운로드 받기</string>
|
||||
<string name="startup_open_database">데이터베이스를 복호화하고 있습니다....</string>
|
||||
<string name="startup_migrate_database">데이터베이스를 업그레이드 하고 있습니다...</string>
|
||||
<string name="startup_compact_database">데이터베이스를 작게 만들고 있습니다...</string>
|
||||
@@ -60,36 +56,10 @@
|
||||
<string name="lock_button">앱 잠그기</string>
|
||||
<string name="settings_button">설정</string>
|
||||
<string name="sign_out_button">로그아웃</string>
|
||||
<string name="transports_onboarding_text">여기를 눌러 Briar가 연락처와 연결하는 방법을 설정하세요.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">인터넷</string>
|
||||
<string name="tor_device_status_online_wifi">와이파이를 통해 인터넷에 연결하고 있습니다</string>
|
||||
<string name="tor_device_status_online_mobile">모바일 데이터로 인터넷에 연결하고 있습니다</string>
|
||||
<string name="tor_device_status_offline">인터넷에 연결돼 있지 않습니다</string>
|
||||
<string name="tor_plugin_status_enabling">인터넷에 연결하고 있습니다</string>
|
||||
<string name="tor_plugin_status_active">인터넷에 연결했습니다</string>
|
||||
<string name="tor_plugin_status_inactive">인터넷에 연결하지 못했습니다</string>
|
||||
<string name="tor_plugin_status_disabled">인터넷을 사용하지 않도록 설정돼 있습니다</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">모바일 데이터를 사용하지 않도록 설정돼 있습니다</string>
|
||||
<string name="tor_plugin_status_disabled_battery">충전하지 않고 있을 때에는 인터넷을 사용하지 않도록 설정돼 있습니다</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">이 국가에서는 인터넷을 사용하지 않도록 설정돼 있습니다</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">동일한 와이파이 네트워크입니다</string>
|
||||
<string name="lan_device_status_on">와이파이에 연결돼 있습니다</string>
|
||||
<string name="lan_device_status_off">와이파이에 연결돼 있지 않습니다</string>
|
||||
<string name="lan_plugin_status_enabling">와이파이에 연결 중입니다</string>
|
||||
<string name="lan_plugin_status_active">와이파이에 연결됐습니다</string>
|
||||
<string name="lan_plugin_status_inactive">와이파이에 연결하지 못했습니다</string>
|
||||
<string name="lan_plugin_status_disabled">와이파이를 사용하지 않도록 설정돼 있습니다</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">블루투스</string>
|
||||
<string name="bt_device_status_on">블루투스가 켜져 있습니다</string>
|
||||
<string name="bt_device_status_off">블루투스가 꺼져 있습니다</string>
|
||||
<string name="bt_plugin_status_enabling">블루투스에 연결 중입니다</string>
|
||||
<string name="bt_plugin_status_active">블루투스에 연결했습니다</string>
|
||||
<string name="bt_plugin_status_inactive">블루투스에 연결하지 못했습니다</string>
|
||||
<string name="bt_plugin_status_disabled">블루투스를 사용하지 않도록 설정돼 있습니다</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Briar에서 로그아웃 됨</string>
|
||||
<string name="reminder_notification_text">눌러서 다시 로그인하세요.</string>
|
||||
@@ -131,8 +101,6 @@
|
||||
<string name="fix">고치기</string>
|
||||
<string name="help">도움</string>
|
||||
<string name="sorry">죄송합니다</string>
|
||||
<string name="error_start_activity">이 시스템에서는 지원되지 않습니다</string>
|
||||
<string name="status_heading">상태</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">저장된 연락처가 없습니다</string>
|
||||
<string name="no_contacts_action">+ 상징을 눌러서 연락처를 추가하세요</string>
|
||||
@@ -147,17 +115,6 @@
|
||||
<string name="set_contact_alias">연락처 이름 바꾸기</string>
|
||||
<string name="set_contact_alias_hint">연락처 이름</string>
|
||||
<string name="set_alias_button">바꾸기</string>
|
||||
<string name="delete_all_messages">모든 메시지 지우기</string>
|
||||
<string name="dialog_title_delete_all_messages">메시지 삭제 확인</string>
|
||||
<string name="dialog_message_delete_all_messages">정말로 모든 메시지를 지우려고 하시나요?</string>
|
||||
<string name="dialog_title_not_all_messages_deleted">모든 메시지를 지울 수는 없었습니다</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_both">진행 중인 초대와 소개와 관련된 메시지는 완료되기 전에는 지울 수 없습니다.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_introductions">진행 중인 소개와 관련된 메시지는 완료되기 전에는 지울 수 없습니다.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_invitations">진행 중인 초대와 관련된 메시지는 완료되기 전에는 지울 수 없습니다.</string>
|
||||
<string name="dialog_message_not_deleted_partly_downloaded">부분적으로 다운로드 된 메시지는 다운로드가 완료되기 전까지는 지울 수 없습니다.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_both">초대나 소개를 지우기 위해서는 요청을 선택하고 답을 주셔야 합니다.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_introductions">소개를 지우기 위해서는 요청을 선택하고 답을 주셔야 합니다.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_invitations">초대를 지우기 위해서는 요청을 선택하고 답을 주셔야 합니다.</string>
|
||||
<string name="delete_contact">연락처 삭제하기</string>
|
||||
<string name="dialog_title_delete_contact">연락처 삭제 확인</string>
|
||||
<string name="dialog_message_delete_contact">정말로 이 연락처, 그리고 이 연락처와의 메시지를 모두 제거하시겠어요?</string>
|
||||
@@ -173,9 +130,8 @@
|
||||
<string name="dialog_message_no_image_support">지인 분의 Briar가 이미지 첨부를 지원하지 않습니다. 이 분이 업그레이드하면 다른 상징을 볼 수 있습니다.</string>
|
||||
<string name="dialog_title_image_support">이제 이 분에게 이미지를 보낼 수 있습니다</string>
|
||||
<string name="dialog_message_image_support">이 상징을 눌러 이미지를 첨부하세요.</string>
|
||||
<string name="messaging_too_many_attachments_toast">첫 %d개의 이미지만 보내질 것입니다</string>
|
||||
<!--Adding Contacts-->
|
||||
<string name="add_contact_title">근처의 연락처 추가하기</string>
|
||||
<string name="add_contact_title">주위의 지인 추가하기</string>
|
||||
<string name="face_to_face">연락처를 추가하려는 사람과 먼저 만나야 합니다.\n\n나중에 누군가 당신인 척 하거나 메시지를 훔쳐보는 것을 방지할 수 있습니다.</string>
|
||||
<string name="continue_button">계속하기</string>
|
||||
<string name="try_again_button">다시 시도하기</string>
|
||||
@@ -190,11 +146,12 @@
|
||||
<string name="connecting_to_device">\u2026 기기에 연결하고 있습니다</string>
|
||||
<string name="authenticating_with_device">\u2026 기기와 인증하고 있습니다</string>
|
||||
<string name="connection_error_title">연락처에 연결하지 못했습니다</string>
|
||||
<string name="connection_error_explanation">둘 다 같은 Wi-Fi 네트워크에 연결돼 있는지 확인해 보세요.</string>
|
||||
<string name="connection_error_feedback">문제가 계속된다면, 부디 <a href="feedback">피드백을 남겨서</a> 앱이 좋아지게 도와주세요.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">원거리에서 연락처 추가하기</string>
|
||||
<string name="add_contact_nearby_title">근처의 연락처 추가하기</string>
|
||||
<string name="add_contact_remotely_title">원거리에서 연락처 추가하기</string>
|
||||
<string name="add_contact_remotely_title_case">멀리서 지인 추가하기</string>
|
||||
<string name="add_contact_nearby_title">주위의 지인 추가하기</string>
|
||||
<string name="add_contact_remotely_title">멀리서 지인 추가하기</string>
|
||||
<string name="contact_link_intro">지인 분에게서 받은 링크를 여기에 입력하세요</string>
|
||||
<string name="contact_link_hint">지인 분의 링크</string>
|
||||
<string name="paste_button">붙여 넣기</string>
|
||||
@@ -234,9 +191,8 @@
|
||||
<string name="offline_state">인터넷에 연결되지 않음</string>
|
||||
<string name="duplicate_link_dialog_title">중복되는 링크입니다</string>
|
||||
<string name="duplicate_link_dialog_text_1">%s: 이미 이 링크를 통한 연락 요청이 있습니다.</string>
|
||||
<string name="duplicate_link_dialog_text_1_contact">%s: 이 링크의 연락처가 이미 있습니다.</string>
|
||||
<!--This is a question asking whether two nicknames refer to the same person-->
|
||||
<string name="duplicate_link_dialog_text_2">%s 님과 %s 님이 같은 사람인가요?</string>
|
||||
<string name="duplicate_link_dialog_text_2">%s과(와) %s이(가) 같은 사람인가요?</string>
|
||||
<!--This is a button for answering that two nicknames do indeed refer to the same person. This
|
||||
string will be used in a dialog button, so if the translation of this string is longer than 20
|
||||
characters, please use "Yes" instead, and use "No" for the "Different Person" button-->
|
||||
@@ -245,7 +201,7 @@
|
||||
will be used in a dialog button, so if the translation of this string longer than 20 characters,
|
||||
please use "No" instead, and use "Yes" for the "Same Person" button-->
|
||||
<string name="different_person_button">다른 사람</string>
|
||||
<string name="duplicate_link_dialog_text_3">%s 님과 %s 님이 동일한 링크를 보냈습니다.\n\n누군가 당신의 연락처를 찾으려고 하는 것일 수도 있습니다.\n\n둘 중 누구에게라도 다른 사람에게서 동일한 링크를 받았다고 알리지 마십시오.</string>
|
||||
<string name="duplicate_link_dialog_text_3">%s과(와) %s이(가) 같은 링크를 보냈습니다.\n\n둘 중 하나가 당신의 지인이 누군지 알아내려고 하는 것일 수도 있습니다.\n\n둘 중 누구에게라도 다른 사람에게서 같은 링크를 받았다고 알리지 마십시오.</string>
|
||||
<string name="pending_contact_updated_toast">남은 연락 요청이 있는지 확인했습니다</string>
|
||||
<!--Introductions-->
|
||||
<string name="introduction_onboarding_title">지인 소개하기</string>
|
||||
@@ -259,19 +215,19 @@
|
||||
<string name="introduction_sent">소개시켰습니다.</string>
|
||||
<string name="introduction_error">소개시키는 과정에서 문제가 있었습니다.</string>
|
||||
<string name="introduction_request_sent">%2$s에게 %1$s을(를) 소개하고 싶다고 전했습니다.</string>
|
||||
<string name="introduction_request_received">%1$s 님이 %2$s 님에게 소개하고 싶다고 합니다. %2$s 님을 연락처 목록에 추가하고 싶으십니까?</string>
|
||||
<string name="introduction_request_exists_received">%1$s 님이 당신을 %2$s 님에게 소개하고 싶다고 하지만, %2$s 님은 이미 연락처 목록에 있습니다. %1$s 님이 아직 모르고 있을 수 있으니, 아직 응할 수 있습니다:</string>
|
||||
<string name="introduction_request_answered_received">%1$s 님이 당신을 %2$s 님에게 소개시키고 싶다고 합니다.</string>
|
||||
<string name="introduction_request_received">%1$s이(가) %2$s에게 소개하고 싶다고 합니다. %2$s을(를) 연락처 목록에 추가하고 싶으십니까?</string>
|
||||
<string name="introduction_request_exists_received">%1$s이(가) %2$s에게 소개하고 싶다고 물었지만, %2$s은(는) 이미 연락처 목록에 있습니다. %1$s이(가) 아직 이 부분을 모르고 있을 수 있으니, 아직 응할 수 있습니다:</string>
|
||||
<string name="introduction_request_answered_received">%1$s이(가) %2$s에게 소개시키고 싶다고 물었습니다.</string>
|
||||
<string name="introduction_response_accepted_sent">%1$s에게 소개되고 싶다고 했습니다.</string>
|
||||
<string name="introduction_response_accepted_sent_info">%1$s 님이 소개를 승락해야 연락처에 추가될 수 있습니다. 여기서 시간이 좀 걸릴 수 있습니다.</string>
|
||||
<string name="introduction_response_accepted_sent_info">%1$s이(가) 당신의 연락처를 받기 전에, 그 쪽에서도 소개를 승락해야 합니다. 여기서 시간이 좀 걸릴 수 있습니다.</string>
|
||||
<string name="introduction_response_declined_sent">%1$s에게 소개되고 싶지 않다고 했습니다.</string>
|
||||
<string name="introduction_response_accepted_received">%1$s 님이 %2$s 님과의 소개를 승락했습니다.</string>
|
||||
<string name="introduction_response_declined_received">%1$s 님이 %2$s 님과의 소개를 거절했습니다.</string>
|
||||
<string name="introduction_response_declined_received_by_introducee">%1$s 님은 %2$s 님이 소개를 거절했다고 합니다.</string>
|
||||
<string name="introduction_response_accepted_received">%1$s이(가) %2$s에게 소개해도 괜찮다고 했습니다.</string>
|
||||
<string name="introduction_response_declined_received">%1$s이(가) %2$s에게 소개되고 싶지 않다고 했습니다.</string>
|
||||
<string name="introduction_response_declined_received_by_introducee">%1$s이(가) %2$s이(가) 소개되고 싶지 않다고 합니다.</string>
|
||||
<!--Private Groups-->
|
||||
<string name="groups_list_empty">모임이 없습니다.</string>
|
||||
<string name="groups_list_empty_action">+ 상징을 눌러 모임을 만들거나, 연락하는 분에게 모임을 공유해 달라고 여쭤보세요</string>
|
||||
<string name="groups_created_by">%s 님이 만듦</string>
|
||||
<string name="groups_list_empty_action">+ 상징을 눌러 모임을 만들거나, 연락하는 분에게 모임을 공유해 달라고 물어보세요</string>
|
||||
<string name="groups_created_by">%s이(가) 만듦</string>
|
||||
<plurals name="messages">
|
||||
<item quantity="other">메시지 %d개</item>
|
||||
</plurals>
|
||||
@@ -286,9 +242,9 @@
|
||||
<string name="groups_member_list">구성원 목록</string>
|
||||
<string name="groups_invite_members">구성원 초대하기</string>
|
||||
<string name="groups_member_created_you">모임을 만들었습니다</string>
|
||||
<string name="groups_member_created">%s 님이 모임을 만들었습니다</string>
|
||||
<string name="groups_member_created">%s이(가) 모임을 만들었습니다</string>
|
||||
<string name="groups_member_joined_you">모임에 참가했습니다</string>
|
||||
<string name="groups_member_joined">%s 님이 모임에 참가했습니다</string>
|
||||
<string name="groups_member_joined">%s이(가) 모임에 참가했습니다</string>
|
||||
<string name="groups_leave">모임 나가기</string>
|
||||
<string name="groups_leave_dialog_title">모임 떠나기 확인</string>
|
||||
<string name="groups_leave_dialog_message">정말로 이 모임을 나가고 싶으신가요?</string>
|
||||
@@ -301,7 +257,7 @@
|
||||
<!--Private Group Invitations-->
|
||||
<string name="groups_invitations_title">모임 초대장</string>
|
||||
<string name="groups_invitations_invitation_sent">%1$s을(를) \"%2$s\" 모임에 참가하도록 초대했습니다.</string>
|
||||
<string name="groups_invitations_invitation_received">%1$s 님이 \"%2$s\" 모임에 참가하도록 초대했습니다.</string>
|
||||
<string name="groups_invitations_invitation_received">%1$s이(가) \"%2$s\" 모임에 참가하도록 초대했습니다.</string>
|
||||
<string name="groups_invitations_joined">모임에 참가했습니다</string>
|
||||
<string name="groups_invitations_declined">모임 초대장 거절함</string>
|
||||
<plurals name="groups_invitations_open">
|
||||
@@ -309,19 +265,19 @@
|
||||
</plurals>
|
||||
<string name="groups_invitations_response_accepted_sent">%s(으)로부터 받은 초대장을 승락했습니다.</string>
|
||||
<string name="groups_invitations_response_declined_sent">%s(으)로부터의 모임 초대장을 거절했습니다.</string>
|
||||
<string name="groups_invitations_response_accepted_received">%s 님이 모임 초대장을 승락했습니다.</string>
|
||||
<string name="groups_invitations_response_declined_received">%s 님이 모임 초대장을 거절했습니다.</string>
|
||||
<string name="groups_invitations_response_accepted_received">%s이(가) 모임 초대장을 승락했습니다.</string>
|
||||
<string name="groups_invitations_response_declined_received">%s이(가) 모임 초대장을 거절했습니다.</string>
|
||||
<string name="sharing_status_groups">모임을 만든 분만 새로운 구성원을 초대할 수 있습니다. 다음은 모임의 모든 현재 구성원입니다.</string>
|
||||
<!--Private Groups Revealing Contacts-->
|
||||
<string name="groups_reveal_contacts">연락처 공개하기</string>
|
||||
<string name="groups_reveal_contacts">연락처 보이기</string>
|
||||
<string name="groups_reveal_dialog_message">이 모임의 지금과 앞으로 들어올 구성원에게 연락처를 공개할지를 정할 수 있습니다.\n\n연락처를 공개하면, 모임을 만든 사람이 오프라인이어도 공개된 연락처와 연결할 수 있기 때문에 모임에 더 빠르고 안정적으로 연결할 수 있습니다.</string>
|
||||
<string name="groups_reveal_visible">연락처 관계가 모임에서 보입니다</string>
|
||||
<string name="groups_reveal_visible_revealed_by_us">(당신이) 모임에게 지인 관계 공개합니다</string>
|
||||
<string name="groups_reveal_visible_revealed_by_contact">(%s님이) 모임에게 지인 관계를 공개합니다</string>
|
||||
<string name="groups_reveal_invisible">모임에게 지인 관계를 공개하지 않습니다</string>
|
||||
<string name="groups_reveal_visible_revealed_by_us">연락처 관계가 모임에서 보입니다(본인이 공개)</string>
|
||||
<string name="groups_reveal_visible_revealed_by_contact">연락처 관계가 모임에서 보입니다(%s이(가) 공개)</string>
|
||||
<string name="groups_reveal_invisible">연락처 관계가 모임에서 보이지 않습니다</string>
|
||||
<!--Forums-->
|
||||
<string name="no_forums">보여드릴 포럼이 없습니다</string>
|
||||
<string name="no_forums_action">+ 상징을 눌러 포럼을 만들거나, 연락하는 분에게 포럼을 공유해 달라고 여쭤보세요</string>
|
||||
<string name="no_forums_action">+ 상징을 눌러 포럼을 만들거나, 연락하는 분에게 포럼을 공유해 달라고 물어보세요 </string>
|
||||
<string name="create_forum_title">포럼 만들기</string>
|
||||
<string name="choose_forum_hint">만드실 포럼 이름을 정해주세요</string>
|
||||
<string name="create_forum_button">포럼 만들기</string>
|
||||
@@ -336,7 +292,7 @@
|
||||
<string name="btn_reply">답장</string>
|
||||
<string name="forum_leave">포럼 떠나기</string>
|
||||
<string name="dialog_title_leave_forum">포럼 떠나기 확인</string>
|
||||
<string name="dialog_message_leave_forum">정말로 이 포럼을 떠나려고 하세요?\n\n이 포럼과 공유한 지인이 업데이트를 받지 못할 수 있습니다.</string>
|
||||
<string name="dialog_message_leave_forum">정말로 이 포럼을 떠나려고 하세요?\n\n이 포럼과 공유한 연락처에서 업데이트가 되지 않을 수 있습니다.</string>
|
||||
<string name="dialog_button_leave">떠나기</string>
|
||||
<string name="forum_left_toast">포럼을 떠났습니다</string>
|
||||
<!--Forum Sharing-->
|
||||
@@ -344,11 +300,11 @@
|
||||
<string name="contacts_selected">선택한 연락처</string>
|
||||
<string name="activity_share_toolbar_header">연락처 선택하기</string>
|
||||
<string name="no_contacts_selector">저장된 연락처가 없습니다</string>
|
||||
<string name="no_contacts_selector_action">연락처를 추가한 후에 돌아오세요</string>
|
||||
<string name="forum_shared_snackbar">선택한 지인과 공유하는 포럼</string>
|
||||
<string name="no_contacts_selector_action">연락처를 추가한 후에 돌아오길 바랍니다</string>
|
||||
<string name="forum_shared_snackbar">선택한 지인 분과 공유하는 포럼</string>
|
||||
<string name="forum_share_message">메시지 추가하기(선택 사항)</string>
|
||||
<string name="forum_share_error">포럼을 공유하는 과정에서 문제가 있었습니다</string>
|
||||
<string name="forum_invitation_received">%1$s님이 \"%2$s\" 포럼을 공유했습니다.</string>
|
||||
<string name="forum_invitation_received">%1$s이(가) \"%2$s\" 포럼을 공유했습니다.</string>
|
||||
<string name="forum_invitation_sent">\"%1$s\" 포럼을 %2$s과(와) 공유했습니다.</string>
|
||||
<string name="forum_invitations_title">포럼 초대장</string>
|
||||
<string name="forum_invitation_exists">이미 이 포럼에 초대를 승락했습니다.\n\n초대를 더 많이 승락할수록 더 빠르고 안정적으로 포럼에 연결할 수 있습니다.</string>
|
||||
@@ -358,10 +314,10 @@
|
||||
<string name="forum_invitation_already_sharing">이미 공유하고 있습니다</string>
|
||||
<string name="forum_invitation_response_accepted_sent">%s(으)로부터의 포럼 초대를 승락했습니다.</string>
|
||||
<string name="forum_invitation_response_declined_sent">%s(으)로부터의 포럼 초대를 거절했습니다.</string>
|
||||
<string name="forum_invitation_response_accepted_received">%s님이 포럼 초대장을 승락했습니다.</string>
|
||||
<string name="forum_invitation_response_declined_received">%s 님이 포럼 초대장을 거절했습니다.</string>
|
||||
<string name="forum_invitation_response_accepted_received">%s이(가) 포럼 초대장을 승락했습니다.</string>
|
||||
<string name="forum_invitation_response_declined_received">%s이(가) 포럼 초대장을 거절했습니다.</string>
|
||||
<string name="sharing_status">공유 상태</string>
|
||||
<string name="sharing_status_forum">포럼은 참가한 누구나 자신의 지인과 공유할 수 있습니다. 현재 다음 연락처와 포럼을 공유하고 있습니다. 이외 다른 구성원이 더 있을 수 있습니다.</string>
|
||||
<string name="sharing_status_forum">포럼은 참가한 누구나 지인과 공유할 수 있습니다. 다음 연락처와 포럼을 공유하고 있습니다. 이외 다른 구성원이 더 있을 수 있습니다.</string>
|
||||
<string name="shared_with">와(과) 공유하고 있습니다.(%1$d %2$d명 온라인)</string>
|
||||
<plurals name="forums_shared">
|
||||
<item quantity="other">지인과 공유한 %d개의 포럼</item>
|
||||
@@ -377,9 +333,9 @@
|
||||
<string name="blogs_blog_post_received">새로운 블로그 게시물을 받았습니다</string>
|
||||
<string name="blogs_blog_post_scroll_to">스크롤</string>
|
||||
<string name="blogs_feed_empty_state">게시물이 없습니다</string>
|
||||
<string name="blogs_feed_empty_state_action">지인이 올린 글과 구독한 블로그의 게시물이 여기에 올라옵니다.\n\n게시물을 작성하려면 펜 상징을 누르세요</string>
|
||||
<string name="blogs_feed_empty_state_action">연락처와 구독한 블로그의 게시물이 여기에 나타납니다.\n\n게시물을 쓰려면 펜 상징을 누르세요</string>
|
||||
<string name="blogs_remove_blog">블로그 제거하기</string>
|
||||
<string name="blogs_remove_blog_dialog_message">정말로 이 블로그를 제거하시겠어요?\n\n게시물이 이 기기에서는 제거되지만 다른 사람의 기기에서는 제거되지 않습니다.\n\n이 블로그를 공유하던 지인이 업데이트를 받지 못하게 될 수 있습니다. </string>
|
||||
<string name="blogs_remove_blog_dialog_message">정말로 이 블로그를 제거하시겠어요?\n\n기기에서 게시물은 제거되지만 다른 사람의 기기에서는 제거되지 않습니다.\n\n이 블로그를 공유하던 연락처에서 업데이트가 되지 않을 수 있습니다. </string>
|
||||
<string name="blogs_remove_blog_ok">제거하기</string>
|
||||
<string name="blogs_blog_removed">블로그를 제거했습니다</string>
|
||||
<string name="blogs_reblog_comment_hint">글 추가하기(선택 사항)</string>
|
||||
@@ -388,17 +344,17 @@
|
||||
<string name="blogs_sharing_share">블로그 공유하기</string>
|
||||
<string name="blogs_sharing_error">블로그를 공유하는 과정에서 문제가 있었습니다.</string>
|
||||
<string name="blogs_sharing_button">블로그 공유하기</string>
|
||||
<string name="blogs_sharing_snackbar">선택한 지인과 블로그 공유함</string>
|
||||
<string name="blogs_sharing_snackbar">선택한 지인 분과 블로그 공유함</string>
|
||||
<string name="blogs_sharing_response_accepted_sent">%s(으)로부터 받은 블로그 초대장을 승락했습니다.</string>
|
||||
<string name="blogs_sharing_response_declined_sent">%s(으)로부터의 블로그 초대장을 거절했습니다.</string>
|
||||
<string name="blogs_sharing_response_accepted_received">%s 님이 블로그 초대를 승락했습니다.</string>
|
||||
<string name="blogs_sharing_response_declined_received">%s 님이 블로그 초대장을 거절했습니다.</string>
|
||||
<string name="blogs_sharing_invitation_received">%1$s 님이 \"%2$s\" 블로그를 공유했습니다.</string>
|
||||
<string name="blogs_sharing_response_accepted_received">%s이(가) 블로그 초대를 승락했습니다.</string>
|
||||
<string name="blogs_sharing_response_declined_received">%s이(가) 블로그 초대장을 거절했습니다.</string>
|
||||
<string name="blogs_sharing_invitation_received">%1$s이(가) \"%2$s\" 블로그를 공유했습니다.</string>
|
||||
<string name="blogs_sharing_invitation_sent">%2$s와(과) \"%1$s\" 블로그를 공유했습니다.</string>
|
||||
<string name="blogs_sharing_invitations_title">블로그 초대장</string>
|
||||
<string name="blogs_sharing_joined_toast">블로그에 구독함</string>
|
||||
<string name="blogs_sharing_declined_toast">모임 초대장 거절함</string>
|
||||
<string name="sharing_status_blog">블로그는 구독한 누구나 자신의 지인과 공유할 수 있습니다. 현재 다음 연락처와 이 블로그를 공유하고 있습니다. 이외 다른 구독자가 더 있을 수 있습니다.</string>
|
||||
<string name="sharing_status_blog">블로그는 구독한 누구나 지인과 공유할 수 있습니다. 다음 지인 분과 이 블로그를 공유하고 있습니다. 이외 다른 구독자가 더 있을 수 있습니다.</string>
|
||||
<!--RSS Feeds-->
|
||||
<string name="blogs_rss_feeds_import">RSS 피드 불러오기</string>
|
||||
<string name="blogs_rss_feeds_import_button">가져오기</string>
|
||||
@@ -409,13 +365,13 @@
|
||||
<string name="blogs_rss_feeds_manage_author">작성자:</string>
|
||||
<string name="blogs_rss_feeds_manage_updated">최종 업데이트:</string>
|
||||
<string name="blogs_rss_remove_feed">피드 제거하기</string>
|
||||
<string name="blogs_rss_remove_feed_dialog_message">정말로 이 피드를 제거하시겠어요?\n\n기기에서 게시물은 제거되지만 다른 사람의 기기에서는 제거되지 않습니다.\n\n이 피드를 공유하던 지인이 업데이트를 받지 못하게 될 수 있습니다. </string>
|
||||
<string name="blogs_rss_remove_feed_dialog_message">정말로 이 피드를 제거하시겠어요?\n\n기기에서 게시물은 제거되지만 다른 사람의 기기에서는 제거되지 않습니다.\n\n이 피드를 공유하던 연락처에서 업데이트가 되지 않을 수 있습니다. </string>
|
||||
<string name="blogs_rss_remove_feed_ok">제거하기</string>
|
||||
<string name="blogs_rss_feeds_manage_delete_error">피드를 삭제할 수 없었습니다!</string>
|
||||
<string name="blogs_rss_feeds_manage_empty_state">보여드릴 RSS 피드가 없습니다\n\n+ 상징을 눌러 피드를 불러오세요</string>
|
||||
<string name="blogs_rss_feeds_manage_error">피드를 불러오는 과정에서 문제가 있었습니다. 나중에 다시 시도해 주세요.</string>
|
||||
<!--Settings Display-->
|
||||
<string name="pref_language_title">Language & region</string>
|
||||
<string name="pref_language_title">언어 & 지역</string>
|
||||
<string name="pref_language_changed">Briar를 다시 시작한 후에 설정이 적용됩니다. 부디 로그아웃하고 Briar를 다시 시작해 주세요.</string>
|
||||
<string name="pref_language_default">기본 설정</string>
|
||||
<string name="display_settings_title">화면</string>
|
||||
@@ -425,20 +381,10 @@
|
||||
<string name="pref_theme_auto">자동(시간에 따라)</string>
|
||||
<string name="pref_theme_system">기본 설정</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">연결</string>
|
||||
<string name="bluetooth_setting">블루투스로 지인과 연결하기</string>
|
||||
<string name="wifi_setting">같은 와이파이 네트워크에 연결된 지인과 연결하기</string>
|
||||
<string name="tor_enable_title">인터넷을 통해 지인과 연결하기</string>
|
||||
<string name="tor_enable_summary">프라이버시를 위해 모든 연결은 Tor 네트워크를 거칩니다</string>
|
||||
<string name="tor_network_setting">Tor 네트워크 연결 방식</string>
|
||||
<string name="tor_network_setting_automatic">장소에 따라 자동으로</string>
|
||||
<string name="tor_network_setting_without_bridges">브리지 없이 Tor 네트워크 사용하기</string>
|
||||
<string name="tor_network_setting_with_bridges">브지를 통해 Tor 네트워크 사용하기</string>
|
||||
<string name="tor_network_setting_never">인터넷에 연결하지 않기</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">자동: %1$s(%2$s에서)</string>
|
||||
<string name="tor_mobile_data_title">모바일 데이터 사용하기</string>
|
||||
<string name="tor_only_when_charging_title">충전할 때만 인터넷에 연결하기</string>
|
||||
<string name="tor_only_when_charging_summary">충전 중이지 않을 때에는 인터넷 연결을 비활성화</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title"> 보안</string>
|
||||
@@ -473,12 +419,12 @@
|
||||
<string name="panic_app_setting_summary">설정된 앱이 없습니다</string>
|
||||
<string name="panic_app_setting_none">없음</string>
|
||||
<string name="dialog_title_connect_panic_app">패닉 앱 확인</string>
|
||||
<string name="dialog_message_connect_panic_app">%1$s 님이 파기 권한을 지닌 패닉 버튼 동작을 작동시킬 수 있게 허용하시겠어요?</string>
|
||||
<string name="dialog_message_connect_panic_app">%1$s이(가) 파기 권한을 지닌 패닉 버튼 동작을 작동시킬 수 있게 허용하시겠어요?</string>
|
||||
<string name="panic_setting_destructive_action">파기하기</string>
|
||||
<string name="panic_setting_signout_title">로그아웃</string>
|
||||
<string name="panic_setting_signout_summary">패닉 버튼이 눌리면 Briar에서 로그아웃하기</string>
|
||||
<string name="purge_setting_title">계정 삭제하기</string>
|
||||
<string name="purge_setting_summary">패닉 버튼이 눌리면 Briar 계정을 삭제하기. 주의: 계정, 연락처와 메시지가 영구적으로 지워집니다</string>
|
||||
<string name="purge_setting_summary">패닉 버튼이 눌리면 Briar 계정을 삭제하기 (주의: 계정, 연락처와 메시지가 영구적으로 지워집니다)</string>
|
||||
<!--Settings Notifications-->
|
||||
<string name="notification_settings_title">알림</string>
|
||||
<string name="notify_sign_in_title">로그인 알려주기</string>
|
||||
@@ -548,8 +494,6 @@
|
||||
<string name="lock_unlock_password">비밀번호 사용하기</string>
|
||||
<string name="lock_is_locked">Briar가 잠겼습니다</string>
|
||||
<string name="lock_tap_to_unlock">눌러 잠금해제</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar는 인터넷이나 Wi-Fi, 블루투스를 통해 지인과 연결할 수 있습니다.\n\n인터넷에 연결할 때는 프라이버시를 위해 언제나 Tor 네트워크를 거칩니다.\n\nBriar는 가능한 연락처에 닿을 수 있는 여러 방식을 병용합니다.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">영희</string>
|
||||
|
||||
@@ -26,12 +26,10 @@
|
||||
<!--Login-->
|
||||
<string name="enter_password">Slaptažodis</string>
|
||||
<string name="try_again">Neteisingas slaptažodis, bandykite dar kartą</string>
|
||||
<string name="dialog_title_cannot_check_password">Nepavyksta patikrinti slaptažodžio</string>
|
||||
<string name="dialog_message_cannot_check_password">Briar nepavyksta patikrinti jūsų slaptažodžio. Norėdami išspręsti šią problemą, pabandykite paleisti įrenginį iš naujo.</string>
|
||||
<string name="sign_in_button">Prisijungti</string>
|
||||
<string name="forgotten_password">Aš pamiršau savo slaptažodį</string>
|
||||
<string name="dialog_title_lost_password">Prarastas slaptažodis</string>
|
||||
<string name="dialog_message_lost_password">Jūsų Briar paskyra yra saugoma šifruotu pavidalu jūsų įrenginyje, o ne debesijoje, taigi, negalime atstatyti jūsų slaptažodžio. Ar norėtumėte ištrinti savo paskyrą ir pradėti iš naujo?\n\nDėmesio: Jūsų tapatybės, žinutės ir adresatai bus prarasti visiems laikams.</string>
|
||||
<string name="dialog_message_lost_password">Jūsų Briar paskyra yra saugoma šifruotu pavidalu jūsų įrenginyje, o ne debesijoje, taigi, negalime atstatyti jūsų slaptažodžio Ar norėtumėte ištrinti savo paskyrą ir pradėti iš naujo?\n\nDėmesio: Jūsų tapatybės, žinutės ir adresatai bus prarasti visiems laikams.</string>
|
||||
<string name="startup_failed_notification_title">Nepavyko paleisti Briar</string>
|
||||
<string name="startup_failed_notification_text">Bakstelėkite išsamesnei informacijai.</string>
|
||||
<string name="startup_failed_activity_title">Briar paleidimo nesėkmė</string>
|
||||
@@ -63,36 +61,10 @@
|
||||
<string name="lock_button">Užrakinti programėlę</string>
|
||||
<string name="settings_button">Nustatymai</string>
|
||||
<string name="sign_out_button">Atsijungti</string>
|
||||
<string name="transports_onboarding_text">Bakstelėkite čia norėdami valdyti tai, kaip Briar jungiasi prie jūsų adresatų.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internetas</string>
|
||||
<string name="tor_device_status_online_wifi">Jūsų telefonas jungiasi prie interneto per belaidį (Wi-Fi)</string>
|
||||
<string name="tor_device_status_online_mobile">Jūsų telefonas jungiasi prie interneto per mobiliuosius duomenis</string>
|
||||
<string name="tor_device_status_offline">Jūsų telefonas neprisijungęs prie interneto</string>
|
||||
<string name="tor_plugin_status_enabling">Briar jungiasi prie interneto</string>
|
||||
<string name="tor_plugin_status_active">Briar yra prisijungusi prie interneto</string>
|
||||
<string name="tor_plugin_status_inactive">Briar negali prisijungti prie interneto</string>
|
||||
<string name="tor_plugin_status_disabled">Briar yra sukonfigūruota taip, kad nesinaudotų internetu</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar yra sukonfigūruota taip, kad nesinaudotų mobiliaisiais duomenimis</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar yra sukonfigūruota taip, kad nesinaudotų internetu, kai įrenginys veikia naudodamas akumuliatoriaus energiją</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar yra sukonfigūruota taip, kad šioje šalyje nesinaudotų internetu</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Belaidis (Wi-Fi)</string>
|
||||
<string name="transport_lan_long">Tas pats belaidis (Wi-Fi) tinklas</string>
|
||||
<string name="lan_device_status_on">Jūsų telefonas yra prisijungęs prie belaidžio (Wi-Fi)</string>
|
||||
<string name="lan_device_status_off">Jūsų telefonas nėra prisijungęs prie belaidžio (Wi-Fi)</string>
|
||||
<string name="lan_plugin_status_enabling">Briar jungiasi prie belaidžio (Wi-Fi) tinklo</string>
|
||||
<string name="lan_plugin_status_active">Briar yra prisijungusi prie belaidžio (Wi-Fi) tinklo</string>
|
||||
<string name="lan_plugin_status_inactive">Briar negali prisijungti prie belaidžio (Wi-Fi) tinklo</string>
|
||||
<string name="lan_plugin_status_disabled">Briar yra sukonfigūruota taip, kad nesinaudotų belaidžiu (Wi-Fi) tinklu</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Jūsų telefono Bluetooth ryšys yra įjungtas</string>
|
||||
<string name="bt_device_status_off">Jūsų telefono Bluetooth ryšys yra išjungtas</string>
|
||||
<string name="bt_plugin_status_enabling">Briar jungiasi prie Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar yra prisijungusi prie Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar negali prisijungti prie Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar yra sukonfigūruota taip, kad nesinaudotų Bluetooth</string>
|
||||
<string name="transport_lan">Belaidis (Wi-Fi)</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Atsijungta iš Briar</string>
|
||||
<string name="reminder_notification_text">Bakstelėkite, norėdami prisijungti atgal.</string>
|
||||
@@ -147,7 +119,6 @@
|
||||
<string name="help">Pagalba</string>
|
||||
<string name="sorry">Atsiprašome</string>
|
||||
<string name="error_start_activity">Jūsų sistemoje neprieinama</string>
|
||||
<string name="status_heading">Būsena:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Nėra rodytinų adresatų</string>
|
||||
<string name="no_contacts_action">Norėdami pridėti adresatą, bakstelėkite + piktogramą</string>
|
||||
@@ -191,7 +162,7 @@
|
||||
<string name="messaging_too_many_attachments_toast">Bus išsiųsti tik %d pirmi paveikslai</string>
|
||||
<!--Adding Contacts-->
|
||||
<string name="add_contact_title">Pridėti šalia esantį adresatą</string>
|
||||
<string name="face_to_face">Jūs privalote susitikti gyvai su asmeniu, kurį norite pridėti kaip adresatą.\n\nTai neleis bet kam apsimetinėti jumis ar ateityje skaityti jūsų žinučių.</string>
|
||||
<string name="face_to_face">Jūs privalote susitikti gyvai su asmeniu, kurį norite pridėti kaip adresatą.\n\nTai neleis bet kam apsimetinėti jumis ar ateityje skaityti jūsų žinutes.</string>
|
||||
<string name="continue_button">Tęsti</string>
|
||||
<string name="try_again_button">Bandyti dar kartą</string>
|
||||
<string name="waiting_for_contact_to_scan">Laukiama, kol adresatas nuskenuos ir prisijungs\u2026</string>
|
||||
@@ -205,6 +176,7 @@
|
||||
<string name="connecting_to_device">Jungiamasi prie įrenginio\u2026</string>
|
||||
<string name="authenticating_with_device">Tapatybės nustatymas su įrenginiu\u2026</string>
|
||||
<string name="connection_error_title">Nepavyko prisijungti prie jūsų adresato</string>
|
||||
<string name="connection_error_explanation">Įsitikinkite, kad abu esate prisijungę prie to paties belaidžio (Wi-Fi) tinklo.</string>
|
||||
<string name="connection_error_feedback">Jei ši problema išlieka, <a href="feedback">atsiųskite mums atsiliepimą</a>, kad padėtumėte mums patobulinti programėlę.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Pridėti adresatą per atstumą</string>
|
||||
@@ -455,20 +427,10 @@
|
||||
<string name="pref_theme_auto">Automatinis (Dienos metas)</string>
|
||||
<string name="pref_theme_system">Sistemos numatytasis</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Ryšiai</string>
|
||||
<string name="bluetooth_setting">Jungtis prie adresatų per Bluetooth ryšį</string>
|
||||
<string name="wifi_setting">Jungtis prie adresatų tame pačiame belaidžiame (Wi-Fi) tinkle</string>
|
||||
<string name="tor_enable_title">Jungtis prie adresatų per internetą</string>
|
||||
<string name="tor_enable_summary">Privatumo sumetimais, visi ryšiai jungsis per Tor tinklą</string>
|
||||
<string name="tor_network_setting">Būdas, kaip jungtis prie Tor tinklo</string>
|
||||
<string name="tor_network_setting_automatic">Automatiškai pagal buvimo vietą</string>
|
||||
<string name="tor_network_setting_without_bridges">Naudoti Tor tinklą be tinklų tilto</string>
|
||||
<string name="tor_network_setting_with_bridges">Naudoti Tor tinklą su tinklų tiltu</string>
|
||||
<string name="tor_network_setting_never">Neprisijungti prie interneto</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Automatiškai: %1$s (šalyje %2$s)</string>
|
||||
<string name="tor_mobile_data_title">Naudoti mobiliuosius duomenis</string>
|
||||
<string name="tor_only_when_charging_title">Prisijungti prie interneto tik įkraunant įrenginį</string>
|
||||
<string name="tor_only_when_charging_summary">Išjungia interneto ryšį, kai įrenginys veikia naudodamas akumuliatorių</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Saugumas</string>
|
||||
@@ -569,7 +531,6 @@
|
||||
<string name="permission_camera_location_title">Kamera ir įrenginio vietovė</string>
|
||||
<string name="permission_camera_location_request_body">Tam, kad galėtų nuskenuoti QR kodą, Briar reikia gauti prieigą prie jūsų kameros.\n\nTam, kad galėtų atrasti Bluetooth įrenginius, Briar reikia gauti prieigą prie jūsų įrenginio vietovės.\n\nBriar nesaugo jūsų įrenginio vietovės ir su niekuo jos nebendrina.</string>
|
||||
<string name="permission_camera_denied_body">Jūs uždraudėte prieigą prie kameros, tačiau norint pridėti adresatus, reikia naudoti kamerą.\n\nApsvarstykite galimybę sutekti prieigą prie kameros.</string>
|
||||
<string name="permission_location_denied_body">Jūs uždraudėte prieigą prie įrenginio vietovės, tačiau norint atrasti Bluetooth įrenginius, Briar reikia šio leidimo.\n\nApsvarstykite galimybę sutekti prieigą prie įrenginio vietovės.</string>
|
||||
<string name="qr_code">QR kodas</string>
|
||||
<string name="show_qr_code_fullscreen">Rodyti QR kodą visame ekrane</string>
|
||||
<!--App Locking-->
|
||||
@@ -579,8 +540,6 @@
|
||||
<string name="lock_unlock_password">Naudoti slaptažodį</string>
|
||||
<string name="lock_is_locked">Briar užrakinta</string>
|
||||
<string name="lock_tap_to_unlock">Bakstelėkite, norėdami atrakinti</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar gali jungtis prie jūsų adresatų per internetą, belaidį (Wi-Fi) tinklą ar Bluetooth ryšį.\n\nPrivatumo sumetimais, visi ryšiai jungiasi per Tor tinklą.\n\nJei adresatas gali būti pasiekiamas keliais būdais, tuomet Briar naudoja juos lygiagrečiai.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Jurgita</string>
|
||||
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">Заклучи ја апликацијата</string>
|
||||
<string name="settings_button">Поставки</string>
|
||||
<string name="sign_out_button">Одјави се</string>
|
||||
<string name="transports_onboarding_text">Допрете овде за да контролирате како Briar се поврзува со вашите контакти.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Интернет</string>
|
||||
<string name="tor_device_status_online_wifi">Вашиот телефон има интернет пристап преку Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">Вашиот телефон има интернет пристап преку мобилни податоци</string>
|
||||
<string name="tor_device_status_offline">Вашиот телефон нема интернет пристап</string>
|
||||
<string name="tor_plugin_status_enabling">Briar се поврзува на Интернет</string>
|
||||
<string name="tor_plugin_status_active">Briar е поврзан на Интернет</string>
|
||||
<string name="tor_plugin_status_inactive">Briar не може да се поврзе на Интернет</string>
|
||||
<string name="tor_plugin_status_disabled">Briar е конфигуриран да не користи Интернет</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar е конфигуриран да не користи мобилни податоци</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar е конфигуриран да не користи Интернет додека е работи на батерија</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar е конфигуриран да не користи Интернет во оваа држава</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Иста Wi-Fi мрежа </string>
|
||||
<string name="lan_device_status_on">Вашиот телефон е поврзан на Wi-Fi</string>
|
||||
<string name="lan_device_status_off">Вашиот телефон не е поврзан на Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar се поврзува на Wi-Fi мрежа</string>
|
||||
<string name="lan_plugin_status_active">Briar е поврзан на Wi-Fi мрежата</string>
|
||||
<string name="lan_plugin_status_inactive">Briar сне може да се поврзе на Wi-Fi мрежата</string>
|
||||
<string name="lan_plugin_status_disabled">Briar е конфигуриран да не ја користи Wi-Fi мрежата</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Bluetooth-от на вашиот телефон е вклучен</string>
|
||||
<string name="bt_device_status_off">Bluetooth-от на вашиот телефон е исклучен</string>
|
||||
<string name="bt_plugin_status_enabling">Briar се поврзува со Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar е поврзан со Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar не може да се поврзе со Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar е конфигуриран да не користи Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Одјави се од Briar</string>
|
||||
<string name="reminder_notification_text">Допрете за да се најавите.</string>
|
||||
@@ -137,7 +111,6 @@
|
||||
<string name="help">Помош</string>
|
||||
<string name="sorry">Жал ни е</string>
|
||||
<string name="error_start_activity">Недостапно на вашиот систем</string>
|
||||
<string name="status_heading">Статус:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Нема контакти за прикажување</string>
|
||||
<string name="no_contacts_action">Допрете ја + иконата за да додадете контакт</string>
|
||||
@@ -195,6 +168,7 @@
|
||||
<string name="connecting_to_device">Поврзување со уред\u2026</string>
|
||||
<string name="authenticating_with_device">Автентикација со уред\u2026</string>
|
||||
<string name="connection_error_title">Не може да се поврзе со твојот контакт</string>
|
||||
<string name="connection_error_explanation">Ве молиме проверете дека и двајцата сте поврзани на истата Wi-Fi мрежа.</string>
|
||||
<string name="connection_error_feedback">Ако овој проблем останува, ве молиме <a href="feedback">испратете повратна информација</a> за да ни помогнете да ја подобриме апликацијата.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Додај контакт НА РАСТОЈАНИЕ</string>
|
||||
@@ -435,20 +409,10 @@
|
||||
<string name="pref_theme_auto">Автоматски (Дневно)</string>
|
||||
<string name="pref_theme_system">Систем стандардно поставен</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Поврзувања</string>
|
||||
<string name="bluetooth_setting">Поврзете се контактите преку Bluetooth</string>
|
||||
<string name="wifi_setting">Поврзете се со контактите на истата Wi-Fi мрежа</string>
|
||||
<string name="tor_enable_title">Поврзете се контактите преку Интернет</string>
|
||||
<string name="tor_enable_summary">Сите поврзувања одат преку Tor мрежата поради приватност</string>
|
||||
<string name="tor_network_setting">Метод на поврзување на Tor мрежата</string>
|
||||
<string name="tor_network_setting_automatic">Автоматски базирано на локација</string>
|
||||
<string name="tor_network_setting_without_bridges">Користете Tor мрежа без мостови</string>
|
||||
<string name="tor_network_setting_with_bridges">Користете Tor мрежа со мостови</string>
|
||||
<string name="tor_network_setting_never">Не се поврзувај на Интернет</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Автоматски: %1$s (во %2$s)</string>
|
||||
<string name="tor_mobile_data_title">Користи мобилни податоци</string>
|
||||
<string name="tor_only_when_charging_title">Поврзи на Интернет само за време на полнење</string>
|
||||
<string name="tor_only_when_charging_summary">Оневозможи го Интернет поврзувањето кога уредот не е приклучен на полнач</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Безбедност</string>
|
||||
@@ -548,8 +512,7 @@
|
||||
<string name="permission_location_request_body">За да открие Bluetooth уреди, на Briar му е потребна дозвола за пристап до вашата локација.\n\nBriar не ја зачувува вашата локација или не ја споделува со никого.</string>
|
||||
<string name="permission_camera_location_title">Камера и локација</string>
|
||||
<string name="permission_camera_location_request_body">За да го скенира QR кодот, на Briar му е потребен пристап до камерата.\n\nЗа да открие Bluetooth уреди, на Briar му е потребна дозвола за вашата локација.\n\nBriar не ја зачувува вашата локација или не ја споделува со никого.</string>
|
||||
<string name="permission_camera_denied_body">Го одбивте пристапот до камерата, но за додавање на контакти потребно е користење на камерата.\n\nВе молиме размислете за давање пристап.</string>
|
||||
<string name="permission_location_denied_body">Го одбивте пристапот до вашата локација, но на Briar му е потребна оваа дозвола за да ги открие Bluetooth уредите.\n\nВе молиме размислете за давање пристап.</string>
|
||||
<string name="permission_camera_denied_body">Го одбивте пристапот до камерата, но за додавање на контакти потребно е користење на камерата.\n\nВе молиме размислете за давање дозвола.</string>
|
||||
<string name="qr_code">QR код</string>
|
||||
<string name="show_qr_code_fullscreen">Покажи го QR кодот на цел екран</string>
|
||||
<!--App Locking-->
|
||||
@@ -559,8 +522,6 @@
|
||||
<string name="lock_unlock_password">Користете лозинка</string>
|
||||
<string name="lock_is_locked">Briar е заклучен</string>
|
||||
<string name="lock_tap_to_unlock">Допрете за отклучување</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar може да се поврзе со вашите контакти преку Интернет, Wi-Fi или Bluetooth.\n\nСите Интернет поврзувања одат преку Tor Мрежата поради приватност.\n\nАко контактот може да биде достапен преку повеќе начини, Briar ќе ги користи паралелно. </string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Жарко</string>
|
||||
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">App vergrendelen</string>
|
||||
<string name="settings_button">Instellingen</string>
|
||||
<string name="sign_out_button">Log uit</string>
|
||||
<string name="transports_onboarding_text">Tik hier om in te stellen hoe Briar een verbinding met je contacten opzet.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">Je apparaat heeft internettoegang via wifi</string>
|
||||
<string name="tor_device_status_online_mobile">Je apparaat heeft internettoegang via mobiele dataverbinding</string>
|
||||
<string name="tor_device_status_offline">Je apparaat heeft geen internettoegang</string>
|
||||
<string name="tor_plugin_status_enabling">Briar is aan het verbinden met internet</string>
|
||||
<string name="tor_plugin_status_active">Briar is verbonden met het internet</string>
|
||||
<string name="tor_plugin_status_inactive">Briar kan geen verbinding maken met het internet</string>
|
||||
<string name="tor_plugin_status_disabled">Briar is geconfigureerd om internet niet te gebruiken</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar is geconfigureerd om mobiele dataverbinding niet te gebruiken</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar is geconfigureerd om het internet niet te gebruiken als apparaat op baterij loopt</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar is geconfigureerd om internet niet te gebruiken in dit land</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wifi</string>
|
||||
<string name="transport_lan_long">Hetzelfde wifinetwerk</string>
|
||||
<string name="lan_device_status_on">Je apparaat is verbonden met wifi</string>
|
||||
<string name="lan_device_status_off">Je apparaat is niet verbonden met wifi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar is verbinding aan het maken met het wifinetwerk</string>
|
||||
<string name="lan_plugin_status_active">Briar is verbonden met het wifinetwerk</string>
|
||||
<string name="lan_plugin_status_inactive">Briar kan geen verbinding maken met het wifinetwerk</string>
|
||||
<string name="lan_plugin_status_disabled">Briar is geconfigureerd om het wifinetwerk niet te gebruiken</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Bluetooth op je apparaat staat aan</string>
|
||||
<string name="bt_device_status_off">Bluetooth op je apparaat staat uit</string>
|
||||
<string name="bt_plugin_status_enabling">Briar is aan het verbinden met bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar is verbonden met bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar kan geen verbinding maken met bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar is geconfigureerd om bluetooth niet te gebruiken</string>
|
||||
<string name="transport_lan">Wifi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Uitgelogd van Briar</string>
|
||||
<string name="reminder_notification_text">Tik om opnieuw in te loggen.</string>
|
||||
@@ -137,7 +111,6 @@
|
||||
<string name="help">Help</string>
|
||||
<string name="sorry">Excuses</string>
|
||||
<string name="error_start_activity">Onbeschikbaar op jouw systeem</string>
|
||||
<string name="status_heading">Status:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Er zijn geen contacten om te tonen</string>
|
||||
<string name="no_contacts_action">Tik op het +-icoon om een contact toe te voegen</string>
|
||||
@@ -163,7 +136,7 @@
|
||||
<string name="dialog_message_not_deleted_not_all_selected_both">Om een uitnodiging of introductie te verwijderen met je het verzoek en het antwoord selecteren.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_introductions">Om een introductie te verwijderen met je het verzoek en het antwoord selecteren.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_invitations">Om een uitnodiging te verwijderen met je het verzoek en het antwoord selecteren.</string>
|
||||
<string name="delete_contact">Verwijder contact</string>
|
||||
<string name="delete_contact">Verwijder bericht</string>
|
||||
<string name="dialog_title_delete_contact">Bevestig verwijderen contact</string>
|
||||
<string name="dialog_message_delete_contact">Weet je zeker dat je dit contact en alle berichten die met dit contact zijn uitgewisseld wil verwijderen?</string>
|
||||
<string name="contact_deleted_toast">Contact is verwijderd</string>
|
||||
@@ -195,6 +168,7 @@
|
||||
<string name="connecting_to_device">Aan het verbinden met apparaat\u2026</string>
|
||||
<string name="authenticating_with_device">Aan het authenticeren met apparaat\u2026</string>
|
||||
<string name="connection_error_title">Kon geen verbinding maken met je contact</string>
|
||||
<string name="connection_error_explanation">Controleer alsjeblieft dat jullie beiden met hetzelfde wifinetwerk zijn verbonden.</string>
|
||||
<string name="connection_error_feedback">Als dit probleem aanhoudt, <a href="feedback">stuur feedback</a> alsjeblieft om ons te helpen de app te verbeteren.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Voeg een contact ver weg toe</string>
|
||||
@@ -436,19 +410,10 @@
|
||||
<string name="pref_theme_system">Systeemstandaard</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Verbindingen</string>
|
||||
<string name="bluetooth_setting">Verbind met contacten via bluetooth</string>
|
||||
<string name="wifi_setting">Verbind met contacten over hetzelfde wifinetwerk</string>
|
||||
<string name="tor_enable_title">Verbind met contactenover het internet</string>
|
||||
<string name="tor_enable_summary">Alle verbindingen gaan door het Tornetwerk voor privacy</string>
|
||||
<string name="tor_network_setting">Verbindingsmethose voor Tornetwerk</string>
|
||||
<string name="tor_network_setting_automatic">Automatisch gebaseerd op locatie</string>
|
||||
<string name="tor_network_setting_without_bridges">Gebruikt Tornetwerk zonder bridges</string>
|
||||
<string name="tor_network_setting_with_bridges">Gebruik Tornetwerk met bridges</string>
|
||||
<string name="tor_network_setting_never">Verbind niet met het internet</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Automatisch: %1$s (in %2$s)</string>
|
||||
<string name="tor_mobile_data_title">Gebruik mobiele data</string>
|
||||
<string name="tor_only_when_charging_title">Verbind alleen met het internet tijdens opladen</string>
|
||||
<string name="tor_only_when_charging_summary">Schakel internetverbinding uit als apparaat op batterij loopt</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Beveiliging</string>
|
||||
@@ -545,9 +510,9 @@
|
||||
<string name="permission_camera_title">Cameratoestemming</string>
|
||||
<string name="permission_camera_request_body">Om de QR-code te scannen moet Briar toegang hebben tot de camera.</string>
|
||||
<string name="permission_location_title">Toegang tot locatie</string>
|
||||
<string name="permission_location_request_body">Om bluetoothapparaten te ontdekken heeft Briar toestemming nodig tot je locatie.\n\nBriar slaat je locatie niet op en deelt het met niemand.</string>
|
||||
<string name="permission_location_request_body">Om Bluetooth-apparaten te ontdekken heeft Briar toestemming nodig tot je locatie.\n\nBriar slaat je locatie niet op en deelt het met niemand.</string>
|
||||
<string name="permission_camera_location_title">Camera en locatie</string>
|
||||
<string name="permission_camera_location_request_body">Om de QR-code in te scannen heeft Briar toegang nodig tot de camera.\n\nOm bluetoothapparaten te ontdekken heeft Briar toestemming nodig tot je locatie.\n\nBriar slaat je locatie niet op en deelt het met niemand.</string>
|
||||
<string name="permission_camera_location_request_body">Om de QR-code in te scannen heeft Briar toegang nodig tot de camera.\n\nOm Bluetooth-apparaten te ontdekken heeft Briar toestemming nodig tot je locatie.\n\nBriar slaat je locatie niet op en deelt het met niemand.</string>
|
||||
<string name="permission_camera_denied_body">Je hebt toegang tot de camera niet vrijgegeven, terwijl het toevoegen van contacten de camera nodig heeft.\n\nOverweeg alsjeblieft toegang vrij te geven.</string>
|
||||
<string name="qr_code">QR-code</string>
|
||||
<string name="show_qr_code_fullscreen">Toon QR-code op volledig scherm</string>
|
||||
@@ -558,8 +523,6 @@
|
||||
<string name="lock_unlock_password">Gebruik Wachtwoord</string>
|
||||
<string name="lock_is_locked">Briar is vergrendeld</string>
|
||||
<string name="lock_tap_to_unlock">Tik om te ontgrendelen</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar kan met je contacten verbinden via het internet, wifi of bluetooth.\n\nAlle internetverbindingen gaan voor privacy door het Tornetwerk.\n\nAls een contact via meerdere methoden te bereiken is, zal Briar die parallel gebruiken.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Veerle</string>
|
||||
|
||||
@@ -63,12 +63,10 @@ Volètz suprimir vòstre compte e ne crear un nòu ?\n
|
||||
<string name="lock_button">Verrolhar l’aplicacion</string>
|
||||
<string name="settings_button">Paramètres</string>
|
||||
<string name="sign_out_button">Se desconnectar</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wifi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="transport_lan">Wifi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Desconnectat de Briar</string>
|
||||
<string name="reminder_notification_text">Tocatz per vos desconnectar</string>
|
||||
@@ -169,6 +167,7 @@ Volètz suprimir vòstre compte e ne crear un nòu ?\n
|
||||
<string name="connecting_to_device">Connexion a l’aparelh\u2026</string>
|
||||
<string name="authenticating_with_device">Autentificacion amb l’aparelh\u2026</string>
|
||||
<string name="connection_error_title">Connexion impossibla al contacte</string>
|
||||
<string name="connection_error_explanation">Verificatz que sètz los dos connectats al meteis ret wifi.</string>
|
||||
<string name="connection_error_feedback">S’aqueste problèma dura, mercés <a href="feedback"> d’enviar un comentari</a> per nos ajudar a melhorar l’aplicacion.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Ajustar un contacte a distància</string>
|
||||
@@ -527,7 +526,6 @@ parteja pas amb degun.</string>
|
||||
<string name="lock_unlock_password">Utilizar lo senhal</string>
|
||||
<string name="lock_is_locked">Briar es verrolhat</string>
|
||||
<string name="lock_tap_to_unlock">Tocatz per desverrolhar</string>
|
||||
<!--Connections Screen-->
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alicia</string>
|
||||
|
||||
@@ -59,12 +59,10 @@
|
||||
<string name="lock_button">Zablokuj Aplikację</string>
|
||||
<string name="settings_button">Ustawienia</string>
|
||||
<string name="sign_out_button">Wyloguj się</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Wylogowano z Briar</string>
|
||||
<string name="reminder_notification_text">Dotknij, aby zalogować się ponownie</string>
|
||||
@@ -118,7 +116,6 @@
|
||||
<string name="fix">Napraw</string>
|
||||
<string name="help">Pomoc</string>
|
||||
<string name="sorry">Przepraszam</string>
|
||||
<string name="status_heading">Status</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Brak kontaktów do pokazania</string>
|
||||
<string name="no_contacts_action">Dotknij ikonki + aby dodać kontakt</string>
|
||||
@@ -165,6 +162,7 @@
|
||||
<string name="connecting_to_device">Łączenie z urządzeniem\u2026</string>
|
||||
<string name="authenticating_with_device">Autoryzowanie z urządzeniem\u2026</string>
|
||||
<string name="connection_error_title">Nie udało się połączyć z kontaktem</string>
|
||||
<string name="connection_error_explanation">Sprawdź czy obaj jesteście połączeni z tą samą siecią Wi-Fi.</string>
|
||||
<string name="connection_error_feedback">Jeśli problem będzie występować dalej, proszę <a href="feedback">wysłać zgłoszenie</a> aby pomóc nam ulepszyć aplikację.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Dodaj Kontakt na odległość</string>
|
||||
@@ -528,7 +526,6 @@
|
||||
<string name="lock_unlock_password">Użyj hasła</string>
|
||||
<string name="lock_is_locked">Briar jest zablokowany</string>
|
||||
<string name="lock_tap_to_unlock">Dotknij by odblokować</string>
|
||||
<!--Connections Screen-->
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alicja</string>
|
||||
|
||||
@@ -61,13 +61,10 @@
|
||||
<string name="lock_button">Bloquear Aplicativo</string>
|
||||
<string name="settings_button">Configurações</string>
|
||||
<string name="sign_out_button">Sair</string>
|
||||
<string name="transports_onboarding_text">Clique aqui para controlar como o Briar se conecta aos seus contatos.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="transport_lan">Wi-fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Saiu do Briar</string>
|
||||
<string name="reminder_notification_text">Toque para fazer login novamente.</string>
|
||||
@@ -114,7 +111,6 @@
|
||||
<string name="help">Ajuda</string>
|
||||
<string name="sorry">Sentimos muito</string>
|
||||
<string name="error_start_activity">Indisponível no seu sistema</string>
|
||||
<string name="status_heading">Status:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Sem contatos para exibir</string>
|
||||
<string name="no_contacts_action">Toque no ícone + para adicionar um contato</string>
|
||||
@@ -172,6 +168,7 @@
|
||||
<string name="connecting_to_device">Conectando a device\u2026</string>
|
||||
<string name="authenticating_with_device">Autenticando com o dispositivo\u2026</string>
|
||||
<string name="connection_error_title">Não foi possível conectar-se ao seu contato</string>
|
||||
<string name="connection_error_explanation">Por favor, certifique se ambos estão conectados na mesma rede Wi-Fi.</string>
|
||||
<string name="connection_error_feedback">Se o problema persistir, por favor <a href="feedback">envie um feedback</a> para nos ajudar a melhorar o app.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Adicionar contato à distância</string>
|
||||
@@ -526,7 +523,6 @@
|
||||
<string name="lock_unlock_password">Usar senha</string>
|
||||
<string name="lock_is_locked">O Briar está desbloqueado</string>
|
||||
<string name="lock_tap_to_unlock">Toque para desbloquear</string>
|
||||
<!--Connections Screen-->
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alice</string>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!--Setup-->
|
||||
<string name="setup_title">Bine ați venit la Briar</string>
|
||||
<string name="setup_name_explanation">Numele dumneavoastră va fi afișat lângă orice conținut trimis. Nu îl veți putea schimba după crearea contului.</string>
|
||||
<string name="setup_name_explanation">Numele dumneavoastră va fi afișat lângă orice conținut trimiteți. Nu îl veți putea schimba după crearea contului.</string>
|
||||
<string name="setup_next">Următorul</string>
|
||||
<string name="setup_password_intro">Alegeți o parolă</string>
|
||||
<string name="setup_password_explanation">Contul dvs. Briar este stocat criptat pe dispozitiv, nu în cloud. Dacă vă uitați parola sau ștergeți Briar, nu veți putea să vă recuperați contul.\n\nAlegeți o parolă lungă greu de ghicit, de exemplu, patru cuvinte aleatorii sau zece litere, numere și simboluri aleatoare.</string>
|
||||
@@ -21,7 +21,7 @@
|
||||
<string name="don_t_ask_again">Nu mai întreba din nou</string>
|
||||
<string name="setup_huawei_text">Vă rugăm să apăsați butonul de mai jos și să vă asigurați că Briar este marcat ca protejat în fereastra de \"Aplicații protejate\".</string>
|
||||
<string name="setup_huawei_button">Protejează Briar</string>
|
||||
<string name="setup_huawei_help">Dacă Briar nu este adăugat în lista de aplicații protejate, nu va fi capabil să ruleze în fundal.</string>
|
||||
<string name="setup_huawei_help">Dacă Briar nu este adăugat în lista de aplicații protejate, nu v-a fi capabil să ruleze în fundal.</string>
|
||||
<string name="warning_dozed">%s nu poate rula în fundal</string>
|
||||
<!--Login-->
|
||||
<string name="enter_password">Parola</string>
|
||||
@@ -32,8 +32,8 @@
|
||||
<string name="forgotten_password">Am uitat parola</string>
|
||||
<string name="dialog_title_lost_password">Parolă uitată</string>
|
||||
<string name="dialog_message_lost_password">Contul dvs. Briar este stocat criptat pe dispozitiv, nu în cloud. Dacă vă uitați parola sau ștergeți Briar, nu veți putea să vă recuperați contul. Doriți să vă ștergeți contul și să începeți din nou?\n\nAtenție: identitățile, contactele și mesajele dvs. vor fi pierdute definitiv.</string>
|
||||
<string name="startup_failed_notification_title">Briar nu a putut fi pornit</string>
|
||||
<string name="startup_failed_notification_text">Atingeți pentru informații suplimentare.</string>
|
||||
<string name="startup_failed_notification_title">Briar nu a putut pornii</string>
|
||||
<string name="startup_failed_notification_text">Atingeți pentru informații suplimentare</string>
|
||||
<string name="startup_failed_activity_title">Eroare de pornire Briar</string>
|
||||
<string name="startup_failed_db_error">Din anumite motive, baza dvs. de date Briar este deteriorată fără vreo posibilitate de a o recupera. Contul dvs., datele dvs. și toate persoanele de contact sunt pierdute. Din nefericire, trebuie să reinstalați Briar sau să creați un nou cont, selectând \"Am uitat parola\" la promptul de parolă.</string>
|
||||
<string name="startup_failed_data_too_old_error">Contul dvs. a fost creat cu o versiune veche a acestei aplicații și nu poate fi deschis cu această versiune. Trebuie fie să reinstalați versiunea veche, fie să configurați un nou cont, selectând \"Am uitat parola\" la solicitarea de a introduce parola.</string>
|
||||
@@ -42,7 +42,7 @@
|
||||
<plurals name="expiry_warning">
|
||||
<item quantity="one">Aceasta este o versiune de test pentru Briar. Contul dumneavoastră va expira în %d zi și nu se poate reînnoi</item>
|
||||
<item quantity="few">Aceasta este o versiune de test pentru Briar. Contul dumneavoastră va expira în %d zile și nu se poate reînnoi.</item>
|
||||
<item quantity="other">Aceasta este o versiune de test pentru Briar. Contul dumneavoastră va expira în %d zile și nu poate fi reînnoit.</item>
|
||||
<item quantity="other">Aceasta este o versiune de test pentru Briar. Contul dumneavoastră va expira în %d de zile și nu se poate reînnoi.</item>
|
||||
</plurals>
|
||||
<string name="expiry_date_reached">Acest program a expirat.\nVă mulțumim că l-ați testat!</string>
|
||||
<string name="download_briar">Pentru a putea să utilizați Briar în continuare, vă rugăm să descărcați ultima versiune.</string>
|
||||
@@ -62,36 +62,10 @@
|
||||
<string name="lock_button">Blochează aplicația</string>
|
||||
<string name="settings_button">Setări</string>
|
||||
<string name="sign_out_button">Ieșire</string>
|
||||
<string name="transports_onboarding_text">Atingeți aici pentru a controla modul în care Briar se conectează la contacte</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">Telefonul are acces la internet prin Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">Telefonul are acces la internet prin date mobile</string>
|
||||
<string name="tor_device_status_offline">Telefonul nu are acces la internet</string>
|
||||
<string name="tor_plugin_status_enabling">Briar se conectează la internet</string>
|
||||
<string name="tor_plugin_status_active">Briar este conectat la internet</string>
|
||||
<string name="tor_plugin_status_inactive">Briar nu se poate conecta la internet</string>
|
||||
<string name="tor_plugin_status_disabled">Briar este configurat să nu se conecteze la internet</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar este configurat să nu folosească date mobile</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar este configurat să nu folosească internetul când utilizează bateria</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar este configurat să nu folosească internetul în această țară</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Aceeași rețea Wi-Fi</string>
|
||||
<string name="lan_device_status_on">Telefonul este conectat la Wi-Fi</string>
|
||||
<string name="lan_device_status_off">Telefonul nu este conectat la Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar se conectează la rețeaua Wi-Fi</string>
|
||||
<string name="lan_plugin_status_active">Briar este conectat la rețeaua Wi-Fi</string>
|
||||
<string name="lan_plugin_status_inactive">Briar nu se poate conecta la rețeaua Wi-Fi</string>
|
||||
<string name="lan_plugin_status_disabled">Briar este configurat să nu folosească rețeaua Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Telefonul are Bluetooth pornit</string>
|
||||
<string name="bt_device_status_off">Telefonul nu are Bluetooth pornit</string>
|
||||
<string name="bt_plugin_status_enabling">Briar se conectează la Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar este conectat la Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar nu se poate conecta la Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar este configurat să nu folosească Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Ieșire din Briar</string>
|
||||
<string name="reminder_notification_text">Atingeți pentru autentificare.</string>
|
||||
@@ -102,28 +76,28 @@
|
||||
<plurals name="private_message_notification_text">
|
||||
<item quantity="one">Mesaj privat nou.</item>
|
||||
<item quantity="few">%d mesaje private noi.</item>
|
||||
<item quantity="other">%d mesaje private noi.</item>
|
||||
<item quantity="other">%d de mesaje private noi.</item>
|
||||
</plurals>
|
||||
<plurals name="group_message_notification_text">
|
||||
<item quantity="one">Mesaj nou de grup.</item>
|
||||
<item quantity="few">%d mesaje de grup noi.</item>
|
||||
<item quantity="other">%d mesaje de grup noi.</item>
|
||||
<item quantity="other">%d de mesaje de grup noi.</item>
|
||||
</plurals>
|
||||
<plurals name="forum_post_notification_text">
|
||||
<item quantity="one">Un nou mesaj pe forum.</item>
|
||||
<item quantity="few">%d mesaje noi pe forum.</item>
|
||||
<item quantity="other">%d mesaje noi pe forum.</item>
|
||||
<item quantity="other">%d de mesaje noi pe forum.</item>
|
||||
</plurals>
|
||||
<plurals name="blog_post_notification_text">
|
||||
<item quantity="one">Un nou mesaj pe blog.</item>
|
||||
<item quantity="few">%d mesaje noi pe blog.</item>
|
||||
<item quantity="other">%d mesaje noi pe blog.</item>
|
||||
<item quantity="other">%d de mesaje noi pe blog.</item>
|
||||
</plurals>
|
||||
<!--Misc-->
|
||||
<string name="now">acum</string>
|
||||
<string name="show">Arată</string>
|
||||
<string name="hide">Ascunde</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="ok">Bine</string>
|
||||
<string name="cancel">Anulează</string>
|
||||
<string name="got_it">Am înțeles</string>
|
||||
<string name="delete">Șterge</string>
|
||||
@@ -137,17 +111,16 @@
|
||||
<string name="no_data">Fără date</string>
|
||||
<string name="ellipsis">…</string>
|
||||
<string name="text_too_long">Textul introdus este prea lung</string>
|
||||
<string name="show_onboarding">Arată fereastra de ajutor</string>
|
||||
<string name="show_onboarding">Arata fereastra de ajutor</string>
|
||||
<string name="fix">Rezolvă</string>
|
||||
<string name="help">Ajutor</string>
|
||||
<string name="sorry">Ne pare rău</string>
|
||||
<string name="error_start_activity">Indisponibil pentru sistemul dumneavoastră</string>
|
||||
<string name="status_heading">Status:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Niciun contact de arătat</string>
|
||||
<string name="no_contacts">Nici un contact de arătat</string>
|
||||
<string name="no_contacts_action">Atingeți iconița + pentru a adăuga un contact</string>
|
||||
<string name="date_no_private_messages">Fără mesaje.</string>
|
||||
<string name="no_private_messages">Niciun mesaj de arătat</string>
|
||||
<string name="no_private_messages">Nici un mesaj de arătat</string>
|
||||
<string name="message_hint">Scrieți mesajul</string>
|
||||
<string name="image_caption_hint">Adaugă un subtitlu (opțional)</string>
|
||||
<string name="image_attach">Atașează imagine</string>
|
||||
@@ -200,6 +173,7 @@
|
||||
<string name="connecting_to_device">Conectare la dispozitiv\u2026</string>
|
||||
<string name="authenticating_with_device">Autentificare cu dispozitivul\u2026</string>
|
||||
<string name="connection_error_title">Nu s-a putut face conexiunea la contactul dumneavoastră</string>
|
||||
<string name="connection_error_explanation">Verificați să fiți conectați la aceeași rețea Wi-Fi.</string>
|
||||
<string name="connection_error_feedback">Dacă problema persistă, vă rugăm să <a href="feedback">trimiteți feedback</a> pentru a ne ajuta să îmbunătățim aplicația.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Adaugă un contact la distanță</string>
|
||||
@@ -559,7 +533,6 @@
|
||||
<string name="permission_camera_location_title">Cameră foto și locație</string>
|
||||
<string name="permission_camera_location_request_body">Pentru a scana codul QR, Briar are nevoie să acceseze camera foto.\n\nPentru a putea descoperi dispozitive Bluetooth, Briar are nevoie de permisiunea de a vă accesa locația.\n\nBriar nu vă stochează locația și nici nu o partajează cu nimeni. </string>
|
||||
<string name="permission_camera_denied_body">Ați refuzat accesul la camera foto, dar pentru a adăuga contacte este necesară folosirea camerei foto.\n\nVă rugăm să luați în considerare acordarea accesului.</string>
|
||||
<string name="permission_location_denied_body">Ați refuzat accesul la locație, dar Briar are nevoie de această permisiune pentru a descoperi dispozitive Bluetooth.\n\nVă rugăm să luați în considerare acordarea accesului.</string>
|
||||
<string name="qr_code">Cod QR</string>
|
||||
<string name="show_qr_code_fullscreen">Arată codul QR pe tot ecranul</string>
|
||||
<!--App Locking-->
|
||||
@@ -569,8 +542,6 @@
|
||||
<string name="lock_unlock_password">Folosește parola</string>
|
||||
<string name="lock_is_locked">Briar este blocat</string>
|
||||
<string name="lock_tap_to_unlock">Atingeți pentru a debloca</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar se poate conecta la contactele dumneavoastră prin internet, Wi-Fi sau Bluetooth.\n\nToate conexiunile la internet trec prin rețeaua Tor din motive de confidențialitate.\n\nDacă un contact poate fi accesat prin metode multiple, Briar le va folosi în mod paralel.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alice</string>
|
||||
|
||||
@@ -65,36 +65,10 @@
|
||||
<string name="lock_button">Заблокировать приложение</string>
|
||||
<string name="settings_button">Настройки</string>
|
||||
<string name="sign_out_button">Выйти</string>
|
||||
<string name="transports_onboarding_text">Нажмите здесь, чтобы проверить, как Briar подключается к вашим контактам.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Интернет</string>
|
||||
<string name="tor_device_status_online_wifi">Ваш телефон имеет доступ в интернет через Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">Ваш телефон имеет доступ в интернет через мобильную сеть.</string>
|
||||
<string name="tor_device_status_offline">Ваш телефон не имеет доступа в интернет</string>
|
||||
<string name="tor_plugin_status_enabling">Briar подключается к интернету</string>
|
||||
<string name="tor_plugin_status_active">Briar подключен к интернету</string>
|
||||
<string name="tor_plugin_status_inactive">Briar не может подключиться к интернету.</string>
|
||||
<string name="tor_plugin_status_disabled">Briar настроен не использовать интернет</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar настроен не использовать мобильную сеть</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar настроен не использовать интернет при работе от батареи</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar настроен не использовать интернет в этой стране</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Та же сеть Wi-Fi</string>
|
||||
<string name="lan_device_status_on">Ваш телефон подключен к Wi-Fi</string>
|
||||
<string name="lan_device_status_off">Телефон не подключен к Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar подключается к сети Wi-Fi</string>
|
||||
<string name="lan_plugin_status_active">Briar подключен к сети Wi-Fi</string>
|
||||
<string name="lan_plugin_status_inactive">Briar не может подключиться к сети Wi-Fi.</string>
|
||||
<string name="lan_plugin_status_disabled">Briar настроен не использовать сеть Wi-Fi.</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Bluetooth вашего телефона включен.</string>
|
||||
<string name="bt_device_status_off">Bluetooth вашего телефона отключен.</string>
|
||||
<string name="bt_plugin_status_enabling">Briar подключается к Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar подключен к Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar не может подключиться к Bluetooth.</string>
|
||||
<string name="bt_plugin_status_disabled">Briar настроен не использовать Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Вы не авторизованы в Briar</string>
|
||||
<string name="reminder_notification_text">Нажмите для входа</string>
|
||||
@@ -149,7 +123,6 @@
|
||||
<string name="help">Помощь</string>
|
||||
<string name="sorry">Сожалеем</string>
|
||||
<string name="error_start_activity">Недоступно для вашей системы</string>
|
||||
<string name="status_heading">Статус:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Нет контактов для отображения</string>
|
||||
<string name="no_contacts_action">Для добавления контакта нажмите значок +</string>
|
||||
@@ -207,6 +180,7 @@
|
||||
<string name="connecting_to_device">Подключение к устройству\u2026</string>
|
||||
<string name="authenticating_with_device">Аутентификация с устройством\u2026</string>
|
||||
<string name="connection_error_title">Не удалось подключиться к контакту</string>
|
||||
<string name="connection_error_explanation">Убедитесь, что вы оба подключены к той же сети Wi-Fi.</string>
|
||||
<string name="connection_error_feedback">Если эта проблема сохраняется, пожалуйста <a href="feedback">отправьте отзыв</a>, чтобы помочь нам улучшить приложение.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Добавление контакта на расстоянии</string>
|
||||
@@ -222,7 +196,7 @@
|
||||
<string name="add_contact_choose_nickname">Выберите ник</string>
|
||||
<string name="add_contact_choose_a_nickname">Введите ник</string>
|
||||
<string name="nickname_intro">Дайте вашему контакту ник. Увидеть его сможете только вы.</string>
|
||||
<string name="your_link">Передайте эту ссылку контакту, который вы хотите добавить.</string>
|
||||
<string name="your_link">Передайте эту ссылку контакту, которого вы хотите добавить.</string>
|
||||
<string name="link_clip_label">Ссылка Briar</string>
|
||||
<string name="link_copied_toast">Ссылка скопирована</string>
|
||||
<string name="adding_contact_error">При добавлении контакта произошла ошибка.</string>
|
||||
@@ -457,20 +431,10 @@
|
||||
<string name="pref_theme_auto">Авто (День)</string>
|
||||
<string name="pref_theme_system">Системные настройки</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Подключения</string>
|
||||
<string name="bluetooth_setting">Подключение к контактам через Bluetooth</string>
|
||||
<string name="wifi_setting">Подключение к контактам в той же сети Wi-Fi</string>
|
||||
<string name="tor_enable_title">Подключение к контактам через интернет</string>
|
||||
<string name="tor_enable_summary">Все соединения проходят через сеть Tor для обеспечения конфиденциальности</string>
|
||||
<string name="tor_network_setting">Способ подключения для сети Tor</string>
|
||||
<string name="tor_network_setting_automatic">Автоматически на основе местоположения</string>
|
||||
<string name="tor_network_setting_without_bridges">Использовать сеть Tor без мостов</string>
|
||||
<string name="tor_network_setting_with_bridges">Использовать сеть Tor с мостами</string>
|
||||
<string name="tor_network_setting_never">Не подключаться к интернету</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Автоматически: %1$s (%2$s)</string>
|
||||
<string name="tor_mobile_data_title">Использовать мобильные данные</string>
|
||||
<string name="tor_only_when_charging_title">Подключаться к интернету только во время зарядки</string>
|
||||
<string name="tor_only_when_charging_summary">Отключение интернет-соединения, при работе устройства от батареи</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Безопасность</string>
|
||||
@@ -580,8 +544,6 @@
|
||||
<string name="lock_unlock_password">Использовать пароль</string>
|
||||
<string name="lock_is_locked">Briar заблокирован</string>
|
||||
<string name="lock_tap_to_unlock">Нажмите для разблокировки</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar может подключаться к контактам через интернет, Wi-Fi или Bluetooth.\n\nВсе интернет-соединения проходят через сеть Tor для обеспечения конфиденциальности.\n\nЕсли с контактом можно связаться несколькими способами, Briar использует их параллельно.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Бузова</string>
|
||||
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">Kyçe Aplikacionin</string>
|
||||
<string name="settings_button">Rregullime</string>
|
||||
<string name="sign_out_button">Dilni</string>
|
||||
<string name="transports_onboarding_text">Prekkeni këtu që të kontrolloni se si lidhet Briar-i me kontaktet tuaja.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">Telefoni juaj mund të përdorë Internet përmes Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">Telefoni juaj mund të përdorë Internet përmes të dhënash pakete celulari</string>
|
||||
<string name="tor_device_status_offline">Telefoni juaj s’mund të përdorë Internet</string>
|
||||
<string name="tor_plugin_status_enabling">Briar-i po lidhet me Internetin</string>
|
||||
<string name="tor_plugin_status_active">Briar-i është lidhur me Internetin</string>
|
||||
<string name="tor_plugin_status_inactive">Briar-i s’mund të lidhet me Internetin</string>
|
||||
<string name="tor_plugin_status_disabled">Briar-i është formësuar të mos përdorë Internet</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar-i është formësuar të mos përdorë të dhëna pakete celulari</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar-i është formësuar të mos përdorë Internet, kur xhiron me bateri</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar-i është formësuar të mos përdorë Internet në këtë vend</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Po atë rrjet Wi-Fi</string>
|
||||
<string name="lan_device_status_on">Telefoni juaj është lidhur me Wi-Fi</string>
|
||||
<string name="lan_device_status_off">Telefoni juaj s’është lidhur me Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar-i po lidhet me rrjetin Wi-Fi</string>
|
||||
<string name="lan_plugin_status_active">Briar-i është lidhur me rrjetin Wi-Fi</string>
|
||||
<string name="lan_plugin_status_inactive">Briar-i s’mund të lidhet dot me rrjetin Wi-Fi</string>
|
||||
<string name="lan_plugin_status_disabled">Briar-i është formësuar të mos përdorë rrjetin Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Bluetooth-i i telefonit tuaj është i hapur</string>
|
||||
<string name="bt_device_status_off">Bluetooth-i i telefonit tuaj është i mbyllur</string>
|
||||
<string name="bt_plugin_status_enabling">Briar-i po lidhet me Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar-i është lidhur me Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar-i s’mund të lidhet me Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar-i është formësuar të mos përdorë Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">U dol nga Briar-i</string>
|
||||
<string name="reminder_notification_text">Prekeni që të ribëhet hyrja.</string>
|
||||
@@ -137,7 +111,6 @@
|
||||
<string name="help">Ndihmë</string>
|
||||
<string name="sorry">Na ndjeni</string>
|
||||
<string name="error_start_activity">Jo i passhëm në sistemin tuaj</string>
|
||||
<string name="status_heading">Gjëndja</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">S’ka kontakte për shfaqje</string>
|
||||
<string name="no_contacts_action">Prekni ikonën + që të shtoni një kontakt</string>
|
||||
@@ -195,6 +168,7 @@
|
||||
<string name="connecting_to_device">Po lidhet me pajisjen\u2026</string>
|
||||
<string name="authenticating_with_device">Po bëhet mirëfilltësimi me pajisjen\u2026</string>
|
||||
<string name="connection_error_title">S’u lidh dot te kontakti juaj</string>
|
||||
<string name="connection_error_explanation">Ju lutemi, kontrolloni se jeni të dy të lidhur në të njëjtin rrjet Wi-Fi.</string>
|
||||
<string name="connection_error_feedback">Nëse problemi vazhdon, ju lutemi, <a href="feedback">na njoftoni</a>, që të mund të përmirësojmë aplikacionin.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Shtoni Kontakt në Largësi</string>
|
||||
@@ -549,7 +523,6 @@
|
||||
<string name="permission_camera_location_title">Kamera dhe vend</string>
|
||||
<string name="permission_camera_location_request_body">Që të skanojë kodin QR, Briar-it i duhet të përdorë kamerën.\n\nQë të pikasë pajisje Bluetooth, Briar-i lyp leje të njohë vendin tuaj.\n\nBriar-i nuk e depoziton vendin tuaj, as e ndan me dikë.</string>
|
||||
<string name="permission_camera_denied_body">Keni mohuar hyrjen në kamera, por shtimi i kontakteve lyp përdorimin e kamerës.\n\nJu lutemi, shihni mundësinë e akordimit të hyrjes.</string>
|
||||
<string name="permission_location_denied_body">Keni mohuar hyrje te vendndodhja juaj, por Briar-i ka nevojë për këtë leje, që të mund të zbulojë pajisje Bluetooth.\n\nJu lutemi, shihni mundësinë e akordimit të hyrjes.</string>
|
||||
<string name="qr_code">Kod QR</string>
|
||||
<string name="show_qr_code_fullscreen">Shfaqe kodin QR sa tërë ekrani</string>
|
||||
<!--App Locking-->
|
||||
@@ -559,11 +532,6 @@
|
||||
<string name="lock_unlock_password">Përdor Fjalëkalim</string>
|
||||
<string name="lock_is_locked">Briar-i është i kyçur</string>
|
||||
<string name="lock_tap_to_unlock">Prekeni që të shkyçet</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar-i mund të lidhet me kontaktet tuaja përmes Interneti, Wi-Fi ose Bluetooth-i.\n\n
|
||||
Për privatësi, krejt lidhjet Internet kalojnë përmes rrjetit Tor.\n\n
|
||||
Nëse me një kontakt mund të bëhet lidhja përmes metodash të shumta,\n\n
|
||||
Briar-i i përdor ato paralelisht.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Mira</string>
|
||||
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">Lås appen</string>
|
||||
<string name="settings_button">Inställningar</string>
|
||||
<string name="sign_out_button">Logga ut</string>
|
||||
<string name="transports_onboarding_text">Klicka här för att styra hur Briar ansluter till dina kontakter.</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">Din telefon har internetåtkomst via Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">Din telefon har internetåtkomst via mobildata</string>
|
||||
<string name="tor_device_status_offline">Din telefon har inte internetåtkomst</string>
|
||||
<string name="tor_plugin_status_enabling">Briar ansluter till internet</string>
|
||||
<string name="tor_plugin_status_active">Briar är anslutet till internet</string>
|
||||
<string name="tor_plugin_status_inactive">Briar kan inte ansluta till internet</string>
|
||||
<string name="tor_plugin_status_disabled">Briar är inte konfigurerat för att använda internet</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar är konfigurerat så att de inte använder mobildata</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar är konfigurerat att inte använda internet vid batterianvändning</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar är konfigurerat att inte använda internet i detta landet</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Samma Wi-Fi-nätverk</string>
|
||||
<string name="lan_device_status_on">Din telefon är ansluten till Wi-Fi</string>
|
||||
<string name="lan_device_status_off">Din telefon är inte ansluten till Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar ansluter till Wi-Fi-nätverket</string>
|
||||
<string name="lan_plugin_status_active">Briar är anslutet till Wi-Fi nätverket</string>
|
||||
<string name="lan_plugin_status_inactive">Briar kan inte ansluta till Wi-Fi-nätverket</string>
|
||||
<string name="lan_plugin_status_disabled">Briar är konfigurerat för att inte använda Wi-Fi-nätverket</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Din telefons Bluetooth är aktiverad</string>
|
||||
<string name="bt_device_status_off">Din telefons Bluetooth är inaktiverad</string>
|
||||
<string name="bt_plugin_status_enabling">Briar ansluter till Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar är ansluten till Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar kan inte ansluta till Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar är konfigurerat för att inte använda Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Utloggad från Briar</string>
|
||||
<string name="reminder_notification_text">Tryck för att logga in igen.</string>
|
||||
@@ -137,7 +111,6 @@
|
||||
<string name="help">Hjälp</string>
|
||||
<string name="sorry">Tyvärr</string>
|
||||
<string name="error_start_activity">Otillgänglig på ditt system</string>
|
||||
<string name="status_heading">Status</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Inga kontakter</string>
|
||||
<string name="no_contacts_action">Tryck på plus-ikonen (+) för att lägga till en kontakt</string>
|
||||
@@ -195,6 +168,7 @@
|
||||
<string name="connecting_to_device">Ansluter till enhet\u2026</string>
|
||||
<string name="authenticating_with_device">Autentiserar med enhet\u2026</string>
|
||||
<string name="connection_error_title">Kunde ej ansluta till din kontakt</string>
|
||||
<string name="connection_error_explanation">Kontrollera att ni båda är anslutna på samma Wi-Fi-nätverk.</string>
|
||||
<string name="connection_error_feedback">Om det här problemet kvarstår, vänligen lämna <a href="feedback">synpunkter</a> så vi kan förbättra appen.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Lägg till en kontakt på avstånd</string>
|
||||
@@ -435,20 +409,10 @@
|
||||
<string name="pref_theme_auto">Automatisk (dagtid)</string>
|
||||
<string name="pref_theme_system">Systemets förval</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Anslutningar</string>
|
||||
<string name="bluetooth_setting">Anslut till kontakter via Bluetooth</string>
|
||||
<string name="wifi_setting">Anslut till kontakter på samma Wi-Fi-nätverk</string>
|
||||
<string name="tor_enable_title">Anslut till kontakter via internet</string>
|
||||
<string name="tor_enable_summary">Alla anslutningar gå via Tor-nätverket av integritetsskäl</string>
|
||||
<string name="tor_network_setting">Anslutningsmetod för Tor-nätverket</string>
|
||||
<string name="tor_network_setting_automatic">Automatisk, baserad på position</string>
|
||||
<string name="tor_network_setting_without_bridges">Använd Tor-nätverket utan bryggor</string>
|
||||
<string name="tor_network_setting_with_bridges">Anvädn Tor-nätverket med bryggor</string>
|
||||
<string name="tor_network_setting_never">Anslut inte till internet</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">Automatisk: %1$s (i %2$s)</string>
|
||||
<string name="tor_mobile_data_title">Använd mobildata</string>
|
||||
<string name="tor_only_when_charging_title">Anslut till internet endast vid laddning</string>
|
||||
<string name="tor_only_when_charging_summary">Avaktiverar anslutning över Internet när enheten går på batteri</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Säkerhet</string>
|
||||
@@ -558,8 +522,6 @@
|
||||
<string name="lock_unlock_password">Använd lösenord</string>
|
||||
<string name="lock_is_locked">Briar är låst</string>
|
||||
<string name="lock_tap_to_unlock">Tryck för att låsa upp</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar kan ansluta till dina kontakter via internet, Wi-Fi eller Bluetooth.\n\nAlla internetanslutningar går via Tor-nätverket av integritetsskäl.\n\nOm en kontakt kan nås via flera metoder kommer Briar att använda dem parallellt.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alice</string>
|
||||
|
||||
@@ -5,100 +5,65 @@
|
||||
<string name="setup_name_explanation">lakabu lako litaonekana kwenye kila chapisho lako . Na hutaweza badilisha baada ya kuteneneza akaunti yako .</string>
|
||||
<string name="setup_next">Ifuatayo</string>
|
||||
<string name="setup_password_intro">Chagua neno siri </string>
|
||||
<string name="setup_password_explanation">Akaunti yako ya Briar imeifaziwa katika msimbo fiche kwenye kifaa chako ,nasio kwenye mawingu. Kama utasahau nywila yako au kuondoa Briar, hamana namna unaweza kuokua akaunti yako . \n\nchagua nywila ndefu ambayo ni ngumu kubuniwa , kama maneno mannne ya nasibu, au kumi ya barua za nasibu, namba na herufi.</string>
|
||||
<string name="setup_doze_title">Uhusiano wa nyuma</string>
|
||||
<string name="setup_doze_intro">Kupokea ujumbe kwenye Briar unaitajika uwe umeunganishwa kwenye mkondo.</string>
|
||||
<string name="setup_doze_explanation">li kupokea ujumbe , Briar unatakiwa uwe umeunganishwa kwenye mkongo kwa nyuma . Tafadhali tengua uboreshaji wa betri ili Briar iendele kuunganishwa.</string>
|
||||
<string name="setup_doze_button">Ruhusa kuunganishwa </string>
|
||||
<string name="choose_nickname">Chagua lakabu yako</string>
|
||||
<string name="choose_password">Chagua nywila yako .</string>
|
||||
<string name="confirm_password">Hakikisha nenosiri lako
|
||||
</string>
|
||||
<string name="name_too_long">Jina ni refu sana .</string>
|
||||
<string name="password_too_weak">Nywila yako ni dhaifu
|
||||
</string>
|
||||
<string name="passwords_do_not_match">
|
||||
Nenosiri zako haziendani </string>
|
||||
<string name="create_account_button">Tengeneza akaunti</string>
|
||||
<string name="more_info">Habari za ziada </string>
|
||||
<string name="don_t_ask_again">Usiulize tena </string>
|
||||
<string name="setup_password_explanation">Akaunti yako ya Briar imeifaziwa katika msimbo fiche kwenye kifaa chako ,nasio kwenye mawingu. kama utasahau nywila yako au kuondoa Briar, hamana namna unaweza kuokua akaunti yako . \n\nchagua nywila ndefu ambayo ni ngumu kubuniwa , kama maneno mannne ya nasibu, au kumi ya barua za nasibu, namba na herufi.</string>
|
||||
<string name="setup_doze_title">uhusiano wa nyuma</string>
|
||||
<string name="setup_doze_intro">kupokea ujumbe kwenye Briar unaitajika uwe umeunganishwa kwenye mkondo </string>
|
||||
<string name="setup_doze_explanation">ili kupokea ujumbe , Briar unatakiwa uwe umeunganishwa kwenye mkongo kwa nyuma . Tafathali tengua oboreshaji wa betri ili Briar iendele kuunganishwa.</string>
|
||||
<string name="setup_doze_button">ruhusa kuunganishwa </string>
|
||||
<string name="choose_nickname">chagua lakabu yako</string>
|
||||
<string name="choose_password">chagua Nywila yako
|
||||
chagua nenosiri lako </string>
|
||||
<string name="confirm_password">hakikisha Nywila yako
|
||||
hakikisha nenosiri lako </string>
|
||||
<string name="name_too_long">jina ni refu sana </string>
|
||||
<string name="password_too_weak">Nywila yako ni thahifu
|
||||
nenosiri lako ni thahifu</string>
|
||||
<string name="passwords_do_not_match">nywila zako haziendani
|
||||
nenosiri zako haziendani </string>
|
||||
<string name="create_account_button">tengeneza akauntu</string>
|
||||
<string name="more_info">habari za ziada </string>
|
||||
<string name="don_t_ask_again">usiulize tena </string>
|
||||
<string name="setup_huawei_text">tafathali bonyeza alama hapo chini ili kuhakikisha Briar imelindwa na \"programu Ulizi\" kwenye kioo chako </string>
|
||||
<string name="setup_huawei_button">Linda Briar </string>
|
||||
<string name="setup_huawei_help">
|
||||
Kama Briar haija wekwa kwenye orotha programu ulizi, haitaweza kufanya kazi kwenye nyuma ya mkongo</string>
|
||||
<string name="setup_huawei_help">kama Briar haija wekwa kwenye orotha programu Ulizi, haitaweza kufanya kazi kwenye nyuma ya mkongo</string>
|
||||
<string name="warning_dozed">%shaijawezekana kujiendesha kwa nyuma ya mkongo</string>
|
||||
<!--Login-->
|
||||
<string name="enter_password">Nywila
|
||||
nenosiri</string>
|
||||
<string name="try_again">Umekosea nywila , jaribu tena
|
||||
Umekosea nenosiri, jaribu tena</string>
|
||||
<string name="dialog_title_cannot_check_password">Haiwezi Kuangalia nywila</string>
|
||||
<string name="dialog_message_cannot_check_password">Briar hawezi kuangalia nywila yako. Tafadhali jaribu kuwasha upya kifaa chako ili utatue shida hii.</string>
|
||||
<string name="sign_in_button">Ingia</string>
|
||||
<string name="forgotten_password">Nimesahau nywila yangu
|
||||
<string name="try_again">umekosea nywila , jaribu tena
|
||||
umekosea nenosiri, jaribu tena</string>
|
||||
<string name="sign_in_button">ingia</string>
|
||||
<string name="forgotten_password">nimesahau Nywila yangu
|
||||
nimesahau nenosiri yangu</string>
|
||||
<string name="dialog_title_lost_password">Umepoteza nywila.
|
||||
Umepoteza nenosiri.</string>
|
||||
<string name="dialog_message_lost_password">Briar hawezi kuhifadhi nywila yako. Tafadhali jaribu kuwasha upya kifaa chako ili utatue shida hii.</string>
|
||||
<string name="startup_failed_notification_title">Briar imeshidwa anza</string>
|
||||
<string name="startup_failed_notification_text">Bonyeza kwa taarifa zaidi.</string>
|
||||
<string name="startup_failed_activity_title">Briar imeshindwa kuanza</string>
|
||||
<string name="startup_failed_db_error">Kutokana na sababu mbali mbali briar yako imevurugika kwenye hifadhi data. Na akaunti yako data na mawasiliano yako yote yamepotea. Itabidi upakue tena briar au tengeneza akaunti nyingine ila chagua umesahau nywila yako pale kwenye uwanja nenosiri .</string>
|
||||
<string name="dialog_title_lost_password">umepoteza nywila
|
||||
umepoteza nenosiri</string>
|
||||
<string name="startup_failed_notification_title">Briar imeshidwa Anza</string>
|
||||
<string name="startup_failed_notification_text">bonyeza kwa taarifa zaidi </string>
|
||||
<string name="startup_failed_activity_title">Briar kuaza kumeshidwa</string>
|
||||
<string name="startup_failed_db_error">Kutokana na sababu mbali mbali Briar yako imevurugika kwenye kifadhidata. Na akaunti yako data na mawasiliano yako yote yamepotea. Itabidi upakue tena Briar au Tengeneza Akaunti nyingine ila chagua umesahau Nenosiri lako\' pale kwenye uwanja nenosiri .</string>
|
||||
<string name="startup_failed_data_too_old_error">Akaunti yako imetengenezwa na tolea la zamani la programu hii na Haiwezekani kufungua hili toleo . Nilazima ubadili hili toleo la zamani au utengeneze Akaunti mpaya kwa kuchagua umesahau nenosiri Katika uwanja wa nenosiri </string>
|
||||
<string name="startup_failed_data_too_new_error">Hili toleo la programu ulilo tumia nila zamani . Tafathi boresha kuwa toleo jipya na ujaribu tena .</string>
|
||||
<string name="startup_failed_service_error">Briar imeshindikan kuanza Unabidi uunganishwe . Hianzishe Briar kama kwawaida kuondoka hilo tatizo . Japo kuwa utapoteza Akaunti yako na data zako zote kutokana na briar hifadhi data zako kwenye save kuu.</string>
|
||||
<plurals name="expiry_warning">
|
||||
<item quantity="one">Hili ni toleo la jaribio la Briar. Akaunti yako itaisha %d kwa siku na haiwezi kufanywa upya.</item>
|
||||
<item quantity="other">Hili ni toleo la jaribio la Briar. Akaunti yako itaisha %d kwa siku na haiwezi kufanywa upya.</item>
|
||||
</plurals>
|
||||
<string name="startup_failed_service_error">Briar imeshindikan kuanza Unabidi uunganishwe . Hianzishe Briar kama kwawaida kuondoka hilo tatizo . Japo kuwa utapoteza Akaunti yako na data zako zote kutokana na Briar haifathi data zako kwenye seva kuu.</string>
|
||||
<string name="expiry_date_reached">Hii programu imemaliza muda wake.\nAsante kwa kujaribu </string>
|
||||
<string name="download_briar">Ili kuendelea kutumia Briar, tafadhali pakua toleo la hivi karibuni.</string>
|
||||
<string name="create_new_account">Unahitajika kutenege Akaunti Mpaya , ila unaweza endelea kutumia lakabu yako .</string>
|
||||
<string name="download_briar_button">Pakua Kupaata toleo la hivi Karibuni</string>
|
||||
<string name="startup_open_database">Kupunguka Hifadhidata</string>
|
||||
<string name="startup_migrate_database">Boresha Hifadhidata</string>
|
||||
<string name="startup_compact_database">Kuingiliana Hifadhi data rununu</string>
|
||||
<string name="startup_compact_database">Kuingiliana Hifadhidata</string>
|
||||
<!--Navigation Drawer-->
|
||||
<string name="nav_drawer_open_description">Fungua njia ya Usambazaji </string>
|
||||
<string name="nav_drawer_close_description">Funga njia ya Usambazaji </string>
|
||||
<string name="contact_list_button">Mawasiliano </string>
|
||||
<string name="groups_button">Vikundi vya kibinafsi</string>
|
||||
<string name="forums_button">Ukumbi</string>
|
||||
<string name="blogs_button">Blogi</string>
|
||||
<string name="blogs_button">blogi</string>
|
||||
<!--This is part of the main menu. The app will be locked when this is tapped.-->
|
||||
<string name="lock_button">Funga programu</string>
|
||||
<string name="settings_button">Mipangilio</string>
|
||||
<string name="settings_button">vipimo</string>
|
||||
<string name="sign_out_button">Kutoka</string>
|
||||
<string name="transports_onboarding_text">Gonga hapa kudhibiti jinsi Briar inavyounganishwa kwenye mawasiliano yako</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Mtandao </string>
|
||||
<string name="tor_device_status_online_wifi">Simu yako ina upatikanaji wa mtandano kupitia Wi_Fi</string>
|
||||
<string name="tor_device_status_online_mobile">Simu yako ina upatikanaji wa mtandano kupitia data ya rununu</string>
|
||||
<string name="tor_device_status_offline">Simu yako haina upatikanaji wa mtandao</string>
|
||||
<string name="tor_plugin_status_enabling">Briar inaunganishwa kwenye Mtandao</string>
|
||||
<string name="tor_plugin_status_active">Simu yako imeunganishwa kwenye Mtandao</string>
|
||||
<string name="tor_plugin_status_inactive">Briar haiwezi kuunganishwa kwenye Mtandano</string>
|
||||
<string name="tor_plugin_status_disabled">Briar imeundwa kutotumia Mtandao</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar imeundwa kutotumia data rununu</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar imeundwa kutotumia Mtandao wakati wa kutumia betri</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar imeundwa kutotumia mtandao kwenye nchi hii</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">WI-FI</string>
|
||||
<string name="transport_lan_long">mtandao sawa wa Wi_Fi</string>
|
||||
<string name="lan_device_status_on">Simu yako imeunganishwa na Wi_Fi</string>
|
||||
<string name="lan_device_status_off">Simu yako haijaunganishwa na Wi_Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar inaunganishwa na mtandao wa Wi_Fi</string>
|
||||
<string name="lan_plugin_status_active">Briar imeunganishwa na mtandao wa Wi_Fi</string>
|
||||
<string name="lan_plugin_status_inactive">Briar haiwezi kuunganishwa kwenye mtandao wa Wi_Fi</string>
|
||||
<string name="lan_plugin_status_disabled">Briar imeundwa kutotumia mtandao wa Wi_Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Bluetooth ya simu Yako imewashwa</string>
|
||||
<string name="bt_device_status_off">Bluetooth ya simu Yako imezimwa</string>
|
||||
<string name="bt_plugin_status_enabling">Briar inaunganishwa na Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar imeunganishwa na bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar haiwezi kuunganishwa na Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar imeundwa kutotumia Bluetooth</string>
|
||||
<string name="transport_lan">WI-FI</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Toka Briar</string>
|
||||
<string name="reminder_notification_text">bonyeza Kuingia tena .</string>
|
||||
@@ -116,108 +81,95 @@ Umepoteza nenosiri.</string>
|
||||
<string name="delete">futa</string>
|
||||
<string name="accept">kukubali</string>
|
||||
<string name="decline">kukata</string>
|
||||
<string name="online">Mkondoni</string>
|
||||
<string name="offline">Nje ya mkondo</string>
|
||||
<string name="send">Tuma</string>
|
||||
<string name="allow">Ruhusu</string>
|
||||
<string name="open">Fungua</string>
|
||||
<string name="no_data">Hakuna data</string>
|
||||
<string name="online">mkondoni</string>
|
||||
<string name="offline">nje ya mkondo</string>
|
||||
<string name="send">tuma</string>
|
||||
<string name="allow">ruhusu</string>
|
||||
<string name="open">fungua</string>
|
||||
<string name="no_data">hakuna data</string>
|
||||
<string name="ellipsis">...</string>
|
||||
<string name="text_too_long">Maneno ulio yainguza nimarefu sana </string>
|
||||
<string name="show_onboarding">Kisanduku cha Msaada </string>
|
||||
<string name="fix">Rekebisha</string>
|
||||
<string name="help">Msaada</string>
|
||||
<string name="show_onboarding">Kisanduku cha Msahada </string>
|
||||
<string name="fix">kurekebisha</string>
|
||||
<string name="help">Msahada</string>
|
||||
<string name="sorry">Samahani</string>
|
||||
<string name="error_start_activity">Haipatikani kwenye mfumo wako</string>
|
||||
<string name="status_heading">Hali</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Hakuna mawasiliano yakuonyesha </string>
|
||||
<string name="no_contacts_action">Bonyeza ikoni + kuongeza mawasiliano </string>
|
||||
<string name="date_no_private_messages">Hakuna ujumbe </string>
|
||||
<string name="no_private_messages">Hakuna ujumbe wakuonyesha </string>
|
||||
<string name="message_hint">Andika ujumbe </string>
|
||||
<string name="image_caption_hint">Ongeza maelezo mafupi (sio ya hiari)</string>
|
||||
<string name="image_attach">Ambatanisha taswira</string>
|
||||
<string name="image_attach_error">Imeshidikana kuambatanisha taswira</string>
|
||||
<string name="image_attach_error_too_big">Taswira ni kubwa sana. Kiwango ni %d MB.</string>
|
||||
<string name="no_contacts">hakuna mawasiliano yakuonyesha </string>
|
||||
<string name="no_contacts_action">bonyeza ikoni + kuongeza mawasiliano </string>
|
||||
<string name="date_no_private_messages">hakuna ujumbe </string>
|
||||
<string name="no_private_messages">hakuna ujumbe wakuonyesha </string>
|
||||
<string name="message_hint">andika ujumbe </string>
|
||||
<string name="image_caption_hint">ongeza maelezo mafupi (sio ya hiari)</string>
|
||||
<string name="image_attach">Ambatanisha na taswira</string>
|
||||
<string name="image_attach_error">imeshidikana kuambatanisha taswira(s)</string>
|
||||
<string name="image_attach_error_too_big">Taswira nikubwa sana . kiwango ni %d MB.</string>
|
||||
<string name="image_attach_error_invalid_mime_type">Mfumo wa taswira hauendani: %s</string>
|
||||
<string name="set_contact_alias">Badilisha jina lako la mawasiliano </string>
|
||||
<string name="set_contact_alias_hint">Jina la mawasiliano </string>
|
||||
<string name="set_alias_button">Badili</string>
|
||||
<string name="delete_all_messages">Futa jumbe zote</string>
|
||||
<string name="dialog_title_delete_all_messages">Hakiki ufutaji wa ujumbe</string>
|
||||
<string name="dialog_message_delete_all_messages">Je, unauhakika wa kufuta jumbe zote?</string>
|
||||
<string name="dialog_title_not_all_messages_deleted">Ufutaji wa jumbe zote umeshindikana</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_both">Jumbe unaohusiana na mialiko inayoendelea na utangulizi haziwezi kufutwa hadi amalize.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_introductions">Jumbe zinazohusiana na utangulizi unaoendelea haziwezi kufutwa hadi amalize.</string>
|
||||
<string name="dialog_message_not_deleted_ongoing_invitations">Jumbe zinazohusiana na mialiko inayoendelea haziwezi kufutwa hadi itakapomalizika.</string>
|
||||
<string name="dialog_message_not_deleted_partly_downloaded">Jumbe zilizopakuliwa kwa sehemu haziwezi kufutwa hadi amalize kupakua.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_both"> Kufuta mwaliko au utangulizi, unahitaji kuchagua ombi na jibu.</string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_introductions">Ili kufuta utangulizi, unahitaji kuchagua ombi na jibu. </string>
|
||||
<string name="dialog_message_not_deleted_not_all_selected_invitations">Ili kufuta mwaliko, unahitaji kuchagua ombi na jibu.</string>
|
||||
<string name="delete_contact">Futa mawasiliano </string>
|
||||
<string name="dialog_title_delete_contact">Thibitisha ufutaji wa mawasiliano </string>
|
||||
<string name="dialog_message_delete_contact">Unauhakika unataka kuondoa mawasiliano na ujumbe wote kati yenu .</string>
|
||||
<string name="contact_deleted_toast">Mawasiliano yamefutwa</string>
|
||||
<string name="set_contact_alias">badilisha jina lako la mawasiliano </string>
|
||||
<string name="set_contact_alias_hint">jina la mawasiliano </string>
|
||||
<string name="set_alias_button">badili</string>
|
||||
<string name="delete_contact">futaa mawasiliano </string>
|
||||
<string name="dialog_title_delete_contact">thibitisha kufuta mawasiliano </string>
|
||||
<string name="dialog_message_delete_contact">unauwakika unataka kuondoa mawasiliano na ujumbe wote kati yenu .</string>
|
||||
<string name="contact_deleted_toast">mawasiliano yame ondolewa </string>
|
||||
<!--This is shown in the action bar when opening an image in fullscreen that the user sent-->
|
||||
<string name="you">Wewe</string>
|
||||
<string name="you">wewe</string>
|
||||
<string name="save_image">Hifathi taswira</string>
|
||||
<string name="dialog_title_save_image">Hifathi taswira?</string>
|
||||
<string name="dialog_message_save_image">Uhifadhi wa taswira hii utaruhusu programu nyengine kuiona. Je, unauhakika unahitaji kuhifathi?</string>
|
||||
<string name="dialog_title_save_image">Unaitaji kuhifathi Taswira?</string>
|
||||
<string name="dialog_message_save_image">Hifathi hii taswira ila itaruhusu programu nyengine kuziona . Una uwakika unaitaji kuhifathi ?</string>
|
||||
<string name="save_image_success">Taswira imehifathiwa </string>
|
||||
<string name="save_image_error">Haiwezekani kuhifathi Taswira.</string>
|
||||
<string name="dialog_title_no_image_support">Taswira haipatikani </string>
|
||||
<string name="dialog_message_no_image_support">Anwani yako ya Briar bado haihimili viambatanisho vya picha. Mara tu watakapoboresha utaona aikoni tofauti</string>
|
||||
<string name="dialog_title_image_support">Sasa unaweza tuma taswira kwa mawasiliano haya.</string>
|
||||
<string name="dialog_message_image_support">Bonyeza ikoni hii kuambatanisha taswira.</string>
|
||||
<string name="messaging_too_many_attachments_toast">Taswira ya kwanza %d ndio itakayotumwa</string>
|
||||
<string name="dialog_message_no_image_support">Mfumo wako wa Briar hausaidi Uambatanishaji wa taswira . Utakapo boresha Briar utaona ikoni tofauti.</string>
|
||||
<string name="dialog_title_image_support">Sasa unaweza tuma taswira kwa mawasiliano yako.</string>
|
||||
<string name="dialog_message_image_support">Bonyeza ikoni hii kuambatanisha Taswira.</string>
|
||||
<!--Adding Contacts-->
|
||||
<string name="add_contact_title">Ongeza mawasaliano ya walio karibu </string>
|
||||
<string name="face_to_face">Ni lazima ukutane na mtu unaye taka kumuongeza kwenye mawasiliano.\n\nHii ita kuepusha na mtu mwengine kuweza kusoma ujembo wako huko mbeleni.</string>
|
||||
<string name="continue_button">Endelea</string>
|
||||
<string name="try_again_button">Jaribu tena </string>
|
||||
<string name="waiting_for_contact_to_scan">Usubiri kwa mawasiliano waku skani na kuunganishwa\u2026</string>
|
||||
<string name="try_again_button">jaribu tena</string>
|
||||
<string name="waiting_for_contact_to_scan">Usubi kwa mawasiliano ku skana na kuunganishwa\u2026</string>
|
||||
<string name="exchanging_contact_details">Kubadilishana mawasiliano taharifa\u2026</string>
|
||||
<string name="contact_added_toast">Mawasiliano yameongezwa:%s</string>
|
||||
<string name="contact_added_toast">mawasiliano wameongezwa:%s</string>
|
||||
<string name="contact_already_exists">Wasiliano%s tayari lipo.</string>
|
||||
<string name="qr_code_invalid">The QR nambari sio sahihi </string>
|
||||
<string name="qr_code_too_old">Nambari ya QR ulio skana inatokea kwenye toleo la zamani %s.\n\nTafathali wasiliana na mwenzio au boreshe kwenye toleo jipya na ujaribu tena .</string>
|
||||
<string name="qr_code_too_new">Nambari ya QR ulio skana Inatoka kwenye toleo jipya %s.\n\nTafathali boresha kuwa kwenye toleo jipya na ujaribu tena .</string>
|
||||
<string name="camera_error">Kamera Hitilafu</string>
|
||||
<string name="connecting_to_device">Unganisha kwenye kifaa\u2026</string>
|
||||
<string name="camera_error">kamera Hitilafu</string>
|
||||
<string name="connecting_to_device">kunganishwa kwenye kifaa\u2026</string>
|
||||
<string name="authenticating_with_device">Uhalisishaji wa kifaa\u2026</string>
|
||||
<string name="connection_error_title">Imeshindwa unganishwa kwenye mawasiliano </string>
|
||||
<string name="connection_error_title">imeshidwa unganishwa kwenye mawasiliano </string>
|
||||
<string name="connection_error_explanation">Tafathali Angalia kama wote Mmeunganishwa kwenye Mtandao wa WI-FI mmoja .</string>
|
||||
<string name="connection_error_feedback">Kama hilo tatizo linaendela , Tafathali <a href="feedback"> tutumie maoni</a>ilituboreshe Programu .</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Ongeza mawasiliano kwambali </string>
|
||||
<string name="add_contact_nearby_title">Ongeza mawasiliano kwa karibu </string>
|
||||
<string name="add_contact_nearby_title">ongeza mawasiliano kwa karibu </string>
|
||||
<string name="add_contact_remotely_title">Ongeza Mawasilina kwa wambali </string>
|
||||
<string name="contact_link_intro">Ingiza kiungo cha mawasiliano hapa. </string>
|
||||
<string name="contact_link_hint">Unganisha mawasiliano </string>
|
||||
<string name="paste_button">Bandika </string>
|
||||
<string name="add_contact_button">Ongeza mawasiliano </string>
|
||||
<string name="copy_button">Nakala</string>
|
||||
<string name="share_button">Kushiriki </string>
|
||||
<string name="contact_link_hint">unganisha mawasiliano </string>
|
||||
<string name="paste_button">bandika </string>
|
||||
<string name="add_contact_button">ongeza mawasiliano </string>
|
||||
<string name="copy_button">nakala</string>
|
||||
<string name="share_button">kushiriki </string>
|
||||
<string name="send_link_title">Badilisha Kiungo. </string>
|
||||
<string name="add_contact_choose_nickname">Chagua lakabu </string>
|
||||
<string name="add_contact_choose_a_nickname">Ingiza lakabu </string>
|
||||
<string name="nickname_intro">Ipe namba hii lakabu . Na niwewe tu utaiona .</string>
|
||||
<string name="your_link">Mpe kiungo hichi unaye taka kuwasiliana nae </string>
|
||||
<string name="link_clip_label">Kiunga cha Briar</string>
|
||||
<string name="link_clip_label">Briar kiunga</string>
|
||||
<string name="link_copied_toast">Kiungo nakili </string>
|
||||
<string name="adding_contact_error">Kulikuwa na hitilafu wakati wa kuongeza mawasiliano </string>
|
||||
<string name="adding_contact_error">kulikuwa na Hitilafu wakati wa kuongeza mawasiliano </string>
|
||||
<string name="pending_contact_requests_snackbar">Maombi ya mawasiliano yalio subirishwa </string>
|
||||
<string name="pending_contact_requests">Maombi yalio subirishwa </string>
|
||||
<string name="no_pending_contacts">Hakuna maombi yalio subirishwa </string>
|
||||
<string name="waiting_for_contact_to_come_online">Subiri kwaulie wasiliana nae aje Mkondoni .</string>
|
||||
<string name="connecting">Kuunganishwa...</string>
|
||||
<string name="connecting">kuunganishwa...</string>
|
||||
<string name="adding_contact">Ongeza Mawasiliano....</string>
|
||||
<string name="adding_contact_failed">Imeshidikana kuongeza Mawasiliano </string>
|
||||
<string name="dialog_title_remove_pending_contact">Hakiki Kufuta </string>
|
||||
<string name="dialog_message_remove_pending_contact">Mawawasilano haya bado yanaendea kuhifathiwa , kama uta ondoa sasa , hayata kuwa yameifathiwa .</string>
|
||||
<string name="own_link_error">Ingiza kiunga cha mawasiliano, ambacho sio cha kwako </string>
|
||||
<string name="own_link_error">Ingiza kiunga cha mawasiliano, Ambacho sio cha kwako </string>
|
||||
<string name="nickname_missing">Tafathali andika lakabu</string>
|
||||
<string name="invalid_link">Kiunga batili </string>
|
||||
<string name="invalid_link">kiunga batili </string>
|
||||
<string name="unsupported_link">Hichi kiunga kimetoka kwenye tolea jipya Bria. Tafathali boresha kuwa kwenye Tolea jipya na ujaribu tena .</string>
|
||||
<string name="intent_own_link">Umefungua kiunga cha kwako mwenyewe. Tumia kingine unachotaka kuongeza!</string>
|
||||
<string name="missing_link">Tafathali ingiza Kiungo </string>
|
||||
@@ -232,28 +184,26 @@ Umepoteza nenosiri.</string>
|
||||
<string name="offline_state">Hakuna mtandao</string>
|
||||
<string name="duplicate_link_dialog_title">Kiunga cha kurudia.</string>
|
||||
<string name="duplicate_link_dialog_text_1">Tayari unayo mawasiliano yenye kiunga hiki:%s</string>
|
||||
<string name="duplicate_link_dialog_text_1_contact">Tayari una mawasiliano na kiunga hiki: 1%s
|
||||
</string>
|
||||
<!--This is a question asking whether two nicknames refer to the same person-->
|
||||
<string name="duplicate_link_dialog_text_2">yani%sna%sni mtu mmoja?</string>
|
||||
<!--This is a button for answering that two nicknames do indeed refer to the same person. This
|
||||
string will be used in a dialog button, so if the translation of this string is longer than 20
|
||||
characters, please use "Yes" instead, and use "No" for the "Different Person" button-->
|
||||
<string name="same_person_button">Mtu yuleyule</string>
|
||||
<string name="same_person_button">Mtu Mmoja</string>
|
||||
<!--This is a button for answering that two nicknames refer to different people. This string
|
||||
will be used in a dialog button, so if the translation of this string longer than 20 characters,
|
||||
please use "No" instead, and use "Yes" for the "Same Person" button-->
|
||||
<string name="different_person_button">Mtu Tofauti</string>
|
||||
<string name="duplicate_link_dialog_text_3">%sna%swamekutumia kiunga sawa.\n\nMmoja wapo anajaribu kujuha ninani umewasiliana nae.\n\nUsi waambie umepokea kiunga hicho kwa mtu mwengine .</string>
|
||||
<string name="pending_contact_updated_toast">mawasilano yalio subirishwa yamesasishwa </string>
|
||||
<string name="pending_contact_updated_toast">mawasiano yalio subirishwa yamesasishwa </string>
|
||||
<!--Introductions-->
|
||||
<string name="introduction_onboarding_title">Tambulisha mawasiliano yako </string>
|
||||
<string name="introduction_onboarding_text">Unaweza yatambulisha mawasiliano yako kwenu wote,Ili isiwe lazima mpaka wakutane ndio waungane kwenye Briar.</string>
|
||||
<string name="introduction_menu_item">Anza Utambulisho </string>
|
||||
<string name="introduction_activity_title">Chagua mawasiliano </string>
|
||||
<string name="introduction_activity_title">chagua mawasiliano </string>
|
||||
<string name="introduction_not_possible">Tayari ulisha kuwa na utambulisho wa mawasilino yanaendelea. Tafathali ruhusa kwanza haya yaishe. Ila kama wewe au unaye wasiliananae wanapatikana muda mchache mtandaoni, itachukua muda kuisha .</string>
|
||||
<string name="introduction_message_title">Tambulisha Mawasiliano </string>
|
||||
<string name="introduction_message_hint">Ongeza Ujumbe (hiari)</string>
|
||||
<string name="introduction_message_hint">Ungeza Ujumbe (hiari)</string>
|
||||
<string name="introduction_button">Anza Utambulisho </string>
|
||||
<string name="introduction_sent">Utambulisho wako Umetumwa.</string>
|
||||
<string name="introduction_error">Kulikuwa na hitilafu wakati wa utambulisho .</string>
|
||||
@@ -263,7 +213,7 @@ Umepoteza nenosiri.</string>
|
||||
<string name="introduction_request_answered_received">%1$sAmeombwa Akutambulishe kwa %2$s.</string>
|
||||
<string name="introduction_response_accepted_sent">Umekubali utambulisho kwa%1$s.</string>
|
||||
<string name="introduction_response_accepted_sent_info">Kabla%1$sAja ongezwa kwenye mawasilino yako, Wanatakiwa wakubali utambulisho vyema . Pia inaweza chukua mudaa </string>
|
||||
<string name="introduction_response_declined_sent">Umekataa utambulisho kwa%1$s.</string>
|
||||
<string name="introduction_response_declined_sent">Une kataa utambulisho kwa%1$s.</string>
|
||||
<string name="introduction_response_accepted_received">%1$samekubali utabulisho kwa %2$s</string>
|
||||
<string name="introduction_response_declined_received">%1$sKakataa Utambulisho kwa %2$s.</string>
|
||||
<string name="introduction_response_declined_received_by_introducee">%1$skasema kwamba %2$s kakataa utambulisho.</string>
|
||||
@@ -271,10 +221,6 @@ Umepoteza nenosiri.</string>
|
||||
<string name="groups_list_empty">Hakuna kikundi cha kuonyesha </string>
|
||||
<string name="groups_list_empty_action">Bonyeza +ikoni kutenege kikundi, au uliza mawasiliano yako wakuunge kwenye kikundi </string>
|
||||
<string name="groups_created_by">Imetengenezwa na %s</string>
|
||||
<plurals name="messages">
|
||||
<item quantity="one">1%d jumbe</item>
|
||||
<item quantity="other">1%d jumbe</item>
|
||||
</plurals>
|
||||
<string name="groups_group_is_empty">Hichi kikundi hakina watu </string>
|
||||
<string name="groups_group_is_dissolved">Hichi kikundi kilisha futwaa</string>
|
||||
<string name="groups_remove">Ondoa</string>
|
||||
@@ -339,23 +285,23 @@ Umepoteza nenosiri.</string>
|
||||
<string name="activity_share_toolbar_header">Chagua Mawasiliano </string>
|
||||
<string name="no_contacts_selector">hakuna mawasiliano yakuonyesha </string>
|
||||
<string name="no_contacts_selector_action">Tafathali rudi tena hapa baada ya kuongeza mawasiliano </string>
|
||||
<string name="forum_shared_snackbar">Jukwaa tulilochangia kwa mawasiliano yaliyochaguliwa</string>
|
||||
<string name="forum_shared_snackbar">Umetawanya kumbi na mawasiliano ulio chagua </string>
|
||||
<string name="forum_share_message">Ungeza Ujumbe (hiari)</string>
|
||||
<string name="forum_share_error">kulikuwa na hitilafu wakati changia huu ukumbi </string>
|
||||
<string name="forum_invitation_received">%1$samechangia jukwaa\"%2$s\" na wewe.</string>
|
||||
<string name="forum_invitation_sent">Umechangia jukwaa\"%1$s\" na %2$s.</string>
|
||||
<string name="forum_invitations_title">Mwaliko wa jukwaa</string>
|
||||
<string name="forum_invitation_exists">Umekubali mwaliko wa ukumbi huu tayari.\n\nNa kukubali mialiko zaidi itakufanya uwe na mawasiliano yako katika jukwaa yawe ya haraka na yakuaminika.</string>
|
||||
<string name="forum_joined_toast">umejiunga kwenye jukwaa</string>
|
||||
<string name="forum_invitation_received">%1$skamwaharifu juu ukumbi \"%2$s\" na wewe.</string>
|
||||
<string name="forum_invitation_sent">Ume taharifiwa juu ya ukumbi \"%1$s\" na %2$s.</string>
|
||||
<string name="forum_invitations_title">Mwaliko wa ukumbi</string>
|
||||
<string name="forum_invitation_exists">Umekubali mwaliko wa ukumbi huu tayari.\n\nNa kukubali mialiko mbali mbali itakufanya uwe na kikundi hai.</string>
|
||||
<string name="forum_joined_toast">umekiunga kwenye Ukumbi </string>
|
||||
<string name="forum_declined_toast">Mwaliko umekataliwa</string>
|
||||
<string name="shared_by_format">Umetumwa na %s</string>
|
||||
<string name="forum_invitation_already_sharing">Tayari imesha sambazwa</string>
|
||||
<string name="forum_invitation_response_accepted_sent">Umekubali mwaliko wa jukwaa kutoka kwa %s.</string>
|
||||
<string name="forum_invitation_response_declined_sent">Umekata mwaliko wa jukwaa kutoka kwa %s.</string>
|
||||
<string name="forum_invitation_response_accepted_received">%sKakubali mwaliko wa jukwaa.</string>
|
||||
<string name="forum_invitation_response_declined_received">%skakata mwaliko wa jukwaa.</string>
|
||||
<string name="forum_invitation_already_sharing">Tayari imesha sabanzwa</string>
|
||||
<string name="forum_invitation_response_accepted_sent">Umekubali mwaliko wa ukumbi kutoka kwa %s.</string>
|
||||
<string name="forum_invitation_response_declined_sent">Umekata mwaliko wa ukumbi kutoka kwa %s.</string>
|
||||
<string name="forum_invitation_response_accepted_received">%sKakubali mwaliko wa ukumbi.</string>
|
||||
<string name="forum_invitation_response_declined_received">%skakata mwaliko wa ukumbi.</string>
|
||||
<string name="sharing_status">Tawanya hali </string>
|
||||
<string name="sharing_status_forum">Mwana kikundi yoyote anaweza kuwataarifu watu wengine. Una tumia jukwaa hili na marafiki zako . Na kuna watu wengine wanaweza kutoona pia .</string>
|
||||
<string name="sharing_status_forum">Mwana kikundi yoyote naweza taharifu watu wengine. Una tumia ukumbi huu na marafiki zako . Nakuna watu wengine wanweza kutoona pia .</string>
|
||||
<string name="shared_with">Umesabazwa na %1$d(%2$dmkondoni)</string>
|
||||
<string name="nobody">Hakuna mtu </string>
|
||||
<!--Blogs-->
|
||||
@@ -368,20 +314,19 @@ Umepoteza nenosiri.</string>
|
||||
<string name="blogs_blog_post_received">Chapisho jipya la blogi limepokelewa </string>
|
||||
<string name="blogs_blog_post_scroll_to">Tembeza kwa</string>
|
||||
<string name="blogs_feed_empty_state">Hakuna chapisho lakuonyesha </string>
|
||||
<string name="blogs_feed_empty_state_action">Taarifa zote kutoka kwenye Mawasaliano yako na blogi unazo zifwatilia zitatokea hapa\n\nBonyeza kalamu ikoni kuandika taarifa </string>
|
||||
<string name="blogs_feed_empty_state_action">Taharifa zote kutoka kwenye Mawasaliano yako na blogi unazo zifwatilia zitatokea hapa\n\nBonyeza kalamu ikoni kuandika Taharifa </string>
|
||||
<string name="blogs_remove_blog">Ondoa blogi </string>
|
||||
<string name="blogs_remove_blog_dialog_message">unauhakika unataka kuondoa hii blogi?\n\nMachapisho yataondolewa kutoka kwenye kifaa chako lakini sio kutoka kwenye vifaa vya watu wengine.\n\nMawasiliano yoyote utakaokuwa umewashirikisha blogi hii wataweza kutopata taarifa mpya.</string>
|
||||
<string name="blogs_remove_blog_ok">Ondoa</string>
|
||||
<string name="blogs_blog_removed">Blogi imeondolewa </string>
|
||||
<string name="blogs_reblog_comment_hint">Weka maoni(hiari)</string>
|
||||
<string name="blogs_reblog_button">Chapisha tena </string>
|
||||
<!--Blog Sharing-->
|
||||
<string name="blogs_sharing_share">Sambaza Blogi</string>
|
||||
<string name="blogs_sharing_share">tuma kwa wengine Blogi</string>
|
||||
<string name="blogs_sharing_error">kulikuwa na hitilafu wakati wakuchangia blogi.</string>
|
||||
<string name="blogs_sharing_button">tuma kwa wengine Blogi</string>
|
||||
<string name="blogs_sharing_snackbar">Tuma blogi kwa mawasiliano yaliyochaguliwa </string>
|
||||
<string name="blogs_sharing_snackbar">Tuma blogi kwa bahathi ya mawasiliano </string>
|
||||
<string name="blogs_sharing_response_accepted_sent">Umekubali mwaliko wa Blogi kutoka %s.</string>
|
||||
<string name="blogs_sharing_response_declined_sent">Umekataa mwaliko wa blogi kutoka kwa %s.</string>
|
||||
<string name="blogs_sharing_response_declined_sent">Umekata mwaliko wa blogi kutoka kwa %s.</string>
|
||||
<string name="blogs_sharing_response_accepted_received">%skakubali mwaliko wa blogi.</string>
|
||||
<string name="blogs_sharing_response_declined_received">%skakata mwaliko wa blogi.</string>
|
||||
<string name="blogs_sharing_invitation_received">%1$s kamwalika kwenye blogi\"%2$s\" na wewe.</string>
|
||||
@@ -389,53 +334,41 @@ Umepoteza nenosiri.</string>
|
||||
<string name="blogs_sharing_invitations_title">Mwaliko wa Blogi</string>
|
||||
<string name="blogs_sharing_joined_toast">Jisajili kwenye Blogi</string>
|
||||
<string name="blogs_sharing_declined_toast">mwaliko umekataliwa</string>
|
||||
<string name="sharing_status_blog">Yeyote anayejisajili kwenye blogi anaweza akaisambaza kwa mawasiliano yake. Unashirikisha kwa mawasiliano yafuatayo. Kuna wengine watajisajili lakini usiweze kuwaona.</string>
|
||||
<!--RSS Feeds-->
|
||||
<string name="blogs_rss_feeds_import">Ingiza RSS taarifa</string>
|
||||
<string name="blogs_rss_feeds_import_button">Ingiza</string>
|
||||
<string name="blogs_rss_feeds_import_hint">Ingiza URL za RSS taarifa</string>
|
||||
<string name="blogs_rss_feeds_import_error">Samahani! Kulikuwa na hitilafu wakati wakuingiza taarifa </string>
|
||||
<string name="blogs_rss_feeds_manage">Simamia taarifa za RSS</string>
|
||||
<string name="blogs_rss_feeds_import">Leta RSS taharifa</string>
|
||||
<string name="blogs_rss_feeds_import_button">Leta</string>
|
||||
<string name="blogs_rss_feeds_import_hint">Ingiza URL za RSS taharifa</string>
|
||||
<string name="blogs_rss_feeds_import_error">Tafathi Samahani! Kulikuwa na Hitilafu wakati wakuingiza Taharifa </string>
|
||||
<string name="blogs_rss_feeds_manage">Simamia RSS taharifa </string>
|
||||
<string name="blogs_rss_feeds_manage_imported">Zilizoingizwa</string>
|
||||
<string name="blogs_rss_feeds_manage_author">Mwandishi:</string>
|
||||
<string name="blogs_rss_feeds_manage_updated">huwisho la mwisho
|
||||
</string>
|
||||
<string name="blogs_rss_remove_feed">Ondoa taarifa</string>
|
||||
<string name="blogs_rss_remove_feed_dialog_message">Unauhakika unataka kutoa hii taarifa?\n\nChapisho lako litaondolewa kwenye kifaa chako ila sio kwenye vifaa vya watu wengine.\n\nMawasiliano yoyote utliokwisha kuyaunganisha wanaweza wasiendelea kupata taarifa. </string>
|
||||
<string name="blogs_rss_feeds_manage_updated">Yamwisho imesasishwa: </string>
|
||||
<string name="blogs_rss_remove_feed">Ondoa taharifa</string>
|
||||
<string name="blogs_rss_remove_feed_dialog_message">Unauwakika unataka kutoa hii taharifa?\n\nChapisho lako litaondolewa kwenye kifaa chako ila sio kwenye vifaa vya watu wengine.\n\nMawasiliano yoyote utakayo ambayo uliyaunganisha wataendelea kupata taharifa. </string>
|
||||
<string name="blogs_rss_remove_feed_ok">Ondoa</string>
|
||||
<string name="blogs_rss_feeds_manage_delete_error">Taharifa haziwezekani kuzifuta! </string>
|
||||
<string name="blogs_rss_feeds_manage_empty_state">Hakuna RSS taharifa zaku onyesha\n\nBonyeza + ikoni kuleta taharifa </string>
|
||||
<string name="blogs_rss_feeds_manage_error">Kulikuwa na tatizo la kufungua taharifa . Tafathali jaribu baadae kidogo.</string>
|
||||
<!--Settings Display-->
|
||||
<string name="pref_language_title">Lugha &mkoa</string>
|
||||
<string name="pref_language_changed">Huu mpango utafanya kazi utakapo anzisha tena Briar. Tafathali toka na kuanzisha tena Briar.</string>
|
||||
<string name="pref_language_changed">Huu mpango utafanya kazi baada yaku kuaza upaya Briar.Tafathali toka na kuanza upaya Briar.</string>
|
||||
<string name="pref_language_default">Mfumo msingi </string>
|
||||
<string name="display_settings_title">Onyesha</string>
|
||||
<string name="pref_theme_title">Lengo</string>
|
||||
<string name="pref_theme_title">Mada</string>
|
||||
<string name="pref_theme_light">mwanga</string>
|
||||
<string name="pref_theme_dark">Giza</string>
|
||||
<string name="pref_theme_auto">kiotomatiki (Mchana)</string>
|
||||
<string name="pref_theme_system">Mfumo Msingi </string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">Viunganishi</string>
|
||||
<string name="bluetooth_setting">Unganisha kwa anwani kupitia Bluetooth</string>
|
||||
<string name="wifi_setting">Unganisha kwa anwani kwenye mtandao huo wa Wi-Fi 376 mtandao</string>
|
||||
<string name="tor_enable_title">Unganisha mawasiliano kupitia mtandao</string>
|
||||
<string name="tor_enable_summary">Muunganiko wote unaokwenda kwa njia ya mtandao wa Tor ni kwa faragha</string>
|
||||
<string name="tor_network_setting">Unganisha njia kwa mtandao wa Tor</string>
|
||||
<string name="tor_network_setting_automatic">kiotomatiki inatengemeana na mahali </string>
|
||||
<string name="tor_network_setting_without_bridges">Tumia mtandao wa Tor bila madaraja</string>
|
||||
<string name="tor_network_setting_with_bridges">Tumia mtandao wa Tor na madaraja</string>
|
||||
<string name="tor_network_setting_never">Usiunganishe kwenye mtandao</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">kiotomatiki:%1$s (ndani%2$s)</string>
|
||||
<string name="tor_mobile_data_title">Tumia Data ya simu</string>
|
||||
<string name="tor_only_when_charging_title">Unganisha kwenye mtandao wakati wa kuchaji tu</string>
|
||||
<string name="tor_only_when_charging_summary">Zima mtandao wakati betri inachajishwa</string>
|
||||
<string name="tor_only_when_charging_summary">Zima mtandao wakati betri ipo chini </string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">Ulizi</string>
|
||||
<string name="pref_lock_title">Funga programu</string>
|
||||
<string name="pref_lock_summary">Tumia nenosiri katika kifaa chako kulinda Briar wakati wa kuingia</string>
|
||||
<string name="pref_lock_summary">Tumia nenosiri la simu kulinda Briar wakati wa kuingia</string>
|
||||
<string name="pref_lock_disabled_summary">Ili kutumia huu mfumo , weka ulizi kwenye kifaa chako </string>
|
||||
<string name="pref_lock_timeout_title">Kifungo cha Programu kimefika mwisho wake </string>
|
||||
<!--The %s placeholder is replaced with the following time spans, e.g. 5 Minutes, 1 Hour-->
|
||||
@@ -451,43 +384,43 @@ Umepoteza nenosiri.</string>
|
||||
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
|
||||
<string name="pref_lock_timeout_60">lisaa 1</string>
|
||||
<string name="pref_lock_timeout_never">Kamwe</string>
|
||||
<string name="pref_lock_timeout_never_summary">kamwe usifunge Briar kiotomatiki</string>
|
||||
<string name="pref_lock_timeout_never_summary">isijeikaji funga Briar kiotomatiki</string>
|
||||
<string name="change_password">Badili nenosiri</string>
|
||||
<string name="current_password">Nenosiri Lasasa</string>
|
||||
<string name="choose_new_password">Nywila mpya</string>
|
||||
<string name="confirm_new_password">Thibitisha nywila mpya.</string>
|
||||
<string name="password_changed">Nywila imebadilishwa</string>
|
||||
<string name="panic_setting">Usanidi wa kitufe cha hofu.</string>
|
||||
<string name="choose_new_password">Nenosiri jipya</string>
|
||||
<string name="confirm_new_password">Hakiki Nenosiri jipya</string>
|
||||
<string name="password_changed">Nenosiri limebadilika </string>
|
||||
<string name="panic_setting">Bonyeza ukiwa na hofu </string>
|
||||
<string name="panic_setting_title">kitufe cha hofu </string>
|
||||
<string name="panic_setting_hint">Sanidi jinsi Briar atavyoitikia wakati unatumia programu ya kitufe cha hofu. </string>
|
||||
<string name="panic_app_setting_title">Programu ya Kitufe cha Hofu.</string>
|
||||
<string name="unknown_app">programu isiyojulikana</string>
|
||||
<string name="panic_app_setting_summary">Hakuna programu iliyowekwa</string>
|
||||
<string name="panic_setting_hint">hakiki jinsi Briar ita kuwa endapo utabonyeza kitufe cha hofu kwenye programu </string>
|
||||
<string name="panic_app_setting_title">Kitufe cha hofu kwenye programu </string>
|
||||
<string name="unknown_app">programu isio tambulika</string>
|
||||
<string name="panic_app_setting_summary">hakuna programu ilio tegeshwa </string>
|
||||
<string name="panic_app_setting_none">Hakuna</string>
|
||||
<string name="dialog_title_connect_panic_app">Thibitisha Programu ya Hofu.</string>
|
||||
<string name="dialog_message_connect_panic_app">Una hakika unataka kuruhusu %1$skuchochea vitendo vya kifungo vya uharibifu.</string>
|
||||
<string name="panic_setting_destructive_action">Vitendo vya Uharibifu.</string>
|
||||
<string name="panic_setting_signout_title">Toka.</string>
|
||||
<string name="panic_setting_signout_summary">Sanidi kutoka kwa Briar ikiwa kitufe cha hofu kimesisitizwa.</string>
|
||||
<string name="purge_setting_title">Futa Akaunti.</string>
|
||||
<string name="purge_setting_summary">Futa Akaunti yako ya Briar ikiwa kitufe cha hofu kimesisitizwa .Tahadhari: Hii itafuta kabisa utambulisho wako, anwani na ujumbe.</string>
|
||||
<string name="dialog_title_connect_panic_app">Hakiki programu Hofu</string>
|
||||
<string name="dialog_message_connect_panic_app">Unauwakika unataka kumruhusu %1$skujibu taharifa za hofu ? </string>
|
||||
<string name="panic_setting_destructive_action">Kitendo cha kuharibu </string>
|
||||
<string name="panic_setting_signout_title">Kutoka</string>
|
||||
<string name="panic_setting_signout_summary">Toka kwenye Briar endapo kitufe cha Hofu kitabo nyezwa </string>
|
||||
<string name="purge_setting_title">futa akaunti</string>
|
||||
<string name="purge_setting_summary">Futa Briar akaunti endapo kitufe cha Hofu kitakuwa kimebonyezwa kwa mstuko . Hii itafuta kabisa mawasiliano na ujumbe wako </string>
|
||||
<!--Settings Notifications-->
|
||||
<string name="notification_settings_title">Arifa</string>
|
||||
<string name="notify_sign_in_title">Nikumbushe kuingia.</string>
|
||||
<string name="notify_sign_in_summary">Onyesha ukumbusho wakati simu inaanza au programu imesasishwa.</string>
|
||||
<string name="notify_private_messages_setting_title">Ujumbe binafsi.</string>
|
||||
<string name="notify_private_messages_setting_summary">Onyesha taarifa za ujumbe wa faragha.</string>
|
||||
<string name="notify_private_messages_setting_summary_26">Sanidi arifa kwa ujumbe wa faragha.</string>
|
||||
<string name="notify_group_messages_setting_title">Ujumbe wa kikundi</string>
|
||||
<string name="notify_group_messages_setting_summary">Onyesha arifa za ujumbe wa kikundi.</string>
|
||||
<string name="notification_settings_title">Arifu</string>
|
||||
<string name="notify_sign_in_title">Nikumbushe ku ingia</string>
|
||||
<string name="notify_sign_in_summary">onyesha kumbusho wakati simu imewaka au programu imesasisha</string>
|
||||
<string name="notify_private_messages_setting_title">ujumbe wa kibinafsi</string>
|
||||
<string name="notify_private_messages_setting_summary">onyesha arifu kwa ujumbe wa kibinafsi</string>
|
||||
<string name="notify_private_messages_setting_summary_26">sanidi arifu kwa ujembe wa kibinafsi</string>
|
||||
<string name="notify_group_messages_setting_title">ujumbe wakikundi</string>
|
||||
<string name="notify_group_messages_setting_summary">Onyesha Taharifa za kikundi </string>
|
||||
<string name="notify_group_messages_setting_summary_26">Hakiki ujumbe wa kikundi </string>
|
||||
<string name="notify_forum_posts_setting_title">chapisho Ukumbi </string>
|
||||
<string name="notify_forum_posts_setting_summary">Onyesha tahadhari kwa chapisho la jukwaa</string>
|
||||
<string name="notify_forum_posts_setting_summary_26"> Hakiki taarifa za chapisho la jukwaa</string>
|
||||
<string name="notify_forum_posts_setting_summary">Onyesha taharifa za chapisho kwenye Ukumbi </string>
|
||||
<string name="notify_forum_posts_setting_summary_26">Hakiki taharifa za chapisho kwenye ukumbi </string>
|
||||
<string name="notify_blog_posts_setting_title">chapisho blogi</string>
|
||||
<string name="notify_blog_posts_setting_summary">Arifu kwa chapisho ya blogi </string>
|
||||
<string name="notify_blog_posts_setting_summary">Onyesha chapisho kutoka kwenye blogi </string>
|
||||
<string name="notify_blog_posts_setting_summary_26">Hakiki taharifa za chapisho kwenye blogi </string>
|
||||
<string name="notify_vibration_setting">mtetemo </string>
|
||||
<string name="notify_vibration_setting">vibrate </string>
|
||||
<string name="notify_sound_setting">Sauti</string>
|
||||
<string name="notify_sound_setting_default">Mwiito mkuu </string>
|
||||
<string name="notify_sound_setting_disabled">Hakuna</string>
|
||||
@@ -497,51 +430,29 @@ Umepoteza nenosiri.</string>
|
||||
<string name="feedback_settings_title">Maoni</string>
|
||||
<string name="send_feedback">Tuma Maoni </string>
|
||||
<!--Link Warning-->
|
||||
<string name="link_warning_title">kiungo onyo</string>
|
||||
<string name="link_warning_intro">Uko karibu kufungua kiunga kifuatacho na programu ya nje</string>
|
||||
<string name="link_warning_text">Hii inaweza kutumika kutambua wewe. Fikiria kama unaamini mtu aliyekutumia kiungo hiki na Fikiria kuifungua kwa kivinjari cha Tor.</string>
|
||||
<string name="link_warning_open_link">kiunga wazi</string>
|
||||
<string name="link_warning_title">kiungo cha onyo</string>
|
||||
<string name="link_warning_open_link">Fungua kiungo </string>
|
||||
<!--Crash Reporter-->
|
||||
<string name="crash_report_title">Ripoti fupi ya ajali ya Brair</string>
|
||||
<string name="crash_report_title">Briar taharia imearibika</string>
|
||||
<string name="briar_crashed">Samahani, Briar imeharibika.</string>
|
||||
<string name="not_your_fault"> Hili sio kosa lako</string>
|
||||
<string name="please_send_report">Tafadhali tusaidie kujenga Briar bora kwa kututumia ripoti ya taharifa.</string>
|
||||
<string name="report_is_encrypted">Tunaahidi kuwa ripoti hiyo imesimbwa kwa njia fiche na kutumwa salama.</string>
|
||||
<string name="feedback_title">maoni</string>
|
||||
<string name="feedback_title">Maoni</string>
|
||||
<string name="describe_crash">Eleza kilicho tokea (hiari)</string>
|
||||
<string name="enter_feedback">Weka Maoni yako </string>
|
||||
<string name="optional_contact_email">Barua pepe yako (hiari)</string>
|
||||
<string name="include_debug_report_crash">Jumuisha data isiyojulikana kuhusu ajali</string>
|
||||
<string name="include_debug_report_feedback">Jumuisha data isiyojulikana kuhusu kifaa hiki</string>
|
||||
<string name="could_not_load_report_data">Haikuweza kupakia data ya ripoti.</string>
|
||||
<string name="send_report">Tuma repoti </string>
|
||||
<string name="close">Funga</string>
|
||||
<string name="dev_report_saved">Ripoti imehifadhiwa. Itatumwa wakati ujao ukiingia kwenye Briar.</string>
|
||||
<!--Sign Out-->
|
||||
<string name="progress_title_logout">Kuondoka Kwenye Briar...</string>
|
||||
<!--Screen Filters & Tapjacking-->
|
||||
<string name="screen_filter_title">Ufunikaji wa skrini umegunduliwa</string>
|
||||
<string name="screen_filter_body">Programu nyingine inachorwa juu ya Briar. Ili kulinda usalama wako, Briar haitajibu kugusa wakati programu nyingine inachorwa juu. \n\nProgramu zifuatazo zinaweza kuchorwa juu:\n\n%1$s</string>
|
||||
<string name="screen_filter_allow">Ruhusu programu hizi kuteka juu</string>
|
||||
<!--Permission Requests-->
|
||||
<string name="permission_camera_title">Ruhusa ya Kamera</string>
|
||||
<string name="permission_camera_request_body">Ili kuchanganua nambari ya QR, Briar inahitaji ufikiaji wa kamera.</string>
|
||||
<string name="permission_camera_title">kamera iruhusu</string>
|
||||
<string name="permission_location_title">Ruhusa ya eneo</string>
|
||||
<string name="permission_location_request_body">ilikugundua vifaa vya Bluetooth, Briar inahitaji idhini ya kufikia eneo lako. \n\ nBriar hahifadhi eneo lako au kushiriki na mtu yeyote.</string>
|
||||
<string name="permission_camera_location_title">Kamera na Eneo</string>
|
||||
<string name="permission_camera_location_request_body">Ili kuchanganua nambari ya QR, Briar inahitaji ufikiaji wa kamera. \n\nKugundua vifaa vya Bluetooth, Briar inahitaji idhini ya kufikia eneo lako. \n\nBriar hahifadhi eneo lako au kushiriki na mtu yeyote.</string>
|
||||
<string name="permission_camera_denied_body">Umekataa ufikiaji wa kamera, lakini kuongeza anwani kunahitaji kutumia kamera. \n\nTafadhali fikiria kutoa idhini ya kufikia.</string>
|
||||
<string name="qr_code">msimbo wa QR</string>
|
||||
<string name="show_qr_code_fullscreen">Onyesha skrini nzima ya msimbo wa QR</string>
|
||||
<!--App Locking-->
|
||||
<string name="lock_unlock">Fungua Briar</string>
|
||||
<string name="lock_unlock_verbose">Ingiza PIN ya kifaa chako, fumbo au nywila kufungua Briar </string>
|
||||
<string name="lock_unlock_fingerprint_description">Gusa kihisi cha alama za vidole kilicho sajiliwa na kidole husika ili kuendelea</string>
|
||||
<string name="lock_unlock_password">Tumia Nywila</string>
|
||||
<string name="lock_unlock_verbose">Ingiza Nenosiri la kifaa chako,PIN au fumbo kufungua Briar </string>
|
||||
<string name="lock_unlock_password">Tumia nenosiri</string>
|
||||
<string name="lock_is_locked">Briar imefungwa </string>
|
||||
<string name="lock_tap_to_unlock">Bonyeza kufungua</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar inaweza kuungana na anwani zako kupitia mtandao, Wi-Fi au Bluetooth. \n\n Muunganisho wote wa mtandao hupitia mtandao wa Tor kwa faragha. \n\n Ikiwa anwani inaweza kufikiwa kwa njia nyingi, Briar huitumia kwa usawa.</string>
|
||||
<string name="lock_tap_to_unlock">Bonyeza kufunga</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alice</string>
|
||||
@@ -550,9 +461,9 @@ Umepoteza nenosiri.</string>
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_carol">Carol</string>
|
||||
<!--This is a message to be used in screenshots. Please use the same translation for Bob!-->
|
||||
<string name="screenshot_message_1">Habari Bob!</string>
|
||||
<string name="screenshot_message_1">Hi Bob!</string>
|
||||
<!--This is a message to be used in screenshots. Please use the same translation for Alice!-->
|
||||
<string name="screenshot_message_2">Habari Alice! Asante kwa kuniambia kuhusu Briar!</string>
|
||||
<string name="screenshot_message_2">Hi Alice! Asante kwa kuniambia juu ya Briar!</string>
|
||||
<!--This is a message to be used in screenshots.-->
|
||||
<string name="screenshot_message_3">Hakuna tatizo, natumaini umeipenda 😀</string>
|
||||
<string name="screenshot_message_3">Hakuna tatizo, natumaini utaipenda 😀</string>
|
||||
</resources>
|
||||
|
||||
@@ -61,36 +61,10 @@
|
||||
<string name="lock_button">Uygulamayı Kilitle</string>
|
||||
<string name="settings_button">Ayarlar</string>
|
||||
<string name="sign_out_button">Oturumu Kapat</string>
|
||||
<string name="transports_onboarding_text">Briar\'ın kişilerinizle nasıl bağlanacağını kontrol etmek için buraya tıklayın</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">İnternet</string>
|
||||
<string name="tor_device_status_online_wifi">Telefonunuzun Wi-Fi aracılığıyla İnternet erişimi var</string>
|
||||
<string name="tor_device_status_online_mobile">Telefonunuzun mobil veri aracılığıyla İnternet erişimi var</string>
|
||||
<string name="tor_device_status_offline">Telefonunuzun İnternet erişimi yok</string>
|
||||
<string name="tor_plugin_status_enabling">Briar İnternet\'e bağlanıyor</string>
|
||||
<string name="tor_plugin_status_active">Briar İnternet\'e bağlandı</string>
|
||||
<string name="tor_plugin_status_inactive">Briar İnternet\'e bağlanamıyor</string>
|
||||
<string name="tor_plugin_status_disabled">Briar İnternet kullanmamak üzere yapılandırılmış</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar mobil veri kullanmamak üzere yapılandırılmış</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar pille çalışırken İnternet kullanmamak üzere yapılandırılmış</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar bu ülkede İnternet kullanmamak üzere yapılandırılmış</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Aynı Wi-Fi Ağı</string>
|
||||
<string name="lan_device_status_on">Telefonunuz Wi-Fi\'ye bağlı</string>
|
||||
<string name="lan_device_status_off">Telefonunuz Wi-Fi\'ye bağlı değil</string>
|
||||
<string name="lan_plugin_status_enabling">Briar Wi-Fi ağına bağlanıyor</string>
|
||||
<string name="lan_plugin_status_active">Briar Wi-Fi ağına bağlandı</string>
|
||||
<string name="lan_plugin_status_inactive">Briar Wi-Fi ağına bağlanamıyor</string>
|
||||
<string name="lan_plugin_status_disabled">Briar Wi-Fi ağını kullanmamak üzere yapılandırılmış</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Telefonunuzun Bluetooth\'u açık</string>
|
||||
<string name="bt_device_status_off">Telefonunuzun Bluetooth\'u kapalı</string>
|
||||
<string name="bt_plugin_status_enabling">Briar Bluetooth\'a bağlanıyor</string>
|
||||
<string name="bt_plugin_status_active">Briar Bluetooth\'a bağlandı</string>
|
||||
<string name="bt_plugin_status_inactive">Briar Bluetooth\'a bağlanamıyor</string>
|
||||
<string name="bt_plugin_status_disabled">Briar Bluetooth kullanmamak üzere yapılandırılmış</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Briar oturumu kapatıldı</string>
|
||||
<string name="reminder_notification_text">Tekrar oturum açmak için dokunun</string>
|
||||
@@ -137,7 +111,6 @@
|
||||
<string name="help">Yardım</string>
|
||||
<string name="sorry">Üzgünüm</string>
|
||||
<string name="error_start_activity">Sisteminizde mevcut değil</string>
|
||||
<string name="status_heading">Durum</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Gösterilecek kişi yok</string>
|
||||
<string name="no_contacts_action">kişi eklemek için + simgesine dokunun</string>
|
||||
@@ -195,6 +168,7 @@
|
||||
<string name="connecting_to_device">Aygıta bağlanıyor\u2026</string>
|
||||
<string name="authenticating_with_device">Aygıtla kimlik doğrulama\u2026</string>
|
||||
<string name="connection_error_title">Kişinizle bağlantı kurulamadı</string>
|
||||
<string name="connection_error_explanation">Lütfen her ikinizin de aynı Wi-Fi ağına bağlı olup olmadığınızı kontrol edin.</string>
|
||||
<string name="connection_error_feedback">Sorun devam ederse, uygulamayı geliştirmemize yardımcı olmak için <a href="feedback">geri bildirim gönderin</a>.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Uzaktaki Kişiyi Ekle</string>
|
||||
@@ -558,8 +532,6 @@
|
||||
<string name="lock_unlock_password">Parola Kullanın</string>
|
||||
<string name="lock_is_locked">Briar kilitli</string>
|
||||
<string name="lock_tap_to_unlock">Kilidi açmak için dokunun</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar kişilerinizle İnternet, Wi-Fi veya Bluetooth ile bağlanabilir.\n\nBütün İnternet bağlantıları gizliliğiniz için Tor Ağı üzerinden yapılıyor.\n\nEğer bir kişiniz birçok yöntemle erişilebiliyorsa, Briar bu yöntemleri paralel olarak kullanır.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alice</string>
|
||||
|
||||
@@ -59,12 +59,10 @@
|
||||
<string name="lock_button">Заблокувати програму</string>
|
||||
<string name="settings_button">Налаштування</string>
|
||||
<string name="sign_out_button">Вийти</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">Інтернет</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">Ви вийшли з Briar</string>
|
||||
<string name="reminder_notification_text">Натисніть, щоб знову увійти.</string>
|
||||
@@ -118,7 +116,6 @@
|
||||
<string name="fix">Виправити</string>
|
||||
<string name="help">Довідка</string>
|
||||
<string name="sorry">Вибачте</string>
|
||||
<string name="status_heading">Статус</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Немає контактів для відображення</string>
|
||||
<string name="no_contacts_action">Натисніть на символ \"+\" для того, щоб додати контакт</string>
|
||||
@@ -165,6 +162,7 @@
|
||||
<string name="connecting_to_device">З\'єднання з пристроєм\u2026</string>
|
||||
<string name="authenticating_with_device">Автентифікація з пристроєм\u2026</string>
|
||||
<string name="connection_error_title">Неможливо з\'єднатися з вашим контактом</string>
|
||||
<string name="connection_error_explanation">Будь ласка, впевніться, що ви обоє під\'єднані до однієї Wi-Fi-мережі.</string>
|
||||
<string name="connection_error_feedback">Якщо ця проблема збережеться, будь ласка, <a href="feedback">надішліть відгук</a>, щоб допомогти нам вдосконалити цей додаток.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Додати контакт віддалено</string>
|
||||
@@ -527,7 +525,6 @@
|
||||
<string name="lock_unlock_password">Використовуйте пароль</string>
|
||||
<string name="lock_is_locked">Briar заблоковано</string>
|
||||
<string name="lock_tap_to_unlock">Натисніть, щоб розблокувати</string>
|
||||
<!--Connections Screen-->
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Аліса</string>
|
||||
|
||||
@@ -60,36 +60,10 @@
|
||||
<string name="lock_button">锁定应用</string>
|
||||
<string name="settings_button">设置</string>
|
||||
<string name="sign_out_button">登出</string>
|
||||
<string name="transports_onboarding_text">点击这里来控制Briar如何连接到您的联系人</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">互联网</string>
|
||||
<string name="tor_device_status_online_wifi">你的手机通过Wi-Fi上网</string>
|
||||
<string name="tor_device_status_online_mobile">您的手机通过移动数据访问互联网</string>
|
||||
<string name="tor_device_status_offline">你的手机不能上网</string>
|
||||
<string name="tor_plugin_status_enabling">Briar正在连接互联网</string>
|
||||
<string name="tor_plugin_status_active">Briar 已联网</string>
|
||||
<string name="tor_plugin_status_inactive">Briar 无法联网</string>
|
||||
<string name="tor_plugin_status_disabled">Briar 配置为不使用互联网</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar 配置为不使用移动数据</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar配置为在用电池运行时不使用互联网</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar配置为在这个国家不使用互联网</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">无线局域网</string>
|
||||
<string name="transport_lan_long">同一 Wi-Fi 网络</string>
|
||||
<string name="lan_device_status_on">你的手机连接到Wi-Fi</string>
|
||||
<string name="lan_device_status_off">你的手机未连接到Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar正在连接Wi-Fi网络</string>
|
||||
<string name="lan_plugin_status_active">Briar已连接到此Wi-Fi网络</string>
|
||||
<string name="lan_plugin_status_inactive">Briar不能连接到此Wi-Fi网络</string>
|
||||
<string name="lan_plugin_status_disabled">Briar 配置为不使用Wi-Fi 网络</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">蓝牙</string>
|
||||
<string name="bt_device_status_on">你手机的蓝牙已打开</string>
|
||||
<string name="bt_device_status_off">你手机额蓝牙已关闭</string>
|
||||
<string name="bt_plugin_status_enabling">Briar 正连接蓝牙</string>
|
||||
<string name="bt_plugin_status_active">Briar 已连接蓝牙</string>
|
||||
<string name="bt_plugin_status_inactive">Briar 不能连接蓝牙</string>
|
||||
<string name="bt_plugin_status_disabled">Briar 配置为不使用蓝牙</string>
|
||||
<string name="transport_lan">无线局域网</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">已登出 Briar</string>
|
||||
<string name="reminder_notification_text">轻按以重新登录。</string>
|
||||
@@ -132,7 +106,6 @@
|
||||
<string name="help">帮助</string>
|
||||
<string name="sorry">抱歉</string>
|
||||
<string name="error_start_activity">在您的系统上不可用</string>
|
||||
<string name="status_heading">状态:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">尚无联系人可供显示</string>
|
||||
<string name="no_contacts_action">轻按 + 号即可添加联系人</string>
|
||||
@@ -190,6 +163,7 @@
|
||||
<string name="connecting_to_device">正在连接至设备\u2026</string>
|
||||
<string name="authenticating_with_device">正在验证设备\u2026</string>
|
||||
<string name="connection_error_title">无法连接到您的联系人</string>
|
||||
<string name="connection_error_explanation">请确保你们连接到了同一个无线局域网中。</string>
|
||||
<string name="connection_error_feedback">如果该问题仍存在,请 <a href="feedback">发送反馈</a> 帮助我们改善应用。</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">添加远处的联系人</string>
|
||||
@@ -425,20 +399,10 @@
|
||||
<string name="pref_theme_auto">自动(白天)</string>
|
||||
<string name="pref_theme_system">系统默认</string>
|
||||
<!--Settings Connections-->
|
||||
<string name="network_settings_title">连接</string>
|
||||
<string name="bluetooth_setting">通过蓝牙连接联系人</string>
|
||||
<string name="wifi_setting">通过同一Wi-Fi和联系人连接</string>
|
||||
<string name="tor_enable_title">通过互联网和联系人连接</string>
|
||||
<string name="tor_enable_summary">为了保护隐私,所有连接都通过Tor网络</string>
|
||||
<string name="tor_network_setting">Tor网络连接方式</string>
|
||||
<string name="tor_network_setting_automatic">基于位置自动选择</string>
|
||||
<string name="tor_network_setting_without_bridges">不通过网桥连接到 Tor</string>
|
||||
<string name="tor_network_setting_with_bridges">通过网桥连接到 Tor</string>
|
||||
<string name="tor_network_setting_never">不连接到互联网</string>
|
||||
<!--How and when Briar will connect to Tor: E.g. "Don't connect to the Internet (in China)" or "Use Tor network with bridges (in Belarus)"-->
|
||||
<string name="tor_network_setting_summary">自动选择:%1$s(在 %2$s)</string>
|
||||
<string name="tor_mobile_data_title">使用移动数据</string>
|
||||
<string name="tor_only_when_charging_title">仅在充电时联网</string>
|
||||
<string name="tor_only_when_charging_summary">当设备使用电池电量时关闭网络连接</string>
|
||||
<!--Settings Security and Panic-->
|
||||
<string name="security_settings_title">安全</string>
|
||||
@@ -539,7 +503,6 @@
|
||||
<string name="permission_camera_location_title">相机和位置</string>
|
||||
<string name="permission_camera_location_request_body"> Briar 需要相机权限以扫描二维码。\n\nBriar 需要位置信息权限以发现蓝牙设备。\n\nBriar 不会存储您的位置或将它分享给任何人。</string>
|
||||
<string name="permission_camera_denied_body">您已拒绝相机权限,而添加联系人需要使用相机。\n\n请考虑授予相机权限。</string>
|
||||
<string name="permission_location_denied_body">您已拒绝访问您的位置,但Briar需要此权限才能发现蓝牙设备。\n\n请考虑授予访问权限。</string>
|
||||
<string name="qr_code">二维码</string>
|
||||
<string name="show_qr_code_fullscreen">全屏显示二维码</string>
|
||||
<!--App Locking-->
|
||||
@@ -549,8 +512,6 @@
|
||||
<string name="lock_unlock_password">使用密码</string>
|
||||
<string name="lock_is_locked">Briar 已锁定</string>
|
||||
<string name="lock_tap_to_unlock">轻按以解锁</string>
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar可以通过互联网、Wi-Fi或蓝牙连接到您的联系人。\n\n为了保护隐私,所有的互联网连接都通过Tor网络。\n\n如果一个联系人可以通过多种方法联系到,Briar会并行地使用它们。</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">韩梅梅</string>
|
||||
|
||||
@@ -56,12 +56,10 @@
|
||||
<string name="lock_button">鎖定程式</string>
|
||||
<string name="settings_button">設置</string>
|
||||
<string name="sign_out_button">登出</string>
|
||||
<!--Transports: Tor-->
|
||||
<!--Transports-->
|
||||
<string name="transport_tor">互聯網</string>
|
||||
<!--Transports: Wi-Fi-->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Transports: Bluetooth-->
|
||||
<string name="transport_bt">藍牙</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<!--Notifications-->
|
||||
<string name="reminder_notification_title">已登出 Briar</string>
|
||||
<string name="reminder_notification_text">輕按以重新登錄。</string>
|
||||
@@ -103,7 +101,6 @@
|
||||
<string name="fix">修復</string>
|
||||
<string name="help">幫助</string>
|
||||
<string name="sorry">抱歉</string>
|
||||
<string name="status_heading">狀態:</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">尚無聯絡人可供顯示</string>
|
||||
<string name="no_contacts_action">輕按 + 號即可添加聯絡人</string>
|
||||
@@ -149,6 +146,7 @@
|
||||
<string name="connecting_to_device">正在連接至裝置\u2026</string>
|
||||
<string name="authenticating_with_device">正在驗證裝置\u2026</string>
|
||||
<string name="connection_error_title">無法連接到您的聯絡人</string>
|
||||
<string name="connection_error_explanation">請確保您們連接到了同一個 Wi-Fi中。</string>
|
||||
<string name="connection_error_feedback">如果該問題仍存在,請 <a href="feedback">發送反饋</a> 幫助我們改善程式。</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">添加遠處的聯絡人</string>
|
||||
@@ -496,7 +494,6 @@
|
||||
<string name="lock_unlock_password">使用密碼</string>
|
||||
<string name="lock_is_locked">Briar 已鎖定</string>
|
||||
<string name="lock_tap_to_unlock">輕按以解鎖</string>
|
||||
<!--Connections Screen-->
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">愛麗詩</string>
|
||||
|
||||
@@ -68,39 +68,11 @@
|
||||
<string name="lock_button">Lock App</string>
|
||||
<string name="settings_button">Settings</string>
|
||||
<string name="sign_out_button">Sign Out</string>
|
||||
<string name="transports_onboarding_text">Tap here to control how Briar connects to your contacts.</string>
|
||||
|
||||
<!-- Transports: Tor -->
|
||||
<!-- Transports -->
|
||||
<string name="transport_tor">Internet</string>
|
||||
<string name="tor_device_status_online_wifi">Your phone has Internet access via Wi-Fi</string>
|
||||
<string name="tor_device_status_online_mobile">Your phone has Internet access via mobile data</string>
|
||||
<string name="tor_device_status_offline">Your phone does not have Internet access</string>
|
||||
<string name="tor_plugin_status_enabling">Briar is connecting to the Internet</string>
|
||||
<string name="tor_plugin_status_active">Briar is connected to the Internet</string>
|
||||
<string name="tor_plugin_status_inactive">Briar can\'t connect to the Internet</string>
|
||||
<string name="tor_plugin_status_disabled">Briar is configured not to use the Internet</string>
|
||||
<string name="tor_plugin_status_disabled_mobile_data">Briar is configured not to use mobile data</string>
|
||||
<string name="tor_plugin_status_disabled_battery">Briar is configured not to use the Internet when running on battery</string>
|
||||
<string name="tor_plugin_status_disabled_country_blocked">Briar is configured not to use the Internet in this country</string>
|
||||
|
||||
<!-- Transports: Wi-Fi -->
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
<string name="transport_lan_long">Same Wi-Fi network</string>
|
||||
<string name="lan_device_status_on">Your phone is connected to Wi-Fi</string>
|
||||
<string name="lan_device_status_off">Your phone is not connected to Wi-Fi</string>
|
||||
<string name="lan_plugin_status_enabling">Briar is connecting to the Wi-Fi network</string>
|
||||
<string name="lan_plugin_status_active">Briar is connected to the Wi-Fi network</string>
|
||||
<string name="lan_plugin_status_inactive">Briar can\'t connect to the Wi-Fi network</string>
|
||||
<string name="lan_plugin_status_disabled">Briar is configured not to use the Wi-Fi network</string>
|
||||
|
||||
<!-- Transports: Bluetooth -->
|
||||
<string name="transport_bt">Bluetooth</string>
|
||||
<string name="bt_device_status_on">Your phone\'s Bluetooth is turned on</string>
|
||||
<string name="bt_device_status_off">Your phone\'s Bluetooth is turned off</string>
|
||||
<string name="bt_plugin_status_enabling">Briar is connecting to Bluetooth</string>
|
||||
<string name="bt_plugin_status_active">Briar is connected to Bluetooth</string>
|
||||
<string name="bt_plugin_status_inactive">Briar can\'t connect to Bluetooth</string>
|
||||
<string name="bt_plugin_status_disabled">Briar is configured not to use Bluetooth</string>
|
||||
<string name="transport_lan">Wi-Fi</string>
|
||||
|
||||
<!-- Notifications -->
|
||||
<string name="reminder_notification_title">Signed out of Briar</string>
|
||||
@@ -149,7 +121,6 @@
|
||||
<string name="help">Help</string>
|
||||
<string name="sorry">Sorry</string>
|
||||
<string name="error_start_activity">Unavailable on your system</string>
|
||||
<string name="status_heading">Status:</string>
|
||||
|
||||
<!-- Contacts and Private Conversations-->
|
||||
<string name="no_contacts">No contacts to show</string>
|
||||
@@ -210,6 +181,7 @@
|
||||
<string name="connecting_to_device">Connecting to device\u2026</string>
|
||||
<string name="authenticating_with_device">Authenticating with device\u2026</string>
|
||||
<string name="connection_error_title">Could not connect to your contact</string>
|
||||
<string name="connection_error_explanation">Please check that you\'re both connected to the same Wi-Fi network.</string>
|
||||
<string name="connection_error_feedback">If this problem persists, please <a href="feedback">send feedback</a> to help us improve the app.</string>
|
||||
|
||||
<!-- Adding Contacts Remotely -->
|
||||
@@ -588,7 +560,6 @@
|
||||
<string name="permission_camera_location_title">Camera and location</string>
|
||||
<string name="permission_camera_location_request_body">To scan the QR code, Briar needs access to the camera.\n\nTo discover Bluetooth devices, Briar needs permission to access your location.\n\nBriar does not store your location or share it with anyone.</string>
|
||||
<string name="permission_camera_denied_body">You have denied access to the camera, but adding contacts requires using the camera.\n\nPlease consider granting access.</string>
|
||||
<string name="permission_location_denied_body">You have denied access to your location, but Briar needs this permission to discover Bluetooth devices.\n\nPlease consider granting access.</string>
|
||||
<string name="qr_code">QR code</string>
|
||||
<string name="show_qr_code_fullscreen">Show QR code fullscreen</string>
|
||||
|
||||
@@ -600,9 +571,6 @@
|
||||
<string name="lock_is_locked">Briar is locked</string>
|
||||
<string name="lock_tap_to_unlock">Tap to unlock</string>
|
||||
|
||||
<!-- Connections Screen -->
|
||||
<string name="transports_help_text">Briar can connect to your contacts via the Internet, Wi-Fi or Bluetooth.\n\nAll Internet connections go through the Tor network for privacy.\n\nIf a contact can be reached by multiple methods, Briar uses them in parallel.</string>
|
||||
|
||||
<!-- Screenshots -->
|
||||
|
||||
<!-- This is a name to be used in screenshots. Feel free to change it to a local name. -->
|
||||
|
||||
@@ -232,6 +232,16 @@
|
||||
android:title="Crash"
|
||||
app:iconSpaceReserved="false"/>
|
||||
|
||||
<Preference
|
||||
android:key="pref_key_export"
|
||||
android:title="Export Account to SD Card"
|
||||
app:iconSpaceReserved="false"/>
|
||||
|
||||
<Preference
|
||||
android:key="pref_key_import"
|
||||
android:title="Import Account from SD Card"
|
||||
app:iconSpaceReserved="false"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.briarproject.briar.android.attachment;
|
||||
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.ImmediateExecutor;
|
||||
import org.briarproject.briar.api.messaging.Attachment;
|
||||
import org.briarproject.briar.api.messaging.AttachmentHeader;
|
||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
@@ -12,13 +11,12 @@ import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.AVAILABLE;
|
||||
import static org.briarproject.briar.android.attachment.AttachmentItem.State.ERROR;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
||||
|
||||
@@ -35,9 +33,8 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
||||
MessagingManager messagingManager =
|
||||
context.mock(MessagingManager.class);
|
||||
imageSizeCalculator = context.mock(ImageSizeCalculator.class);
|
||||
Executor dbExecutor = new ImmediateExecutor();
|
||||
retriever = new AttachmentRetrieverImpl(dbExecutor, messagingManager,
|
||||
dimensions, imageHelper, imageSizeCalculator);
|
||||
retriever = new AttachmentRetrieverImpl(messagingManager, dimensions,
|
||||
imageHelper, imageSizeCalculator);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -50,10 +47,10 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
||||
will(returnValue("jpg"));
|
||||
}});
|
||||
|
||||
AttachmentItem item = retriever.createAttachmentItem(attachment, false);
|
||||
AttachmentItem item = retriever.getAttachmentItem(attachment, false);
|
||||
assertEquals(mimeType, item.getMimeType());
|
||||
assertEquals("jpg", item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -66,8 +63,8 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
||||
will(returnValue(null));
|
||||
}});
|
||||
|
||||
AttachmentItem item = retriever.createAttachmentItem(attachment, false);
|
||||
assertEquals(ERROR, item.getState());
|
||||
AttachmentItem item = retriever.getAttachmentItem(attachment, false);
|
||||
assertTrue(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -83,7 +80,7 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
||||
will(returnValue("jpg"));
|
||||
}});
|
||||
|
||||
AttachmentItem item = retriever.createAttachmentItem(attachment, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(attachment, true);
|
||||
assertEquals(msgId, item.getMessageId());
|
||||
assertEquals(160, item.getWidth());
|
||||
assertEquals(240, item.getHeight());
|
||||
@@ -91,7 +88,7 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
||||
assertEquals(240, item.getThumbnailHeight());
|
||||
assertEquals(mimeType, item.getMimeType());
|
||||
assertEquals("jpg", item.getExtension());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -107,12 +104,12 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
||||
will(returnValue("jpg"));
|
||||
}});
|
||||
|
||||
AttachmentItem item = retriever.createAttachmentItem(attachment, true);
|
||||
AttachmentItem item = retriever.getAttachmentItem(attachment, true);
|
||||
assertEquals(1728, item.getWidth());
|
||||
assertEquals(2592, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxHeight, item.getThumbnailHeight());
|
||||
assertEquals(AVAILABLE, item.getState());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -128,8 +125,8 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
||||
will(returnValue(null));
|
||||
}});
|
||||
|
||||
AttachmentItem item = retriever.createAttachmentItem(attachment, true);
|
||||
assertEquals(ERROR, item.getState());
|
||||
AttachmentItem item = retriever.getAttachmentItem(attachment, true);
|
||||
assertTrue(item.hasError());
|
||||
}
|
||||
|
||||
private Attachment getAttachment(String contentType) {
|
||||
|
||||
@@ -68,7 +68,7 @@ public interface MessagingManager extends ConversationClient {
|
||||
String getMessageText(MessageId m) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the attachment with the given attachment header.
|
||||
* Returns the attachment with the given message ID and content type.
|
||||
*
|
||||
* @throws InvalidAttachmentException If the header refers to a message
|
||||
* that is not an attachment, or to an attachment that does not have the
|
||||
|
||||
@@ -83,6 +83,8 @@ public class FeedManagerIntegrationTest extends BriarTestCase {
|
||||
assertEquals(url, feed.getUrl());
|
||||
assertEquals(feedBlog, feed.getBlog());
|
||||
assertEquals("Schneier on Security", feed.getTitle());
|
||||
assertEquals("A blog covering security and security technology.",
|
||||
feed.getDescription());
|
||||
assertEquals(feed.getTitle(), feed.getBlog().getName());
|
||||
assertEquals(feed.getTitle(), feed.getLocalAuthor().getName());
|
||||
|
||||
|
||||
@@ -69,8 +69,7 @@ Returns a JSON array of contacts:
|
||||
"handshakePublicKey": "XnYRd7a7E4CTqgAvh4hCxh/YZ0EPscxknB9ZcEOpSzY=",
|
||||
"verified": true,
|
||||
"lastChatActivity": 1557838312175,
|
||||
"connected": false,
|
||||
"unreadCount": 7
|
||||
"connected": false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -183,18 +182,6 @@ Note that it's also possible to add contacts nearby via Bluetooth/Wifi or
|
||||
introductions. In these cases contacts omit the `pendingContact` state and
|
||||
directly become `contact`s.
|
||||
|
||||
### Changing alias of a contact
|
||||
|
||||
`PUT /v1/contacts/{contactId}/alias`
|
||||
|
||||
The alias should be posted as a JSON object:
|
||||
|
||||
```json
|
||||
{
|
||||
"alias": "A nickname for the new contact"
|
||||
}
|
||||
```
|
||||
|
||||
### Removing a contact
|
||||
|
||||
`DELETE /v1/contacts/{contactId}`
|
||||
@@ -246,25 +233,6 @@ The text of the message should be posted as JSON:
|
||||
}
|
||||
```
|
||||
|
||||
### Marking private messages as read
|
||||
|
||||
`POST /v1/messages/{contactId}/read`
|
||||
|
||||
The `messageId` of the message to be marked as read
|
||||
needs to be provided in the request body as follows:
|
||||
|
||||
```json
|
||||
{
|
||||
"messageId": "+AIMMgOCPFF8HDEhiEHYjbfKrg7v0G94inKxjvjYzA8="
|
||||
}
|
||||
```
|
||||
|
||||
### Deleting all private messages
|
||||
|
||||
`DELETE /v1/messages/{contactId}/all`
|
||||
|
||||
It returns with a status code `200`, if removal was successful.
|
||||
|
||||
### Listing blog posts
|
||||
|
||||
`GET /v1/blogs/posts`
|
||||
@@ -441,39 +409,3 @@ When the last connection is lost (the contact goes offline), it sends a `Contact
|
||||
"type": "event"
|
||||
}
|
||||
```
|
||||
|
||||
### A message was sent
|
||||
|
||||
When Briar sent a message to a contact, it sends a `MessagesSentEvent`. This is indicated in Briar
|
||||
by showing one tick next to the message.
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"contactId": 1,
|
||||
"messageIds": [
|
||||
"+AIMMgOCPFF8HDEhiEHYjbfKrg7v0G94inKxjvjYzA8="
|
||||
]
|
||||
},
|
||||
"name": "MessagesSentEvent",
|
||||
"type": "event"
|
||||
}
|
||||
```
|
||||
|
||||
### A message was acknowledged
|
||||
|
||||
When a contact acknowledges that they received a message, Briar sends a `MessagesAckedEvent`.
|
||||
This is indicated in Briar by showing two ticks next to the message.
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"contactId": 1,
|
||||
"messageIds": [
|
||||
"+AIMMgOCPFF8HDEhiEHYjbfKrg7v0G94inKxjvjYzA8="
|
||||
]
|
||||
},
|
||||
"name": "MessagesAckedEvent",
|
||||
"type": "event"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
import java.util.jar.JarEntry
|
||||
import java.util.jar.JarFile
|
||||
import java.util.jar.JarOutputStream
|
||||
|
||||
import static java.util.Collections.list
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'idea'
|
||||
@@ -53,34 +47,6 @@ jar {
|
||||
from {
|
||||
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
|
||||
}
|
||||
doLast() {
|
||||
// Rename the original jar
|
||||
File jar = project.jar.archivePath
|
||||
String srcPath = jar.toString().replaceFirst('\\.jar$', '.unsorted.jar')
|
||||
File srcFile = new File(srcPath)
|
||||
jar.renameTo(srcFile)
|
||||
JarFile srcJarFile = new JarFile(srcFile)
|
||||
OutputStream destStream = new JarOutputStream(new FileOutputStream(jar))
|
||||
// Read and sort the entries
|
||||
Map<String, JarEntry> entries = new TreeMap<String, JarEntry>()
|
||||
for (JarEntry e : list(srcJarFile.entries())) entries.put(e.getName(), e)
|
||||
// Write the sorted entries
|
||||
for (JarEntry srcEntry : entries.values()) {
|
||||
JarEntry destEntry = new JarEntry(srcEntry.getName())
|
||||
destEntry.setTime(0)
|
||||
destStream.putNextEntry(destEntry)
|
||||
InputStream srcStream = srcJarFile.getInputStream(srcEntry)
|
||||
int read
|
||||
byte[] buf = new byte[4096]
|
||||
while ((read = srcStream.read(buf, 0, buf.length)) != -1) {
|
||||
destStream.write(buf, 0, read)
|
||||
}
|
||||
destStream.closeEntry()
|
||||
srcStream.close()
|
||||
}
|
||||
destStream.close()
|
||||
srcJarFile.close()
|
||||
}
|
||||
}
|
||||
|
||||
// At the moment for non-Android projects we need to explicitly mark the code generated by kapt
|
||||
|
||||
@@ -81,20 +81,11 @@ constructor(
|
||||
path("/:contactId") {
|
||||
delete { ctx -> contactController.delete(ctx) }
|
||||
}
|
||||
path("/:contactId/alias") {
|
||||
put { ctx -> contactController.setContactAlias(ctx) }
|
||||
}
|
||||
}
|
||||
path("/messages/:contactId") {
|
||||
get { ctx -> messagingController.list(ctx) }
|
||||
post { ctx -> messagingController.write(ctx) }
|
||||
}
|
||||
path("/messages/:contactId/read") {
|
||||
post { ctx -> messagingController.markMessageRead(ctx) }
|
||||
}
|
||||
path("/messages/:contactId/all") {
|
||||
delete { ctx -> messagingController.deleteAllMessages(ctx) }
|
||||
}
|
||||
path("/forums") {
|
||||
get { ctx -> forumController.list(ctx) }
|
||||
post { ctx -> forumController.create(ctx) }
|
||||
|
||||
@@ -9,7 +9,6 @@ interface ContactController {
|
||||
fun addPendingContact(ctx: Context): Context
|
||||
fun listPendingContacts(ctx: Context): Context
|
||||
fun removePendingContact(ctx: Context): Context
|
||||
fun setContactAlias(ctx: Context): Context
|
||||
fun delete(ctx: Context): Context
|
||||
|
||||
}
|
||||
|
||||
@@ -77,8 +77,7 @@ constructor(
|
||||
val contacts = contactManager.contacts.map { contact ->
|
||||
val latestMsgTime = conversationManager.getGroupCount(contact.id).latestMsgTime
|
||||
val connected = connectionRegistry.isConnected(contact.id)
|
||||
val unreadCount = conversationManager.getGroupCount(contact.id).unreadCount
|
||||
contact.output(latestMsgTime, connected, unreadCount)
|
||||
contact.output(latestMsgTime, connected)
|
||||
}
|
||||
return ctx.json(contacts)
|
||||
}
|
||||
@@ -92,7 +91,9 @@ constructor(
|
||||
val link = ctx.getFromJson(objectMapper, "link")
|
||||
val alias = ctx.getFromJson(objectMapper, "alias")
|
||||
if (!LINK_REGEX.matcher(link).find()) throw BadRequestResponse("Invalid Link")
|
||||
checkAliasLength(alias)
|
||||
val aliasUtf8 = toUtf8(alias)
|
||||
if (aliasUtf8.isEmpty() || aliasUtf8.size > MAX_AUTHOR_NAME_LENGTH)
|
||||
throw BadRequestResponse("Invalid Alias")
|
||||
val pendingContact = contactManager.addPendingContact(link, alias)
|
||||
return ctx.json(pendingContact.output())
|
||||
}
|
||||
@@ -123,18 +124,6 @@ constructor(
|
||||
return ctx
|
||||
}
|
||||
|
||||
override fun setContactAlias(ctx: Context): Context {
|
||||
val contactId = ctx.getContactIdFromPathParam()
|
||||
val alias = ctx.getFromJson(objectMapper, "alias")
|
||||
checkAliasLength(alias)
|
||||
try {
|
||||
contactManager.setContactAlias(contactId, alias)
|
||||
} catch (e: NoSuchContactException) {
|
||||
throw NotFoundResponse()
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
override fun delete(ctx: Context): Context {
|
||||
val contactId = ctx.getContactIdFromPathParam()
|
||||
try {
|
||||
@@ -145,10 +134,4 @@ constructor(
|
||||
return ctx
|
||||
}
|
||||
|
||||
private fun checkAliasLength(alias: String) {
|
||||
val aliasUtf8 = toUtf8(alias)
|
||||
if (aliasUtf8.isEmpty() || aliasUtf8.size > MAX_AUTHOR_NAME_LENGTH)
|
||||
throw BadRequestResponse("Invalid Alias")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,13 +7,12 @@ import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent
|
||||
import org.briarproject.bramble.identity.output
|
||||
import org.briarproject.briar.headless.json.JsonDict
|
||||
|
||||
internal fun Contact.output(latestMsgTime: Long, connected: Boolean, unreadCount: Int) = JsonDict(
|
||||
internal fun Contact.output(latestMsgTime: Long, connected: Boolean) = JsonDict(
|
||||
"contactId" to id.int,
|
||||
"author" to author.output(),
|
||||
"verified" to isVerified,
|
||||
"lastChatActivity" to latestMsgTime,
|
||||
"connected" to connected,
|
||||
"unreadCount" to unreadCount
|
||||
"connected" to connected
|
||||
).apply {
|
||||
alias?.let { put("alias", it) }
|
||||
handshakePublicKey?.let { put("handshakePublicKey", it.encoded) }
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user