Compare commits

..

1 Commits

Author SHA1 Message Date
akwizgran
327e12e9f8 Don't allow multiple messages to be queued in memory for validation at startup. 2020-09-24 15:42:18 +01:00
34 changed files with 84 additions and 905 deletions

View File

@@ -28,20 +28,6 @@
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" /> <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
</JavaCodeStyleSettings> </JavaCodeStyleSettings>
<JetCodeStyleSettings> <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" /> <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings> </JetCodeStyleSettings>
<XML> <XML>

View File

@@ -3,4 +3,3 @@ gen
build build
.settings .settings
src/main/res/raw/*.zip src/main/res/raw/*.zip
src/main/jniLibs

View File

@@ -5,14 +5,14 @@ apply plugin: 'witness'
apply from: 'witness.gradle' apply from: 'witness.gradle'
android { android {
compileSdkVersion rootProject.ext.compileSdkVersion compileSdkVersion 29
buildToolsVersion rootProject.ext.buildToolsVersion buildToolsVersion '29.0.2'
defaultConfig { defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion 16
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion 28
versionCode rootProject.ext.versionCode versionCode 10209
versionName rootProject.ext.versionName versionName "1.2.9"
consumerProguardFiles 'proguard-rules.txt' consumerProguardFiles 'proguard-rules.txt'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -53,12 +53,10 @@ dependencies {
} }
def torBinariesDir = 'src/main/res/raw' def torBinariesDir = 'src/main/res/raw'
def torLibsDir = 'src/main/jniLibs'
task cleanTorBinaries { task cleanTorBinaries {
doLast { doLast {
delete fileTree(torBinariesDir) { include '*.zip' } delete fileTree(torBinariesDir) { include '*.zip' }
delete fileTree(torLibsDir) { include '**/*.so' }
} }
} }
@@ -69,36 +67,8 @@ task unpackTorBinaries {
copy { copy {
from configurations.tor.collect { zipTree(it) } from configurations.tor.collect { zipTree(it) }
into torBinariesDir into torBinariesDir
include 'geoip.zip' // TODO: Remove after next Tor upgrade, which won't include non-PIE binaries
} include 'geoip.zip', '*_pie.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'
}
}
}
} }
} }
dependsOn cleanTorBinaries dependsOn cleanTorBinaries
@@ -106,6 +76,5 @@ task unpackTorBinaries {
tasks.withType(MergeResources) { tasks.withType(MergeResources) {
inputs.dir torBinariesDir inputs.dir torBinariesDir
inputs.dir torLibsDir
dependsOn unpackTorBinaries dependsOn unpackTorBinaries
} }

View File

@@ -135,7 +135,6 @@ class AndroidBluetoothPlugin
@Override @Override
@Nullable @Nullable
String getBluetoothAddress() { String getBluetoothAddress() {
if (adapter == null) return null;
String address = AndroidUtils.getBluetoothAddress(app, adapter); String address = AndroidUtils.getBluetoothAddress(app, adapter);
return address.isEmpty() ? null : address; return address.isEmpty() ? null : address;
} }

View File

@@ -16,42 +16,19 @@ import org.briarproject.bramble.api.system.AndroidWakeLockManager;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.ResourceProvider; import org.briarproject.bramble.api.system.ResourceProvider;
import org.briarproject.bramble.util.AndroidUtils;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor; 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 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 @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
class AndroidTorPlugin extends TorPlugin { 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 Application app;
private final AndroidWakeLock wakeLock; private final AndroidWakeLock wakeLock;
private final File torLib, obfs4Lib;
AndroidTorPlugin(Executor ioExecutor, AndroidTorPlugin(Executor ioExecutor,
Executor wakefulIoExecutor, Executor wakefulIoExecutor,
@@ -78,9 +55,6 @@ class AndroidTorPlugin extends TorPlugin {
maxIdleTime, torDirectory); maxIdleTime, torDirectory);
this.app = app; this.app = app;
wakeLock = wakeLockManager.createWakeLock("TorPlugin"); wakeLock = wakeLockManager.createWakeLock("TorPlugin");
String nativeLibDir = app.getApplicationInfo().nativeLibraryDir;
torLib = new File(nativeLibDir, TOR_LIB_NAME);
obfs4Lib = new File(nativeLibDir, OBFS4_LIB_NAME);
} }
@Override @Override
@@ -111,112 +85,4 @@ class AndroidTorPlugin extends TorPlugin {
super.stop(); super.stop();
wakeLock.release(); 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;
}
} }

View File

@@ -132,7 +132,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private final CircumventionProvider circumventionProvider; private final CircumventionProvider circumventionProvider;
private final ResourceProvider resourceProvider; private final ResourceProvider resourceProvider;
private final int maxLatency, maxIdleTime, socketTimeout; 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 File doneFile, cookieFile;
private final AtomicBoolean used = new AtomicBoolean(false); private final AtomicBoolean used = new AtomicBoolean(false);
@@ -181,7 +181,9 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
socketTimeout = Integer.MAX_VALUE; socketTimeout = Integer.MAX_VALUE;
else socketTimeout = maxIdleTime * 2; else socketTimeout = maxIdleTime * 2;
this.torDirectory = torDirectory; this.torDirectory = torDirectory;
torFile = new File(torDirectory, "tor");
geoIpFile = new File(torDirectory, "geoip"); geoIpFile = new File(torDirectory, "geoip");
obfs4File = new File(torDirectory, "obfs4proxy");
configFile = new File(torDirectory, "torrc"); configFile = new File(torDirectory, "torrc");
doneFile = new File(torDirectory, "done"); doneFile = new File(torDirectory, "done");
cookieFile = new File(torDirectory, ".tor/control_auth_cookie"); cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
@@ -190,14 +192,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
new PoliteExecutor("TorPlugin", ioExecutor, 1); new PoliteExecutor("TorPlugin", ioExecutor, 1);
} }
protected File getTorExecutableFile() {
return new File(torDirectory, "tor");
}
protected File getObfs4ExecutableFile() {
return new File(torDirectory, "obfs4proxy");
}
@Override @Override
public TransportId getId() { public TransportId getId() {
return TorConstants.ID; return TorConstants.ID;
@@ -230,7 +224,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
LOG.warning("Old auth cookie not deleted"); LOG.warning("Old auth cookie not deleted");
// Start a new Tor process // Start a new Tor process
LOG.info("Starting Tor"); LOG.info("Starting Tor");
File torFile = getTorExecutableFile();
String torPath = torFile.getAbsolutePath(); String torPath = torFile.getAbsolutePath();
String configPath = configFile.getAbsolutePath(); String configPath = configFile.getAbsolutePath();
String pid = String.valueOf(getProcessId()); String pid = String.valueOf(getProcessId());
@@ -329,43 +322,44 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
} }
private void installAssets() throws PluginException { private void installAssets() throws PluginException {
InputStream in = null;
OutputStream out = null;
try { try {
// The done file may already exist from a previous installation // The done file may already exist from a previous installation
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored
doneFile.delete(); doneFile.delete();
installTorExecutable(); // Unzip the Tor binary to the filesystem
installObfs4Executable(); in = getTorInputStream();
extract(getGeoIpInputStream(), geoIpFile); out = new FileOutputStream(torFile);
extract(getConfigInputStream(), configFile); 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()) if (!doneFile.createNewFile())
LOG.warning("Failed to create done file"); LOG.warning("Failed to create done file");
} catch (IOException e) { } catch (IOException e) {
tryToClose(in, LOG, WARNING);
tryToClose(out, LOG, WARNING);
throw new PluginException(e); throw new PluginException(e);
} }
} }
protected void extract(InputStream in, File dest) throws IOException { private InputStream getTorInputStream() throws IOException {
OutputStream out = new FileOutputStream(dest);
copyAndClose(in, out);
}
protected void installTorExecutable() throws IOException {
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Installing Tor binary for " + architecture); 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 InputStream in = resourceProvider
.getResourceInputStream("tor_" + architecture, ".zip"); .getResourceInputStream("tor_" + architecture, ".zip");
ZipInputStream zin = new ZipInputStream(in); ZipInputStream zin = new ZipInputStream(in);
@@ -382,6 +376,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
} }
private InputStream getObfs4InputStream() throws IOException { private InputStream getObfs4InputStream() throws IOException {
if (LOG.isLoggable(INFO))
LOG.info("Installing obfs4proxy binary for " + architecture);
InputStream in = resourceProvider InputStream in = resourceProvider
.getResourceInputStream("obfs4proxy_" + architecture, ".zip"); .getResourceInputStream("obfs4proxy_" + architecture, ".zip");
ZipInputStream zin = new ZipInputStream(in); ZipInputStream zin = new ZipInputStream(in);
@@ -573,7 +569,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (enable) { if (enable) {
Collection<String> conf = new ArrayList<>(); Collection<String> conf = new ArrayList<>();
conf.add("UseBridges 1"); conf.add("UseBridges 1");
File obfs4File = getObfs4ExecutableFile();
if (needsMeek) { if (needsMeek) {
conf.add("ClientTransportPlugin meek_lite exec " + conf.add("ClientTransportPlugin meek_lite exec " +
obfs4File.getAbsolutePath()); obfs4File.getAbsolutePath());

View File

@@ -35,6 +35,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject; import javax.inject.Inject;
@@ -124,8 +125,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
Group g = db.getGroup(txn, m.getGroupId()); Group g = db.getGroup(txn, m.getGroupId());
return new Pair<>(m, g); return new Pair<>(m, g);
}); });
validateMessageAsync(mg.getFirst(), mg.getSecond()); validateMessageAsync(mg.getFirst(), mg.getSecond(), unvalidated);
validateNextMessageAsync(unvalidated);
} catch (NoSuchMessageException e) { } catch (NoSuchMessageException e) {
LOG.info("Message removed before validation"); LOG.info("Message removed before validation");
validateNextMessageAsync(unvalidated); validateNextMessageAsync(unvalidated);
@@ -213,12 +213,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
} }
} }
private void validateMessageAsync(Message m, Group g) { private void validateMessageAsync(Message m, Group g,
validationExecutor.execute(() -> validateMessage(m, g)); @Nullable Queue<MessageId> unvalidated) {
validationExecutor.execute(() -> validateMessage(m, g, unvalidated));
} }
@ValidationExecutor @ValidationExecutor
private void validateMessage(Message m, Group g) { private void validateMessage(Message m, Group g,
@Nullable Queue<MessageId> unvalidated) {
ClientMajorVersion cv = ClientMajorVersion cv =
new ClientMajorVersion(g.getClientId(), g.getMajorVersion()); new ClientMajorVersion(g.getClientId(), g.getMajorVersion());
MessageValidator v = validators.get(cv); MessageValidator v = validators.get(cv);
@@ -234,6 +236,8 @@ class ValidationManagerImpl implements ValidationManager, Service,
Queue<MessageId> invalidate = new LinkedList<>(); Queue<MessageId> invalidate = new LinkedList<>();
invalidate.add(m.getId()); invalidate.add(m.getId());
invalidateNextMessageAsync(invalidate); invalidateNextMessageAsync(invalidate);
} finally {
if (unvalidated != null) validateNextMessageAsync(unvalidated);
} }
} }
} }
@@ -440,7 +444,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
try { try {
Group g = db.transactionWithResult(true, txn -> Group g = db.transactionWithResult(true, txn ->
db.getGroup(txn, m.getGroupId())); db.getGroup(txn, m.getGroupId()));
validateMessageAsync(m, g); validateMessageAsync(m, g, null);
} catch (NoSuchGroupException e) { } catch (NoSuchGroupException e) {
LOG.info("Group removed before validation"); LOG.info("Group removed before validation");
} catch (DbException e) { } catch (DbException e) {

View File

@@ -16,14 +16,14 @@ def getStdout = { command, defaultValue ->
} }
android { android {
compileSdkVersion rootProject.ext.compileSdkVersion compileSdkVersion 29
buildToolsVersion rootProject.ext.buildToolsVersion buildToolsVersion '29.0.2'
defaultConfig { defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion 16
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion 28
versionCode rootProject.ext.versionCode versionCode 10209
versionName rootProject.ext.versionName versionName "1.2.9"
applicationId "org.briarproject.briar.android" applicationId "org.briarproject.briar.android"
buildConfigField "String", "GitHash", buildConfigField "String", "GitHash",
"\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\"" "\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\""

View File

@@ -24,7 +24,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/include_in_report" app:layout_constraintTop_toBottomOf="@+id/include_in_report"

View File

@@ -27,7 +27,6 @@
<string name="enter_password">‮كلمة السّر</string> <string name="enter_password">‮كلمة السّر</string>
<string name="try_again">كلمة السرّ خاطئة, الرجاء المحاولة مجدّدا</string> <string name="try_again">كلمة السرّ خاطئة, الرجاء المحاولة مجدّدا</string>
<string name="dialog_title_cannot_check_password">لا يمكن التحقق من كلمة السر</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="sign_in_button">تسجيل الدخول</string>
<string name="forgotten_password">نسيتُ كلمة السر</string> <string name="forgotten_password">نسيتُ كلمة السر</string>
<string name="dialog_title_lost_password">فقدت كلمة السر</string> <string name="dialog_title_lost_password">فقدت كلمة السر</string>
@@ -65,36 +64,12 @@
<string name="lock_button">قفل التطبيق</string> <string name="lock_button">قفل التطبيق</string>
<string name="settings_button">الإعدادات</string> <string name="settings_button">الإعدادات</string>
<string name="sign_out_button">تسجيل الخروج</string> <string name="sign_out_button">تسجيل الخروج</string>
<string name="transports_onboarding_text">إلمس هنا من أجل التحكم بطريقةالربط مع جهات الاتصال.</string>
<!--Transports: Tor--> <!--Transports: Tor-->
<string name="transport_tor">إنترنت</string> <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--> <!--Transports: Wi-Fi-->
<string name="transport_lan">واي-فاي</string> <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--> <!--Transports: Bluetooth-->
<string name="transport_bt">بلوتوث</string> <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>
<!--Notifications--> <!--Notifications-->
<string name="reminder_notification_title">تم تسجيل الخروج من Briar (براير)</string> <string name="reminder_notification_title">تم تسجيل الخروج من Briar (براير)</string>
<string name="reminder_notification_text">الرجاء اللمس لإعادة الدخول</string> <string name="reminder_notification_text">الرجاء اللمس لإعادة الدخول</string>
@@ -484,8 +459,6 @@
<string name="tor_enable_summary">كل جهات الاتصال تمر عبر شبكة تور من أجل الخصوصية</string> <string name="tor_enable_summary">كل جهات الاتصال تمر عبر شبكة تور من أجل الخصوصية</string>
<string name="tor_network_setting">وسيلة الاتصال لشبكة تور</string> <string name="tor_network_setting">وسيلة الاتصال لشبكة تور</string>
<string name="tor_network_setting_automatic">تلقائيًا حسب الموقع</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> <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)"--> <!--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_network_setting_summary">تلقائيا: %1$s (في %2$s)</string>
@@ -601,7 +574,6 @@
<string name="lock_is_locked">Briar (براير) مقفل</string> <string name="lock_is_locked">Briar (براير) مقفل</string>
<string name="lock_tap_to_unlock">الرجاء اللمس لفك القفل</string> <string name="lock_tap_to_unlock">الرجاء اللمس لفك القفل</string>
<!--Connections Screen--> <!--Connections Screen-->
<string name="transports_help_text">يمكن ل Briar التواصل مع جهات الاتصال عن طريق الانترنت, شكبة ال Wi-Fi أو البلوتوث.n\n\كل وسائل الاتصال عن طريق الانترنت تمر عبر شبكة تور من أجل الخصوصية.n\n\إذا كان من الممكن الوصول إلى شبكة إتصال بعدة طرق فإن Briar سوف يستعملهم جميعاً بالتوازي.</string>
<!--Screenshots--> <!--Screenshots-->
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_alice">آليس</string> <string name="screenshot_alice">آليس</string>

View File

@@ -211,7 +211,7 @@
<string name="add_contact_choose_nickname">Wähle einen Spitznamen</string> <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="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="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_clip_label">Briar Link</string>
<string name="link_copied_toast">Link kopiert</string> <string name="link_copied_toast">Link kopiert</string>
<string name="adding_contact_error">Es gab einen Fehler beim Hinzufügen des Kontaktes.</string> <string name="adding_contact_error">Es gab einen Fehler beim Hinzufügen des Kontaktes.</string>

View File

@@ -157,12 +157,12 @@
<string name="dialog_message_delete_all_messages">¿Estás seguro de que deseas eliminar todos los mensajes?</string> <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_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_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_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_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_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_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, debes 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="delete_contact">Eliminar contacto</string>
<string name="dialog_title_delete_contact">Confirmar eliminación de 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> <string name="dialog_message_delete_contact">¿Seguro que quieres eliminar este contacto y todos los mensajes intercambiados entre vosotros?</string>

View File

@@ -31,7 +31,7 @@
<string name="sign_in_button">Connexion</string> <string name="sign_in_button">Connexion</string>
<string name="forgotten_password">Jai oublié mon mot de passe</string> <string name="forgotten_password">Jai oublié mon mot de passe</string>
<string name="dialog_title_lost_password">Mot de passe oublié</string> <string name="dialog_title_lost_password">Mot de passe oublié</string>
<string name="dialog_message_lost_password">Votre compte Briar est enregistré chiffré sur votre appareil, pas dans le nuage, et nous ne pouvons donc pas réinitialiser votre mot de passe. Voulez-vous supprimer votre compte et recommencer?\n\nAttention : vos identités, contacts et messages seront perdus irrémédiablement.</string> <string name="dialog_message_lost_password">Votre compte Briar est enregistré chiffré sur votre appareil, pas dans le nuage, et nous ne pouvons donc pas réinitialiser votre mot de passe. Souhaitez-vous supprimer votre compte et recommencer?\n\nAttention : vos identités, contacts et messages seront perdus irrémédiablement.</string>
<string name="startup_failed_notification_title">Impossible de démarrer Briar</string> <string name="startup_failed_notification_title">Impossible de démarrer Briar</string>
<string name="startup_failed_notification_text">Toucher pour plus dinformations.</string> <string name="startup_failed_notification_text">Toucher pour plus dinformations.</string>
<string name="startup_failed_activity_title">Échec de démarrage de Briar</string> <string name="startup_failed_activity_title">Échec de démarrage de Briar</string>
@@ -143,7 +143,7 @@
<string name="no_contacts_action">Touchez licône + pour ajouter un contact</string> <string name="no_contacts_action">Touchez licône + pour ajouter un contact</string>
<string name="date_no_private_messages">Aucun message.</string> <string name="date_no_private_messages">Aucun message.</string>
<string name="no_private_messages">Aucun message à afficher</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_caption_hint">Ajouter une légende (facultatif)</string>
<string name="image_attach">Joindre une image</string> <string name="image_attach">Joindre une image</string>
<string name="image_attach_error">Impossible de joindre une ou des images</string> <string name="image_attach_error">Impossible de joindre une ou des images</string>
@@ -154,7 +154,7 @@
<string name="set_alias_button">Modifier</string> <string name="set_alias_button">Modifier</string>
<string name="delete_all_messages">Supprimer tous les messages</string> <string name="delete_all_messages">Supprimer tous les messages</string>
<string name="dialog_title_delete_all_messages">Confirmer la suppression des messages</string> <string name="dialog_title_delete_all_messages">Confirmer la suppression des messages</string>
<string name="dialog_message_delete_all_messages">Voulez-vous vraiment supprimer tous les messages?</string> <string name="dialog_message_delete_all_messages">Souhaitez-vous vraiment supprimer tous les messages?</string>
<string name="dialog_title_not_all_messages_deleted">Impossible de supprimer tous les messages</string> <string name="dialog_title_not_all_messages_deleted">Impossible de supprimer tous les messages</string>
<string name="dialog_message_not_deleted_ongoing_both">Les messages relatifs aux invitations et présentations en cours ne peuvent pas être supprimés jusquà leur conclusion.</string> <string name="dialog_message_not_deleted_ongoing_both">Les messages relatifs aux invitations et présentations en cours ne peuvent pas être supprimés jusquà leur conclusion.</string>
<string name="dialog_message_not_deleted_ongoing_introductions">Les messages relatifs aux présentations en cours ne peuvent pas être supprimés jusquà leur conclusion.</string> <string name="dialog_message_not_deleted_ongoing_introductions">Les messages relatifs aux présentations en cours ne peuvent pas être supprimés jusquà leur conclusion.</string>
@@ -165,13 +165,13 @@
<string name="dialog_message_not_deleted_not_all_selected_invitations">Pour supprimer une invitation, vous devez sélectionner la demande et la réponse.</string> <string name="dialog_message_not_deleted_not_all_selected_invitations">Pour supprimer une invitation, vous devez sélectionner la demande et la réponse.</string>
<string name="delete_contact">Supprimer le contact</string> <string name="delete_contact">Supprimer le contact</string>
<string name="dialog_title_delete_contact">Confirmer la suppression du contact</string> <string name="dialog_title_delete_contact">Confirmer la suppression du contact</string>
<string name="dialog_message_delete_contact">Voulez-vous vraiment supprimer ce contact et tous les messages associés?</string> <string name="dialog_message_delete_contact">Souhaitez-vous vraiment supprimer ce contact et tous les messages associés?</string>
<string name="contact_deleted_toast">Le contact a été supprimé</string> <string name="contact_deleted_toast">Le contact a été supprimé</string>
<!--This is shown in the action bar when opening an image in fullscreen that the user sent--> <!--This is shown in the action bar when opening an image in fullscreen that the user sent-->
<string name="you">Vous</string> <string name="you">Vous</string>
<string name="save_image">Enregistrer limage</string> <string name="save_image">Enregistrer limage</string>
<string name="dialog_title_save_image">Enregistrer limage?</string> <string name="dialog_title_save_image">Enregistrer limage?</string>
<string name="dialog_message_save_image">Lenregistrement de cette image permettra aux autres applis dy accéder.\n\n Voulez-vous vraiment lenregistrer?</string> <string name="dialog_message_save_image">Lenregistrement de cette image permettra aux autres applis dy accéder.\n\n Souhaitez-vous vraiment lenregistrer?</string>
<string name="save_image_success">Limage a été enregistrée</string> <string name="save_image_success">Limage a été enregistrée</string>
<string name="save_image_error">Impossible denregistrer limage</string> <string name="save_image_error">Impossible denregistrer limage</string>
<string name="dialog_title_no_image_support">Les images ne sont pas disponibles</string> <string name="dialog_title_no_image_support">Les images ne sont pas disponibles</string>
@@ -266,7 +266,7 @@
<string name="introduction_sent">Votre présentation a été envoyée.</string> <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_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_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_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_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> <string name="introduction_response_accepted_sent">Vous avez accepté dêtre présenté à %1$s.</string>
@@ -299,10 +299,10 @@
<string name="groups_member_joined">%s sest joint au groupe</string> <string name="groups_member_joined">%s sest joint au groupe</string>
<string name="groups_leave">Quitter le groupe</string> <string name="groups_leave">Quitter le groupe</string>
<string name="groups_leave_dialog_title">Confirmer la sortie du groupe</string> <string name="groups_leave_dialog_title">Confirmer la sortie du groupe</string>
<string name="groups_leave_dialog_message">Voulez-vous vraiment quitter ce groupe?</string> <string name="groups_leave_dialog_message">Souhaitez-vous vraiment quitter ce groupe?</string>
<string name="groups_dissolve">Dissoudre le groupe</string> <string name="groups_dissolve">Dissoudre le groupe</string>
<string name="groups_dissolve_dialog_title">Confirmer la dissolution du groupe</string> <string name="groups_dissolve_dialog_title">Confirmer la dissolution du groupe</string>
<string name="groups_dissolve_dialog_message">Voulez-vous vraiment dissoudre ce groupe?\n\nLes autres participants ne pourront pas poursuivre leur conversation et ne recevront peut-être pas les derniers messages.</string> <string name="groups_dissolve_dialog_message">Souhaitez-vous vraiment dissoudre ce groupe?\n\nLes autres participants ne pourront pas poursuivre leur conversation et ne recevront peut-être pas les derniers messages.</string>
<string name="groups_dissolve_button">Dissoudre</string> <string name="groups_dissolve_button">Dissoudre</string>
<string name="groups_dissolved_dialog_title">Le groupe a été dissous</string> <string name="groups_dissolved_dialog_title">Le groupe a été dissous</string>
<string name="groups_dissolved_dialog_message">Le créateur de ce groupe la dissous.\n\nVous ne pouvez plus écrire de messages au groupe et ne recevrez peut-être pas tous ceux qui y ont été publiés.</string> <string name="groups_dissolved_dialog_message">Le créateur de ce groupe la dissous.\n\nVous ne pouvez plus écrire de messages au groupe et ne recevrez peut-être pas tous ceux qui y ont été publiés.</string>
@@ -346,7 +346,7 @@
<string name="btn_reply">Répondre</string> <string name="btn_reply">Répondre</string>
<string name="forum_leave">Quitter le forum</string> <string name="forum_leave">Quitter le forum</string>
<string name="dialog_title_leave_forum">Confirmer la sortie du forum</string> <string name="dialog_title_leave_forum">Confirmer la sortie du forum</string>
<string name="dialog_message_leave_forum">Voulez-vous vraiment quitter ce forum?\n\nLes contacts avec qui vous lavez partagé pourraient ne plus en recevoir les mises à jour.</string> <string name="dialog_message_leave_forum">Souhaitez-vous vraiment quitter ce forum?\n\nLes contacts avec qui vous lavez partagé pourraient ne plus en recevoir les mises à jour.</string>
<string name="dialog_button_leave">Quitter</string> <string name="dialog_button_leave">Quitter</string>
<string name="forum_left_toast">À quitté le forum</string> <string name="forum_left_toast">À quitté le forum</string>
<!--Forum Sharing--> <!--Forum Sharing-->
@@ -390,7 +390,7 @@
<string name="blogs_feed_empty_state">Aucun billet à afficher</string> <string name="blogs_feed_empty_state">Aucun billet à afficher</string>
<string name="blogs_feed_empty_state_action">Les billets de vos contacts et les blogues auxquels vous vous abonnez apparaîtront ici.\n\nTouchez licône de crayon pour rédiger un billet</string> <string name="blogs_feed_empty_state_action">Les billets de vos contacts et les blogues auxquels vous vous abonnez apparaîtront ici.\n\nTouchez licône de crayon pour rédiger un billet</string>
<string name="blogs_remove_blog">Supprimer le blogue</string> <string name="blogs_remove_blog">Supprimer le blogue</string>
<string name="blogs_remove_blog_dialog_message">Voulez-vous vraiment supprimer ce blogue?\nLes billets seront supprimés de votre appareil mais pas des appareils dautrui.\n\nLes contacts avec qui vous avez partagé ce blogue pourraient ne plus en recevoir les mises à jour.</string> <string name="blogs_remove_blog_dialog_message">Souhaitez-vous vraiment supprimer ce blogue?\nLes billets seront supprimés de votre appareil mais pas des appareils dautrui.\n\nLes contacts avec qui vous avez partagé ce blogue pourraient ne plus en recevoir les mises à jour.</string>
<string name="blogs_remove_blog_ok">Supprimer</string> <string name="blogs_remove_blog_ok">Supprimer</string>
<string name="blogs_blog_removed">Le blogue a été supprimé</string> <string name="blogs_blog_removed">Le blogue a été supprimé</string>
<string name="blogs_reblog_comment_hint">Ajouter un commentaire (facultatif)</string> <string name="blogs_reblog_comment_hint">Ajouter un commentaire (facultatif)</string>
@@ -420,7 +420,7 @@
<string name="blogs_rss_feeds_manage_author">Auteur :</string> <string name="blogs_rss_feeds_manage_author">Auteur :</string>
<string name="blogs_rss_feeds_manage_updated">Dernière mise à jour :</string> <string name="blogs_rss_feeds_manage_updated">Dernière mise à jour :</string>
<string name="blogs_rss_remove_feed">Supprimer le fil</string> <string name="blogs_rss_remove_feed">Supprimer le fil</string>
<string name="blogs_rss_remove_feed_dialog_message">Voulez-vous vraiment supprimer ce fil?\nLes billets seront supprimés de votre appareil mais pas des appareils dautrui.\n\nLes contacts avec qui vous avez partagé ce fil pourraient ne plus en recevoir les mises à jour.</string> <string name="blogs_rss_remove_feed_dialog_message">Souhaitez-vous vraiment supprimer ce fil?\nLes billets seront supprimés de votre appareil mais pas des appareils dautrui.\n\nLes contacts avec qui vous avez partagé ce fil pourraient ne plus en recevoir les mises à jour.</string>
<string name="blogs_rss_remove_feed_ok">Supprimer</string> <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_delete_error">Impossible de supprimer le fil!</string>
<string name="blogs_rss_feeds_manage_empty_state">Aucun fil RSS à afficher\n\nTouchez licône + pour importer un fil</string> <string name="blogs_rss_feeds_manage_empty_state">Aucun fil RSS à afficher\n\nTouchez licône + pour importer un fil</string>
@@ -484,7 +484,7 @@
<string name="panic_app_setting_summary">Aucune appli na été définie</string> <string name="panic_app_setting_summary">Aucune appli na été définie</string>
<string name="panic_app_setting_none">Aucune</string> <string name="panic_app_setting_none">Aucune</string>
<string name="dialog_title_connect_panic_app">Confirmer lapplication durgence</string> <string name="dialog_title_connect_panic_app">Confirmer lapplication durgence</string>
<string name="dialog_message_connect_panic_app">Voulez-vous vraiment autoriser %1$s à déclencher les actions destructrices du bouton durgence?</string> <string name="dialog_message_connect_panic_app">Souhaitez-vous vraiment autoriser %1$s à déclencher les actions destructrices du bouton durgence?</string>
<string name="panic_setting_destructive_action">Actions destructrices</string> <string name="panic_setting_destructive_action">Actions destructrices</string>
<string name="panic_setting_signout_title">Déconnexion</string> <string name="panic_setting_signout_title">Déconnexion</string>
<string name="panic_setting_signout_summary">Se déconnecter de Briar si lon appuie sur un bouton durgence</string> <string name="panic_setting_signout_summary">Se déconnecter de Briar si lon appuie sur un bouton durgence</string>

View File

@@ -61,36 +61,12 @@
<string name="lock_button">Bloquear App</string> <string name="lock_button">Bloquear App</string>
<string name="settings_button">Axustes</string> <string name="settings_button">Axustes</string>
<string name="sign_out_button">Finalizar sesión</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: Tor-->
<string name="transport_tor">Internet</string> <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--> <!--Transports: Wi-Fi-->
<string name="transport_lan">Wi-Fi</string> <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--> <!--Transports: Bluetooth-->
<string name="transport_bt">Bluetooth</string> <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>
<!--Notifications--> <!--Notifications-->
<string name="reminder_notification_title">Desconectou de Briar</string> <string name="reminder_notification_title">Desconectou de Briar</string>
<string name="reminder_notification_text">Toque para voltar a conectar</string> <string name="reminder_notification_text">Toque para voltar a conectar</string>
@@ -560,7 +536,6 @@
<string name="lock_is_locked">Briar está bloqueada</string> <string name="lock_is_locked">Briar está bloqueada</string>
<string name="lock_tap_to_unlock">Toque para desbloquear</string> <string name="lock_tap_to_unlock">Toque para desbloquear</string>
<!--Connections Screen--> <!--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--> <!--Screenshots-->
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_alice">Alice</string> <string name="screenshot_alice">Alice</string>

View File

@@ -61,36 +61,12 @@
<string name="lock_button">App zárolása</string> <string name="lock_button">App zárolása</string>
<string name="settings_button">Beállítások</string> <string name="settings_button">Beállítások</string>
<string name="sign_out_button">Kijelentkezés</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: Tor-->
<string name="transport_tor">Internet</string> <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--> <!--Transports: Wi-Fi-->
<string name="transport_lan">Wi-Fi</string> <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--> <!--Transports: Bluetooth-->
<string name="transport_bt">Bluetooth</string> <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>
<!--Notifications--> <!--Notifications-->
<string name="reminder_notification_title">Kilépve a Briar-ból</string> <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> <string name="reminder_notification_text">Érintse meg az újra belépéshez.</string>
@@ -445,19 +421,10 @@ Kapcsolatai, akivel megosztotta ezt a blogot, lehet nem kapnak többé frissít
<string name="pref_theme_system">Rendszer alapértelmezett</string> <string name="pref_theme_system">Rendszer alapértelmezett</string>
<!--Settings Connections--> <!--Settings Connections-->
<string name="network_settings_title">Kapcsolatok</string> <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_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)"--> <!--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_network_setting_summary">Automatikus: %1$s ( %2$s)</string>
<string name="tor_mobile_data_title">Mobil adat használata</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> <string name="tor_only_when_charging_summary">Letiltja az internet kapcsolatot, amikor elemről fut az eszköz</string>
<!--Settings Security and Panic--> <!--Settings Security and Panic-->
<string name="security_settings_title">Biztonság</string> <string name="security_settings_title">Biztonság</string>
@@ -569,7 +536,6 @@ Vigyázat: Ez végleg törli az identitásait, kapcsolatait és üzeneteit</stri
<string name="lock_is_locked">A Briar zárolt</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> <string name="lock_tap_to_unlock">Érintse meg a zárolás feloldásához</string>
<!--Connections Screen--> <!--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--> <!--Screenshots-->
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_alice">Alice</string> <string name="screenshot_alice">Alice</string>

View File

@@ -79,18 +79,8 @@
<string name="transport_lan_long">Sama þráðlausa Wi-Fi netkerfið</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_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_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--> <!--Transports: Bluetooth-->
<string name="transport_bt">Bluetooth</string> <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>
<!--Notifications--> <!--Notifications-->
<string name="reminder_notification_title">Skráð út úr Briar</string> <string name="reminder_notification_title">Skráð út úr Briar</string>
<string name="reminder_notification_text">Ýttu til að skrá þig aftur inn.</string> <string name="reminder_notification_text">Ýttu til að skrá þig aftur inn.</string>
@@ -436,29 +426,19 @@
<string name="pref_theme_auto">Sjálfvirkt (eftir tíma dags)</string> <string name="pref_theme_auto">Sjálfvirkt (eftir tíma dags)</string>
<string name="pref_theme_system">Sjálfgefið í kerfinu</string> <string name="pref_theme_system">Sjálfgefið í kerfinu</string>
<!--Settings Connections--> <!--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_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)"--> <!--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_network_setting_summary">Sjálfvirkt: %1$s (eftir %2$s)</string>
<string name="tor_mobile_data_title">Nota farsímagagnasamband</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> <string name="tor_only_when_charging_summary">Gerir internettengingu óvirka þegar tækið keyrir á rafhlöðu</string>
<!--Settings Security and Panic--> <!--Settings Security and Panic-->
<string name="security_settings_title">Öryggi</string> <string name="security_settings_title">Öryggi</string>
<string name="pref_lock_title">Forritslæsing</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_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_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--> <!--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"--> <!--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> <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"--> <!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
@@ -560,7 +540,6 @@
<string name="lock_is_locked">Briar er læst</string> <string name="lock_is_locked">Briar er læst</string>
<string name="lock_tap_to_unlock">Ýttu til að aflæsa</string> <string name="lock_tap_to_unlock">Ýttu til að aflæsa</string>
<!--Connections Screen--> <!--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--> <!--Screenshots-->
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--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> <string name="screenshot_alice">Lísa</string>

View File

@@ -61,36 +61,12 @@
<string name="lock_button">App vergrendelen</string> <string name="lock_button">App vergrendelen</string>
<string name="settings_button">Instellingen</string> <string name="settings_button">Instellingen</string>
<string name="sign_out_button">Log uit</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: Tor-->
<string name="transport_tor">Internet</string> <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--> <!--Transports: Wi-Fi-->
<string name="transport_lan">Wifi</string> <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--> <!--Transports: Bluetooth-->
<string name="transport_bt">Bluetooth</string> <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>
<!--Notifications--> <!--Notifications-->
<string name="reminder_notification_title">Uitgelogd van Briar</string> <string name="reminder_notification_title">Uitgelogd van Briar</string>
<string name="reminder_notification_text">Tik om opnieuw in te loggen.</string> <string name="reminder_notification_text">Tik om opnieuw in te loggen.</string>
@@ -560,7 +536,6 @@
<string name="lock_is_locked">Briar is vergrendeld</string> <string name="lock_is_locked">Briar is vergrendeld</string>
<string name="lock_tap_to_unlock">Tik om te ontgrendelen</string> <string name="lock_tap_to_unlock">Tik om te ontgrendelen</string>
<!--Connections Screen--> <!--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--> <!--Screenshots-->
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_alice">Veerle</string> <string name="screenshot_alice">Veerle</string>

View File

@@ -61,7 +61,6 @@
<string name="lock_button">Bloquear Aplicativo</string> <string name="lock_button">Bloquear Aplicativo</string>
<string name="settings_button">Configurações</string> <string name="settings_button">Configurações</string>
<string name="sign_out_button">Sair</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: Tor-->
<string name="transport_tor">Internet</string> <string name="transport_tor">Internet</string>
<!--Transports: Wi-Fi--> <!--Transports: Wi-Fi-->

View File

@@ -65,36 +65,12 @@
<string name="lock_button">Заблокировать приложение</string> <string name="lock_button">Заблокировать приложение</string>
<string name="settings_button">Настройки</string> <string name="settings_button">Настройки</string>
<string name="sign_out_button">Выйти</string> <string name="sign_out_button">Выйти</string>
<string name="transports_onboarding_text">Нажмите здесь, чтобы проверить, как Briar подключается к вашим контактам.</string>
<!--Transports: Tor--> <!--Transports: Tor-->
<string name="transport_tor">Интернет</string> <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--> <!--Transports: Wi-Fi-->
<string name="transport_lan">Wi-Fi</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--> <!--Transports: Bluetooth-->
<string name="transport_bt">Bluetooth</string> <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--> <!--Notifications-->
<string name="reminder_notification_title">Вы не авторизованы в Briar</string> <string name="reminder_notification_title">Вы не авторизованы в Briar</string>
<string name="reminder_notification_text">Нажмите для входа</string> <string name="reminder_notification_text">Нажмите для входа</string>
@@ -223,7 +199,7 @@
<string name="add_contact_choose_nickname">Выберите ник</string> <string name="add_contact_choose_nickname">Выберите ник</string>
<string name="add_contact_choose_a_nickname">Введите ник</string> <string name="add_contact_choose_a_nickname">Введите ник</string>
<string name="nickname_intro">Дайте вашему контакту ник. Увидеть его сможете только вы.</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_clip_label">Ссылка Briar</string>
<string name="link_copied_toast">Ссылка скопирована</string> <string name="link_copied_toast">Ссылка скопирована</string>
<string name="adding_contact_error">При добавлении контакта произошла ошибка.</string> <string name="adding_contact_error">При добавлении контакта произошла ошибка.</string>
@@ -582,7 +558,6 @@
<string name="lock_is_locked">Briar заблокирован</string> <string name="lock_is_locked">Briar заблокирован</string>
<string name="lock_tap_to_unlock">Нажмите для разблокировки</string> <string name="lock_tap_to_unlock">Нажмите для разблокировки</string>
<!--Connections Screen--> <!--Connections Screen-->
<string name="transports_help_text">Briar может подключаться к контактам через интернет, Wi-Fi или Bluetooth.\n\nВсе интернет-соединения проходят через сеть Tor для обеспечения конфиденциальности.\n\nЕсли с контактом можно связаться несколькими способами, Briar использует их параллельно.</string>
<!--Screenshots--> <!--Screenshots-->
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_alice">Бузова</string> <string name="screenshot_alice">Бузова</string>

View File

@@ -61,36 +61,12 @@
<string name="lock_button">Lås appen</string> <string name="lock_button">Lås appen</string>
<string name="settings_button">Inställningar</string> <string name="settings_button">Inställningar</string>
<string name="sign_out_button">Logga ut</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: Tor-->
<string name="transport_tor">Internet</string> <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--> <!--Transports: Wi-Fi-->
<string name="transport_lan">Wi-Fi</string> <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--> <!--Transports: Bluetooth-->
<string name="transport_bt">Bluetooth</string> <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>
<!--Notifications--> <!--Notifications-->
<string name="reminder_notification_title">Utloggad från Briar</string> <string name="reminder_notification_title">Utloggad från Briar</string>
<string name="reminder_notification_text">Tryck för att logga in igen.</string> <string name="reminder_notification_text">Tryck för att logga in igen.</string>
@@ -436,20 +412,10 @@
<string name="pref_theme_auto">Automatisk (dagtid)</string> <string name="pref_theme_auto">Automatisk (dagtid)</string>
<string name="pref_theme_system">Systemets förval</string> <string name="pref_theme_system">Systemets förval</string>
<!--Settings Connections--> <!--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_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)"--> <!--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_network_setting_summary">Automatisk: %1$s (i %2$s)</string>
<string name="tor_mobile_data_title">Använd mobildata</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> <string name="tor_only_when_charging_summary">Avaktiverar anslutning över Internet när enheten går på batteri</string>
<!--Settings Security and Panic--> <!--Settings Security and Panic-->
<string name="security_settings_title">Säkerhet</string> <string name="security_settings_title">Säkerhet</string>
@@ -560,7 +526,6 @@
<string name="lock_is_locked">Briar är låst</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> <string name="lock_tap_to_unlock">Tryck för att låsa upp</string>
<!--Connections Screen--> <!--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--> <!--Screenshots-->
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_alice">Alice</string> <string name="screenshot_alice">Alice</string>

View File

@@ -61,36 +61,12 @@
<string name="lock_button">Uygulamayı Kilitle</string> <string name="lock_button">Uygulamayı Kilitle</string>
<string name="settings_button">Ayarlar</string> <string name="settings_button">Ayarlar</string>
<string name="sign_out_button">Oturumu Kapat</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: Tor-->
<string name="transport_tor">İnternet</string> <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--> <!--Transports: Wi-Fi-->
<string name="transport_lan">Wi-Fi</string> <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--> <!--Transports: Bluetooth-->
<string name="transport_bt">Bluetooth</string> <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>
<!--Notifications--> <!--Notifications-->
<string name="reminder_notification_title">Briar oturumu kapatıldı</string> <string name="reminder_notification_title">Briar oturumu kapatıldı</string>
<string name="reminder_notification_text">Tekrar oturum açmak için dokunun</string> <string name="reminder_notification_text">Tekrar oturum açmak için dokunun</string>
@@ -560,7 +536,6 @@
<string name="lock_is_locked">Briar kilitli</string> <string name="lock_is_locked">Briar kilitli</string>
<string name="lock_tap_to_unlock">Kilidi açmak için dokunun</string> <string name="lock_tap_to_unlock">Kilidi açmak için dokunun</string>
<!--Connections Screen--> <!--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--> <!--Screenshots-->
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_alice">Alice</string> <string name="screenshot_alice">Alice</string>

View File

@@ -60,36 +60,12 @@
<string name="lock_button">锁定应用</string> <string name="lock_button">锁定应用</string>
<string name="settings_button">设置</string> <string name="settings_button">设置</string>
<string name="sign_out_button">登出</string> <string name="sign_out_button">登出</string>
<string name="transports_onboarding_text">点击这里来控制Briar如何连接到您的联系人</string>
<!--Transports: Tor--> <!--Transports: Tor-->
<string name="transport_tor">互联网</string> <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--> <!--Transports: Wi-Fi-->
<string name="transport_lan">无线局域网</string> <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--> <!--Transports: Bluetooth-->
<string name="transport_bt">蓝牙</string> <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>
<!--Notifications--> <!--Notifications-->
<string name="reminder_notification_title">已登出 Briar</string> <string name="reminder_notification_title">已登出 Briar</string>
<string name="reminder_notification_text">轻按以重新登录。</string> <string name="reminder_notification_text">轻按以重新登录。</string>
@@ -132,7 +108,6 @@
<string name="help">帮助</string> <string name="help">帮助</string>
<string name="sorry">抱歉</string> <string name="sorry">抱歉</string>
<string name="error_start_activity">在您的系统上不可用</string> <string name="error_start_activity">在您的系统上不可用</string>
<string name="status_heading">状态:</string>
<!--Contacts and Private Conversations--> <!--Contacts and Private Conversations-->
<string name="no_contacts">尚无联系人可供显示</string> <string name="no_contacts">尚无联系人可供显示</string>
<string name="no_contacts_action">轻按 + 号即可添加联系人</string> <string name="no_contacts_action">轻按 + 号即可添加联系人</string>
@@ -439,7 +414,6 @@
<!--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)"--> <!--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_network_setting_summary">自动选择:%1$s在 %2$s</string>
<string name="tor_mobile_data_title">使用移动数据</string> <string name="tor_mobile_data_title">使用移动数据</string>
<string name="tor_only_when_charging_title">仅在充电时联网</string>
<string name="tor_only_when_charging_summary">当设备使用电池电量时关闭网络连接</string> <string name="tor_only_when_charging_summary">当设备使用电池电量时关闭网络连接</string>
<!--Settings Security and Panic--> <!--Settings Security and Panic-->
<string name="security_settings_title">安全</string> <string name="security_settings_title">安全</string>
@@ -550,7 +524,6 @@
<string name="lock_is_locked">Briar 已锁定</string> <string name="lock_is_locked">Briar 已锁定</string>
<string name="lock_tap_to_unlock">轻按以解锁</string> <string name="lock_tap_to_unlock">轻按以解锁</string>
<!--Connections Screen--> <!--Connections Screen-->
<string name="transports_help_text">Briar可以通过互联网、Wi-Fi或蓝牙连接到您的联系人。\n\n为了保护隐私所有的互联网连接都通过Tor网络。\n\n如果一个联系人可以通过多种方法联系到Briar会并行地使用它们。</string>
<!--Screenshots--> <!--Screenshots-->
<!--This is a name to be used in screenshots. Feel free to change it to a local name.--> <!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
<string name="screenshot_alice">韩梅梅</string> <string name="screenshot_alice">韩梅梅</string>

View File

@@ -69,8 +69,7 @@ Returns a JSON array of contacts:
"handshakePublicKey": "XnYRd7a7E4CTqgAvh4hCxh/YZ0EPscxknB9ZcEOpSzY=", "handshakePublicKey": "XnYRd7a7E4CTqgAvh4hCxh/YZ0EPscxknB9ZcEOpSzY=",
"verified": true, "verified": true,
"lastChatActivity": 1557838312175, "lastChatActivity": 1557838312175,
"connected": false, "connected": false
"unreadCount": 7
} }
``` ```
@@ -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 introductions. In these cases contacts omit the `pendingContact` state and
directly become `contact`s. 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 ### Removing a contact
`DELETE /v1/contacts/{contactId}` `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 ### Listing blog posts
`GET /v1/blogs/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" "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"
}
```

View File

@@ -81,20 +81,11 @@ constructor(
path("/:contactId") { path("/:contactId") {
delete { ctx -> contactController.delete(ctx) } delete { ctx -> contactController.delete(ctx) }
} }
path("/:contactId/alias") {
put { ctx -> contactController.setContactAlias(ctx) }
}
} }
path("/messages/:contactId") { path("/messages/:contactId") {
get { ctx -> messagingController.list(ctx) } get { ctx -> messagingController.list(ctx) }
post { ctx -> messagingController.write(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") { path("/forums") {
get { ctx -> forumController.list(ctx) } get { ctx -> forumController.list(ctx) }
post { ctx -> forumController.create(ctx) } post { ctx -> forumController.create(ctx) }

View File

@@ -9,7 +9,6 @@ interface ContactController {
fun addPendingContact(ctx: Context): Context fun addPendingContact(ctx: Context): Context
fun listPendingContacts(ctx: Context): Context fun listPendingContacts(ctx: Context): Context
fun removePendingContact(ctx: Context): Context fun removePendingContact(ctx: Context): Context
fun setContactAlias(ctx: Context): Context
fun delete(ctx: Context): Context fun delete(ctx: Context): Context
} }

View File

@@ -77,8 +77,7 @@ constructor(
val contacts = contactManager.contacts.map { contact -> val contacts = contactManager.contacts.map { contact ->
val latestMsgTime = conversationManager.getGroupCount(contact.id).latestMsgTime val latestMsgTime = conversationManager.getGroupCount(contact.id).latestMsgTime
val connected = connectionRegistry.isConnected(contact.id) val connected = connectionRegistry.isConnected(contact.id)
val unreadCount = conversationManager.getGroupCount(contact.id).unreadCount contact.output(latestMsgTime, connected)
contact.output(latestMsgTime, connected, unreadCount)
} }
return ctx.json(contacts) return ctx.json(contacts)
} }
@@ -92,7 +91,9 @@ constructor(
val link = ctx.getFromJson(objectMapper, "link") val link = ctx.getFromJson(objectMapper, "link")
val alias = ctx.getFromJson(objectMapper, "alias") val alias = ctx.getFromJson(objectMapper, "alias")
if (!LINK_REGEX.matcher(link).find()) throw BadRequestResponse("Invalid Link") 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) val pendingContact = contactManager.addPendingContact(link, alias)
return ctx.json(pendingContact.output()) return ctx.json(pendingContact.output())
} }
@@ -123,18 +124,6 @@ constructor(
return ctx 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 { override fun delete(ctx: Context): Context {
val contactId = ctx.getContactIdFromPathParam() val contactId = ctx.getContactIdFromPathParam()
try { try {
@@ -145,10 +134,4 @@ constructor(
return ctx return ctx
} }
private fun checkAliasLength(alias: String) {
val aliasUtf8 = toUtf8(alias)
if (aliasUtf8.isEmpty() || aliasUtf8.size > MAX_AUTHOR_NAME_LENGTH)
throw BadRequestResponse("Invalid Alias")
}
} }

View File

@@ -7,13 +7,12 @@ import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent
import org.briarproject.bramble.identity.output import org.briarproject.bramble.identity.output
import org.briarproject.briar.headless.json.JsonDict 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, "contactId" to id.int,
"author" to author.output(), "author" to author.output(),
"verified" to isVerified, "verified" to isVerified,
"lastChatActivity" to latestMsgTime, "lastChatActivity" to latestMsgTime,
"connected" to connected, "connected" to connected
"unreadCount" to unreadCount
).apply { ).apply {
alias?.let { put("alias", it) } alias?.let { put("alias", it) }
handshakePublicKey?.let { put("handshakePublicKey", it.encoded) } handshakePublicKey?.let { put("handshakePublicKey", it.encoded) }

View File

@@ -8,8 +8,4 @@ interface MessagingController {
fun write(ctx: Context): Context fun write(ctx: Context): Context
fun markMessageRead(ctx: Context): Context
fun deleteAllMessages(ctx: Context): Context
} }

View File

@@ -11,9 +11,6 @@ import org.briarproject.bramble.api.db.DatabaseExecutor
import org.briarproject.bramble.api.db.NoSuchContactException import org.briarproject.bramble.api.db.NoSuchContactException
import org.briarproject.bramble.api.event.Event import org.briarproject.bramble.api.event.Event
import org.briarproject.bramble.api.event.EventListener import org.briarproject.bramble.api.event.EventListener
import org.briarproject.bramble.api.sync.event.MessagesAckedEvent
import org.briarproject.bramble.api.sync.event.MessagesSentEvent
import org.briarproject.bramble.api.sync.MessageId
import org.briarproject.bramble.api.system.Clock import org.briarproject.bramble.api.system.Clock
import org.briarproject.bramble.util.StringUtils.utf8IsTooLong import org.briarproject.bramble.util.StringUtils.utf8IsTooLong
import org.briarproject.briar.api.blog.BlogInvitationRequest import org.briarproject.briar.api.blog.BlogInvitationRequest
@@ -36,16 +33,12 @@ import org.briarproject.briar.headless.event.output
import org.briarproject.briar.headless.getContactIdFromPathParam import org.briarproject.briar.headless.getContactIdFromPathParam
import org.briarproject.briar.headless.getFromJson import org.briarproject.briar.headless.getFromJson
import org.briarproject.briar.headless.json.JsonDict import org.briarproject.briar.headless.json.JsonDict
import org.spongycastle.util.encoders.Base64
import org.spongycastle.util.encoders.DecoderException
import java.util.concurrent.Executor import java.util.concurrent.Executor
import javax.annotation.concurrent.Immutable import javax.annotation.concurrent.Immutable
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
internal const val EVENT_CONVERSATION_MESSAGE = "ConversationMessageReceivedEvent" internal const val EVENT_CONVERSATION_MESSAGE = "ConversationMessageReceivedEvent"
internal const val EVENT_MESSAGES_ACKED = "MessagesAckedEvent"
internal const val EVENT_MESSAGES_SENT = "MessagesSentEvent"
@Immutable @Immutable
@Singleton @Singleton
@@ -86,36 +79,6 @@ constructor(
return ctx.json(m.output(contact.id, text)) return ctx.json(m.output(contact.id, text))
} }
override fun markMessageRead(ctx: Context): Context {
val contact = getContact(ctx)
val groupId = messagingManager.getContactGroup(contact).id
val messageIdString = ctx.getFromJson(objectMapper, "messageId")
val messageId = deserializeMessageId(messageIdString)
messagingManager.setReadFlag(groupId, messageId, true)
return ctx.json(messageIdString)
}
private fun deserializeMessageId(idString: String): MessageId {
val idBytes = try {
Base64.decode(idString)
} catch (e: DecoderException) {
throw NotFoundResponse()
}
if (idBytes.size != MessageId.LENGTH) throw NotFoundResponse()
return MessageId(idBytes)
}
override fun deleteAllMessages(ctx: Context): Context {
val contactId = ctx.getContactIdFromPathParam()
try {
val result = conversationManager.deleteAllMessages(contactId)
return ctx.json(result.output())
} catch (e: NoSuchContactException) {
throw NotFoundResponse()
}
}
override fun eventOccurred(e: Event) { override fun eventOccurred(e: Event) {
when (e) { when (e) {
is ConversationMessageReceivedEvent<*> -> { is ConversationMessageReceivedEvent<*> -> {
@@ -127,12 +90,6 @@ constructor(
webSocketController.sendEvent(EVENT_CONVERSATION_MESSAGE, e.output()) webSocketController.sendEvent(EVENT_CONVERSATION_MESSAGE, e.output())
} }
} }
is MessagesSentEvent -> {
webSocketController.sendEvent(EVENT_MESSAGES_SENT, e.output())
}
is MessagesAckedEvent -> {
webSocketController.sendEvent(EVENT_MESSAGES_ACKED, e.output())
}
} }
} }

View File

@@ -1,11 +1,7 @@
package org.briarproject.briar.headless.messaging package org.briarproject.briar.headless.messaging
import org.briarproject.bramble.api.contact.ContactId import org.briarproject.bramble.api.contact.ContactId
import org.briarproject.bramble.api.sync.MessageId
import org.briarproject.bramble.api.sync.event.MessagesAckedEvent
import org.briarproject.bramble.api.sync.event.MessagesSentEvent
import org.briarproject.briar.api.conversation.ConversationMessageHeader import org.briarproject.briar.api.conversation.ConversationMessageHeader
import org.briarproject.briar.api.conversation.DeletionResult
import org.briarproject.briar.api.messaging.PrivateMessage import org.briarproject.briar.api.messaging.PrivateMessage
import org.briarproject.briar.api.messaging.PrivateMessageHeader import org.briarproject.briar.api.messaging.PrivateMessageHeader
import org.briarproject.briar.headless.json.JsonDict import org.briarproject.briar.headless.json.JsonDict
@@ -47,24 +43,3 @@ internal fun PrivateMessage.output(contactId: ContactId, text: String) = JsonDic
"groupId" to message.groupId.bytes, "groupId" to message.groupId.bytes,
"text" to text "text" to text
) )
internal fun DeletionResult.output() = JsonDict(
"allDeleted" to allDeleted(),
"hasIntroductionSessionInProgress" to hasIntroductionSessionInProgress(),
"hasInvitationSessionInProgress" to hasInvitationSessionInProgress(),
"hasNotAllIntroductionSelected" to hasNotAllIntroductionSelected(),
"hasNotAllInvitationSelected" to hasNotAllInvitationSelected(),
"hasNotFullyDownloaded" to hasNotFullyDownloaded()
)
internal fun MessagesAckedEvent.output() = JsonDict(
"contactId" to contactId.int,
"messageIds" to messageIds.toJson()
)
internal fun MessagesSentEvent.output() = JsonDict(
"contactId" to contactId.int,
"messageIds" to messageIds.toJson()
)
internal fun Collection<MessageId>.toJson() = map { it.bytes }

View File

@@ -46,7 +46,6 @@ abstract class ControllerTest {
protected val message: Message = getMessage(group.id) protected val message: Message = getMessage(group.id)
protected val text: String = getRandomString(5) protected val text: String = getRandomString(5)
protected val timestamp = 42L protected val timestamp = 42L
protected val unreadCount = 42
protected fun assertJsonEquals(json: String, obj: Any) { protected fun assertJsonEquals(json: String, obj: Any) {
assertEquals(json, outputCtx.json(obj).resultString(), STRICT) assertEquals(json, outputCtx.json(obj).resultString(), STRICT)

View File

@@ -6,7 +6,6 @@ import io.javalin.plugin.json.JavalinJson.toJson
import io.mockk.Runs import io.mockk.Runs
import io.mockk.every import io.mockk.every
import io.mockk.just import io.mockk.just
import io.mockk.mockkStatic
import io.mockk.runs import io.mockk.runs
import org.briarproject.bramble.api.Pair import org.briarproject.bramble.api.Pair
import org.briarproject.bramble.api.contact.Contact import org.briarproject.bramble.api.contact.Contact
@@ -28,7 +27,6 @@ import org.briarproject.bramble.test.TestUtils.getPendingContact
import org.briarproject.bramble.test.TestUtils.getRandomBytes import org.briarproject.bramble.test.TestUtils.getRandomBytes
import org.briarproject.bramble.util.StringUtils.getRandomString import org.briarproject.bramble.util.StringUtils.getRandomString
import org.briarproject.briar.headless.ControllerTest import org.briarproject.briar.headless.ControllerTest
import org.briarproject.briar.headless.getFromJson
import org.briarproject.briar.headless.json.JsonDict import org.briarproject.briar.headless.json.JsonDict
import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Assertions.assertThrows
@@ -60,8 +58,7 @@ internal class ContactControllerTest : ControllerTest() {
every { contactManager.contacts } returns listOf(contact) every { contactManager.contacts } returns listOf(contact)
every { conversationManager.getGroupCount(contact.id).latestMsgTime } returns timestamp every { conversationManager.getGroupCount(contact.id).latestMsgTime } returns timestamp
every { connectionRegistry.isConnected(contact.id) } returns connected every { connectionRegistry.isConnected(contact.id) } returns connected
every { conversationManager.getGroupCount(contact.id).unreadCount } returns unreadCount every { ctx.json(listOf(contact.output(timestamp, connected))) } returns ctx
every { ctx.json(listOf(contact.output(timestamp, connected, unreadCount))) } returns ctx
controller.list(ctx) controller.list(ctx)
} }
@@ -196,66 +193,6 @@ internal class ContactControllerTest : ControllerTest() {
} }
} }
@Test
fun testSetContactAlias() {
mockkStatic("org.briarproject.briar.headless.RouterKt")
every { ctx.pathParam("contactId") } returns "1"
every { ctx.getFromJson(objectMapper, "alias") } returns "foo"
every { contactManager.setContactAlias(ContactId(1), "foo") } just Runs
controller.setContactAlias(ctx)
}
@Test
fun testSetContactAliasInvalidId() {
mockkStatic("org.briarproject.briar.headless.RouterKt")
every { ctx.pathParam("contactId") } returns "foo"
every { ctx.getFromJson(objectMapper, "alias") } returns "bar"
assertThrows(NotFoundResponse::class.java) {
controller.setContactAlias(ctx)
}
}
@Test
fun testSetContactAliasNonexistentId() {
mockkStatic("org.briarproject.briar.headless.RouterKt")
every { ctx.pathParam("contactId") } returns "1"
every { ctx.getFromJson(objectMapper, "alias") } returns "foo"
every { contactManager.setContactAlias(ContactId(1), "foo") } throws NotFoundResponse()
assertThrows(NotFoundResponse::class.java) {
controller.setContactAlias(ctx)
}
}
@Test
fun testSetContactAliasInvalid() {
mockkStatic("org.briarproject.briar.headless.RouterKt")
every { ctx.pathParam("contactId") } returns "1"
every { ctx.getFromJson(objectMapper, "alias") } returns getRandomString(MAX_AUTHOR_NAME_LENGTH + 1)
assertThrows(BadRequestResponse::class.java) {
controller.setContactAlias(ctx)
}
}
@Test
fun testSetContactAliasEmpty() {
mockkStatic("org.briarproject.briar.headless.RouterKt")
every { ctx.pathParam("contactId") } returns "1"
every { ctx.getFromJson(objectMapper, "alias") } returns ""
assertThrows(BadRequestResponse::class.java) {
controller.setContactAlias(ctx)
}
}
@Test
fun testSetContactAliasMissing() {
mockkStatic("org.briarproject.briar.headless.RouterKt")
every { ctx.pathParam("contactId") } returns "1"
every { ctx.body() } returns ""
assertThrows(BadRequestResponse::class.java) {
controller.setContactAlias(ctx)
}
}
@Test @Test
fun testDelete() { fun testDelete() {
every { ctx.pathParam("contactId") } returns "1" every { ctx.pathParam("contactId") } returns "1"
@@ -376,11 +313,10 @@ internal class ContactControllerTest : ControllerTest() {
"handshakePublicKey": ${toJson(contact.handshakePublicKey!!.encoded)}, "handshakePublicKey": ${toJson(contact.handshakePublicKey!!.encoded)},
"verified": ${contact.isVerified}, "verified": ${contact.isVerified},
"lastChatActivity": $timestamp, "lastChatActivity": $timestamp,
"connected": $connected, "connected": $connected
"unreadCount": $unreadCount
} }
""" """
assertJsonEquals(json, contact.output(timestamp, connected, unreadCount)) assertJsonEquals(json, contact.output(timestamp, connected))
} }
@Test @Test

View File

@@ -10,14 +10,11 @@ import org.briarproject.bramble.api.db.NoSuchContactException
import org.briarproject.bramble.api.identity.AuthorInfo import org.briarproject.bramble.api.identity.AuthorInfo
import org.briarproject.bramble.api.identity.AuthorInfo.Status.UNVERIFIED import org.briarproject.bramble.api.identity.AuthorInfo.Status.UNVERIFIED
import org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED import org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED
import org.briarproject.bramble.api.sync.MessageId
import org.briarproject.bramble.api.sync.event.MessagesAckedEvent
import org.briarproject.bramble.api.sync.event.MessagesSentEvent
import org.briarproject.bramble.test.ImmediateExecutor import org.briarproject.bramble.test.ImmediateExecutor
import org.briarproject.bramble.test.TestUtils.getRandomId import org.briarproject.bramble.test.TestUtils.getRandomId
import org.briarproject.bramble.util.StringUtils.getRandomString import org.briarproject.bramble.util.StringUtils.getRandomString
import org.briarproject.briar.api.client.SessionId import org.briarproject.briar.api.client.SessionId
import org.briarproject.briar.api.conversation.DeletionResult import org.briarproject.briar.api.conversation.ConversationManager
import org.briarproject.briar.api.introduction.IntroductionRequest import org.briarproject.briar.api.introduction.IntroductionRequest
import org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH import org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH
import org.briarproject.briar.api.messaging.MessagingManager import org.briarproject.briar.api.messaging.MessagingManager
@@ -27,13 +24,10 @@ import org.briarproject.briar.api.messaging.PrivateMessageHeader
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent
import org.briarproject.briar.headless.ControllerTest import org.briarproject.briar.headless.ControllerTest
import org.briarproject.briar.headless.event.output import org.briarproject.briar.headless.event.output
import org.briarproject.briar.headless.getFromJson
import org.briarproject.briar.headless.json.JsonDict import org.briarproject.briar.headless.json.JsonDict
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.spongycastle.util.encoders.Base64
import kotlin.random.Random
internal class MessagingControllerImplTest : ControllerTest() { internal class MessagingControllerImplTest : ControllerTest() {
@@ -106,40 +100,6 @@ internal class MessagingControllerImplTest : ControllerTest() {
testInvalidContactId { controller.list(ctx) } testInvalidContactId { controller.list(ctx) }
} }
@Test
fun testMessagesAckedEvent() {
val messageId1 = MessageId(getRandomId())
val messageId2 = MessageId(getRandomId())
val messageIds = listOf(messageId1, messageId2)
val event = MessagesAckedEvent(contact.id, messageIds)
every {
webSocketController.sendEvent(
EVENT_MESSAGES_ACKED,
event.output()
)
} just runs
controller.eventOccurred(event)
}
@Test
fun testMessagesSentEvent() {
val messageId1 = MessageId(getRandomId())
val messageId2 = MessageId(getRandomId())
val messageIds = listOf(messageId1, messageId2)
val event = MessagesSentEvent(contact.id, messageIds)
every {
webSocketController.sendEvent(
EVENT_MESSAGES_SENT,
event.output()
)
} just runs
controller.eventOccurred(event)
}
@Test @Test
fun listNonexistentContactId() { fun listNonexistentContactId() {
testNonexistentContactId { controller.list(ctx) } testNonexistentContactId { controller.list(ctx) }
@@ -202,32 +162,6 @@ internal class MessagingControllerImplTest : ControllerTest() {
assertThrows(BadRequestResponse::class.java) { controller.write(ctx) } assertThrows(BadRequestResponse::class.java) { controller.write(ctx) }
} }
@Test
fun markMessageRead() {
mockkStatic("org.briarproject.briar.headless.RouterKt")
mockkStatic("org.spongycastle.util.encoders.Base64")
expectGetContact()
val messageIdString = message.id.bytes.toString()
every { messagingManager.getContactGroup(contact).id } returns group.id
every { ctx.getFromJson(objectMapper, "messageId") } returns messageIdString
every { Base64.decode(messageIdString) } returns message.id.bytes
every { messagingManager.setReadFlag(group.id, message.id, true) } just Runs
every { ctx.json(messageIdString) } returns ctx
controller.markMessageRead(ctx)
}
@Test
fun markMessageReadInvalidContactId() {
testInvalidContactId { controller.markMessageRead(ctx) }
}
@Test
fun markMessageReadNonexistentId() {
testNonexistentContactId { controller.markMessageRead(ctx) }
}
@Test @Test
fun privateMessageEvent() { fun privateMessageEvent() {
val event = PrivateMessageReceivedEvent(header, contact.id) val event = PrivateMessageReceivedEvent(header, contact.id)
@@ -243,43 +177,6 @@ internal class MessagingControllerImplTest : ControllerTest() {
controller.eventOccurred(event) controller.eventOccurred(event)
} }
@Test
fun testOutputMessagesAckedEvent() {
val messageId1 = MessageId(getRandomId())
val messageId2 = MessageId(getRandomId())
val messageIds = listOf(messageId1, messageId2)
val event = MessagesAckedEvent(contact.id, messageIds)
val json = """
{
"contactId": ${contact.id.int},
"messageIds": [
${toJson(messageId1.bytes)},
${toJson(messageId2.bytes)}
]
}
"""
assertJsonEquals(json, event.output())
}
@Test
fun testOutputMessagesSentEvent() {
val messageId1 = MessageId(getRandomId())
val messageId2 = MessageId(getRandomId())
val messageIds = listOf(messageId1, messageId2)
val event = MessagesSentEvent(contact.id, messageIds)
val json = """
{
"contactId": ${contact.id.int},
"messageIds": [
${toJson(messageId1.bytes)},
${toJson(messageId2.bytes)}
]
}
"""
assertJsonEquals(json, event.output())
}
@Test @Test
fun testOutputPrivateMessageHeader() { fun testOutputPrivateMessageHeader() {
val json = """ val json = """
@@ -345,53 +242,6 @@ internal class MessagingControllerImplTest : ControllerTest() {
assertJsonEquals(json, request.output(contact.id)) assertJsonEquals(json, request.output(contact.id))
} }
@Test
fun testDeleteAllMessages() {
val result = DeletionResult()
every { ctx.pathParam("contactId") } returns "1"
every { conversationManager.deleteAllMessages(ContactId(1)) } returns result
every { ctx.json(result.output()) } returns ctx
controller.deleteAllMessages(ctx)
}
@Test
fun testDeleteAllMessagesInvalidContactId() {
every { ctx.pathParam("contactId") } returns "foo"
assertThrows(NotFoundResponse::class.java) {
controller.deleteAllMessages(ctx)
}
}
@Test
fun testDeleteAllMessagesNonexistentContactId() {
every { ctx.pathParam("contactId") } returns "1"
every { conversationManager.deleteAllMessages(ContactId(1)) } throws NoSuchContactException()
assertThrows(NotFoundResponse::class.java) {
controller.deleteAllMessages(ctx)
}
}
@Test
fun testOutputDeletionResult() {
val result = DeletionResult()
if (Random.nextBoolean()) result.addInvitationNotAllSelected()
if (Random.nextBoolean()) result.addInvitationSessionInProgress()
if (Random.nextBoolean()) result.addIntroductionNotAllSelected()
if (Random.nextBoolean()) result.addIntroductionSessionInProgress()
if (Random.nextBoolean()) result.addNotFullyDownloaded()
val json = """
{
"allDeleted": ${result.allDeleted()},
"hasIntroductionSessionInProgress": ${result.hasIntroductionSessionInProgress()},
"hasInvitationSessionInProgress": ${result.hasInvitationSessionInProgress()},
"hasNotAllIntroductionSelected": ${result.hasNotAllIntroductionSelected()},
"hasNotAllInvitationSelected": ${result.hasNotAllInvitationSelected()},
"hasNotFullyDownloaded": ${result.hasNotFullyDownloaded()}
}
"""
assertJsonEquals(json, result.output())
}
private fun expectGetContact() { private fun expectGetContact() {
every { ctx.pathParam("contactId") } returns contact.id.int.toString() every { ctx.pathParam("contactId") } returns contact.id.int.toString()
every { contactManager.getContact(contact.id) } returns contact every { contactManager.getContact(contact.id) } returns contact

View File

@@ -33,12 +33,3 @@ buildscript {
classpath files('libs/gradle-witness.jar') classpath files('libs/gradle-witness.jar')
} }
} }
project.ext {
buildToolsVersion = '30.0.2'
compileSdkVersion = 30
minSdkVersion = 16
targetSdkVersion = 29
versionCode = 10211
versionName = '1.2.11'
}