Merge tag '2.6.3' into develop
10
CHANGELOG.md
|
@ -1,5 +1,15 @@
|
|||
# Changelog
|
||||
|
||||
### Version 2.6.3
|
||||
|
||||
* Support for ?register and ?register;preauth XMPP uri parameters
|
||||
|
||||
### Version 2.6.2
|
||||
* let users set their own nick name
|
||||
* resume download of OMEMO encrypted files
|
||||
* Channels now use '#' as symbol in avatar
|
||||
* Quicksy uses 'always' as OMEMO encryption default (hides lock icon)
|
||||
|
||||
### Version 2.6.1
|
||||
* fixes for Jingle IBB file transfer
|
||||
* fixes for repeated corrections filling up the database
|
||||
|
|
43
build.gradle
|
@ -6,7 +6,7 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0'
|
||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ configurations {
|
|||
playstoreImplementation
|
||||
compatImplementation
|
||||
conversationsFreeCompatImplementation
|
||||
conversationsPlaystoreCompatImplementation
|
||||
conversationsPlaystoreSystemImplementation
|
||||
quicksyFreeCompatImplementation
|
||||
quicksyImplementation
|
||||
}
|
||||
|
@ -36,8 +38,10 @@ dependencies {
|
|||
exclude group: 'com.google.firebase', module: 'firebase-analytics'
|
||||
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
|
||||
}
|
||||
conversationsPlaystoreCompatImplementation("com.android.installreferrer:installreferrer:1.1")
|
||||
conversationsPlaystoreSystemImplementation("com.android.installreferrer:installreferrer:1.1")
|
||||
implementation 'org.sufficientlysecure:openpgp-api:10.0'
|
||||
implementation ('com.theartofdev.edmodo:android-image-cropper:2.7.+') {
|
||||
implementation('com.theartofdev.edmodo:android-image-cropper:2.7.+') {
|
||||
exclude group: 'com.android.support', module: 'appcompat-v7'
|
||||
exclude group: 'com.android.support', module: 'exifinterface'
|
||||
}
|
||||
|
@ -61,16 +65,18 @@ dependencies {
|
|||
implementation "com.wefika:flowlayout:0.4.1"
|
||||
implementation 'net.ypresto.androidtranscoder:android-transcoder:0.3.0'
|
||||
implementation project(':libs:xmpp-addr')
|
||||
implementation 'org.osmdroid:osmdroid-android:6.1.0'
|
||||
implementation 'org.osmdroid:osmdroid-android:6.1.5'
|
||||
implementation 'org.hsluv:hsluv:0.2'
|
||||
implementation 'org.conscrypt:conscrypt-android:2.2.1'
|
||||
implementation 'me.drakeet.support:toastcompat:1.1.0'
|
||||
implementation "com.leinardi.android:speed-dial:2.0.1"
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.6.1'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.12.6'
|
||||
//retrofit needs to stick with 2.6.x (https://github.com/square/retrofit/blob/master/CHANGELOG.md)
|
||||
implementation "com.squareup.retrofit2:retrofit:2.6.4"
|
||||
implementation "com.squareup.retrofit2:converter-gson:2.6.4"
|
||||
//okhttp needs to stick with 3.12.x
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.12.7'
|
||||
implementation 'com.google.guava:guava:27.1-android'
|
||||
quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.10.16'
|
||||
quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.11.1'
|
||||
}
|
||||
|
||||
ext {
|
||||
|
@ -84,8 +90,8 @@ android {
|
|||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 25
|
||||
versionCode 351
|
||||
versionName "2.6.1"
|
||||
versionCode 360
|
||||
versionName "2.6.3"
|
||||
archivesBaseName += "-$versionName"
|
||||
applicationId "eu.sum7.conversations"
|
||||
resValue "string", "applicationId", applicationId
|
||||
|
@ -141,12 +147,12 @@ android {
|
|||
sourceSets {
|
||||
quicksyFreeCompat {
|
||||
java {
|
||||
srcDirs 'src/freeCompat/java'
|
||||
srcDir 'src/freeCompat/java'
|
||||
}
|
||||
}
|
||||
quicksyPlaystoreCompat {
|
||||
java {
|
||||
srcDirs 'src/playstoreCompat/java'
|
||||
srcDir 'src/playstoreCompat/java'
|
||||
}
|
||||
res {
|
||||
srcDir 'src/playstoreCompat/res'
|
||||
|
@ -160,12 +166,19 @@ android {
|
|||
}
|
||||
conversationsFreeCompat {
|
||||
java {
|
||||
srcDirs 'src/freeCompat/java'
|
||||
srcDir 'src/freeCompat/java'
|
||||
srcDir 'src/conversationsFree/java'
|
||||
}
|
||||
}
|
||||
conversationsFreeSystem {
|
||||
java {
|
||||
srcDir 'src/conversationsFree/java'
|
||||
}
|
||||
}
|
||||
conversationsPlaystoreCompat {
|
||||
java {
|
||||
srcDirs 'src/playstoreCompat/java'
|
||||
srcDir 'src/playstoreCompat/java'
|
||||
srcDir 'src/conversationsPlaystore/java'
|
||||
}
|
||||
res {
|
||||
srcDir 'src/playstoreCompat/res'
|
||||
|
@ -173,6 +186,9 @@ android {
|
|||
}
|
||||
}
|
||||
conversationsPlaystoreSystem {
|
||||
java {
|
||||
srcDir 'src/conversationsPlaystore/java'
|
||||
}
|
||||
res {
|
||||
srcDir 'src/conversationsPlaystore/res'
|
||||
}
|
||||
|
@ -193,7 +209,6 @@ android {
|
|||
}
|
||||
|
||||
|
||||
|
||||
if (new File("signing.properties").exists()) {
|
||||
Properties props = new Properties()
|
||||
props.load(new FileInputStream(file("signing.properties")))
|
||||
|
|
|
@ -11,32 +11,33 @@
|
|||
<activity
|
||||
android:name=".ui.WelcomeActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"/>
|
||||
android:launchMode="singleTask" />
|
||||
<activity
|
||||
android:name=".ui.PickServerActivity"
|
||||
android:label="@string/create_new_account"
|
||||
android:launchMode="singleTask"/>
|
||||
android:launchMode="singleTask" />
|
||||
<activity
|
||||
android:name=".ui.MagicCreateActivity"
|
||||
android:label="@string/create_new_account"
|
||||
android:launchMode="singleTask"/>
|
||||
android:launchMode="singleTask" />
|
||||
<activity
|
||||
android:name=".ui.ImportBackupActivity"
|
||||
android:label="@string/restore_backup"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="application/vnd.conversations.backup" />
|
||||
<data android:scheme="content" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="application/vnd.conversations.backup" />
|
||||
<data android:scheme="file" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -2,115 +2,163 @@ package eu.siacs.conversations.ui;
|
|||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.databinding.DataBindingUtil;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.databinding.MagicCreateBinding;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.utils.CryptoHelper;
|
||||
import eu.siacs.conversations.utils.InstallReferrerUtils;
|
||||
import rocks.xmpp.addr.Jid;
|
||||
|
||||
public class MagicCreateActivity extends XmppActivity implements TextWatcher {
|
||||
|
||||
private TextView mFullJidDisplay;
|
||||
private EditText mUsername;
|
||||
public static final String EXTRA_DOMAIN = "domain";
|
||||
public static final String EXTRA_PRE_AUTH = "pre_auth";
|
||||
public static final String EXTRA_USERNAME = "username";
|
||||
|
||||
@Override
|
||||
protected void refreshUiReal() {
|
||||
private MagicCreateBinding binding;
|
||||
private String domain;
|
||||
private String username;
|
||||
private String preAuth;
|
||||
|
||||
}
|
||||
@Override
|
||||
protected void refreshUiReal() {
|
||||
|
||||
@Override
|
||||
void onBackendConnected() {
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
void onBackendConnected() {
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final int theme = findTheme();
|
||||
if (this.mTheme != theme) {
|
||||
recreate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
if (getResources().getBoolean(R.bool.portrait_only)) {
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.magic_create);
|
||||
setSupportActionBar(findViewById(R.id.toolbar));
|
||||
configureActionBar(getSupportActionBar());
|
||||
mFullJidDisplay = findViewById(R.id.full_jid);
|
||||
mUsername = findViewById(R.id.username);
|
||||
Button next = findViewById(R.id.create_account);
|
||||
next.setOnClickListener(v -> {
|
||||
try {
|
||||
String username = mUsername.getText().toString();
|
||||
Jid jid = Jid.of(username.toLowerCase(), Config.MAGIC_CREATE_DOMAIN, null);
|
||||
if (!jid.getEscapedLocal().equals(jid.getLocal())|| username.length() < 3) {
|
||||
mUsername.setError(getString(R.string.invalid_username));
|
||||
mUsername.requestFocus();
|
||||
} else {
|
||||
mUsername.setError(null);
|
||||
Account account = xmppConnectionService.findAccountByJid(jid);
|
||||
if (account == null) {
|
||||
account = new Account(jid, CryptoHelper.createPassword(new SecureRandom()));
|
||||
account.setOption(Account.OPTION_REGISTER, true);
|
||||
account.setOption(Account.OPTION_DISABLED, true);
|
||||
account.setOption(Account.OPTION_MAGIC_CREATE, true);
|
||||
xmppConnectionService.createAccount(account);
|
||||
}
|
||||
Intent intent = new Intent(MagicCreateActivity.this, EditAccountActivity.class);
|
||||
intent.putExtra("jid", account.getJid().asBareJid().toString());
|
||||
intent.putExtra("init", true);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
Toast.makeText(MagicCreateActivity.this, R.string.secure_password_generated, Toast.LENGTH_SHORT).show();
|
||||
StartConversationActivity.addInviteUri(intent, getIntent());
|
||||
startActivity(intent);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
mUsername.setError(getString(R.string.invalid_username));
|
||||
mUsername.requestFocus();
|
||||
}
|
||||
});
|
||||
mUsername.addTextChangedListener(this);
|
||||
}
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final int theme = findTheme();
|
||||
if (this.mTheme != theme) {
|
||||
recreate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
final Intent data = getIntent();
|
||||
this.domain = data == null ? null : data.getStringExtra(EXTRA_DOMAIN);
|
||||
this.preAuth = data == null ? null : data.getStringExtra(EXTRA_PRE_AUTH);
|
||||
this.username = data == null ? null : data.getStringExtra(EXTRA_USERNAME);
|
||||
if (getResources().getBoolean(R.bool.portrait_only)) {
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
this.binding = DataBindingUtil.setContentView(this, R.layout.magic_create);
|
||||
setSupportActionBar((Toolbar) this.binding.toolbar);
|
||||
configureActionBar(getSupportActionBar(), this.domain == null);
|
||||
if (username != null && domain != null) {
|
||||
binding.title.setText(R.string.your_server_invitation);
|
||||
binding.instructions.setText(getString(R.string.magic_create_text_fixed, domain));
|
||||
binding.finePrint.setVisibility(View.INVISIBLE);
|
||||
binding.username.setEnabled(false);
|
||||
binding.username.setText(this.username);
|
||||
updateFullJidInformation(this.username);
|
||||
} else if (domain != null) {
|
||||
binding.instructions.setText(getString(R.string.magic_create_text_on_x, domain));
|
||||
binding.finePrint.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
binding.createAccount.setOnClickListener(v -> {
|
||||
try {
|
||||
final String username = binding.username.getText().toString();
|
||||
final Jid jid;
|
||||
final boolean fixedUsername;
|
||||
if (this.domain != null && this.username != null) {
|
||||
fixedUsername = true;
|
||||
jid = Jid.ofLocalAndDomain(this.username, this.domain);
|
||||
} else if (this.domain != null) {
|
||||
fixedUsername = false;
|
||||
jid = Jid.ofLocalAndDomain(username, this.domain);
|
||||
} else {
|
||||
fixedUsername = false;
|
||||
jid = Jid.ofLocalAndDomain(username, Config.MAGIC_CREATE_DOMAIN);
|
||||
}
|
||||
if (!jid.getEscapedLocal().equals(jid.getLocal()) || (this.username == null && username.length() < 3)) {
|
||||
binding.username.setError(getString(R.string.invalid_username));
|
||||
binding.username.requestFocus();
|
||||
} else {
|
||||
binding.username.setError(null);
|
||||
Account account = xmppConnectionService.findAccountByJid(jid);
|
||||
if (account == null) {
|
||||
account = new Account(jid, CryptoHelper.createPassword(new SecureRandom()));
|
||||
account.setOption(Account.OPTION_REGISTER, true);
|
||||
account.setOption(Account.OPTION_DISABLED, true);
|
||||
account.setOption(Account.OPTION_MAGIC_CREATE, true);
|
||||
account.setOption(Account.OPTION_FIXED_USERNAME, fixedUsername);
|
||||
if (this.preAuth != null) {
|
||||
account.setKey(Account.PRE_AUTH_REGISTRATION_TOKEN, this.preAuth);
|
||||
}
|
||||
xmppConnectionService.createAccount(account);
|
||||
}
|
||||
Intent intent = new Intent(MagicCreateActivity.this, EditAccountActivity.class);
|
||||
intent.putExtra("jid", account.getJid().asBareJid().toString());
|
||||
intent.putExtra("init", true);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
Toast.makeText(MagicCreateActivity.this, R.string.secure_password_generated, Toast.LENGTH_SHORT).show();
|
||||
StartConversationActivity.addInviteUri(intent, getIntent());
|
||||
startActivity(intent);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
binding.username.setError(getString(R.string.invalid_username));
|
||||
binding.username.requestFocus();
|
||||
}
|
||||
});
|
||||
binding.username.addTextChangedListener(this);
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
InstallReferrerUtils.markInstallReferrerExecuted(this);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (s.toString().trim().length() > 0) {
|
||||
try {
|
||||
mFullJidDisplay.setVisibility(View.VISIBLE);
|
||||
Jid jid = Jid.of(s.toString().toLowerCase(), Config.MAGIC_CREATE_DOMAIN, null);
|
||||
mFullJidDisplay.setText(getString(R.string.your_full_jid_will_be, jid.toEscapedString()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
mFullJidDisplay.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
} else {
|
||||
mFullJidDisplay.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(final Editable s) {
|
||||
updateFullJidInformation(s.toString());
|
||||
}
|
||||
|
||||
private void updateFullJidInformation(final String username) {
|
||||
if (username.trim().isEmpty()) {
|
||||
binding.fullJid.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
try {
|
||||
binding.fullJid.setVisibility(View.VISIBLE);
|
||||
final Jid jid;
|
||||
if (this.domain == null) {
|
||||
jid = Jid.ofLocalAndDomain(username, Config.MAGIC_CREATE_DOMAIN);
|
||||
} else {
|
||||
jid = Jid.ofLocalAndDomain(username, this.domain);
|
||||
}
|
||||
binding.fullJid.setText(getString(R.string.your_full_jid_will_be, jid.toEscapedString()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
binding.fullJid.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,30 @@
|
|||
package eu.siacs.conversations.ui;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.databinding.DataBindingUtil;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.databinding.ActivityWelcomeBinding;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.utils.InstallReferrerUtils;
|
||||
import eu.siacs.conversations.utils.SignupUtils;
|
||||
import eu.siacs.conversations.utils.XmppUri;
|
||||
import rocks.xmpp.addr.Jid;
|
||||
|
||||
import static eu.siacs.conversations.utils.PermissionUtils.allGranted;
|
||||
import static eu.siacs.conversations.utils.PermissionUtils.writeGranted;
|
||||
|
@ -24,6 +33,46 @@ public class WelcomeActivity extends XmppActivity {
|
|||
|
||||
private static final int REQUEST_IMPORT_BACKUP = 0x63fb;
|
||||
|
||||
private XmppUri inviteUri;
|
||||
|
||||
public static void launch(AppCompatActivity activity) {
|
||||
Intent intent = new Intent(activity, WelcomeActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
activity.startActivity(intent);
|
||||
activity.overridePendingTransition(0, 0);
|
||||
}
|
||||
|
||||
public void onInstallReferrerDiscovered(final String referrer) {
|
||||
Log.d(Config.LOGTAG, "welcome activity: on install referrer discovered " + referrer);
|
||||
if (referrer != null) {
|
||||
final XmppUri xmppUri = new XmppUri(referrer);
|
||||
runOnUiThread(() -> processXmppUri(xmppUri));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean processXmppUri(final XmppUri xmppUri) {
|
||||
if (xmppUri.isValidJid()) {
|
||||
final String preauth = xmppUri.getParamater("preauth");
|
||||
final Jid jid = xmppUri.getJid();
|
||||
final Intent intent;
|
||||
if (xmppUri.isAction(XmppUri.ACTION_REGISTER)) {
|
||||
intent = SignupUtils.getTokenRegistrationIntent(this, jid, preauth);
|
||||
} else if (xmppUri.isAction(XmppUri.ACTION_ROSTER) && "y".equals(xmppUri.getParamater("ibr"))) {
|
||||
intent = SignupUtils.getTokenRegistrationIntent(this, Jid.ofDomain(jid.getDomain()), preauth);
|
||||
intent.putExtra(StartConversationActivity.EXTRA_INVITE_URI, xmppUri.toString());
|
||||
} else {
|
||||
intent = null;
|
||||
}
|
||||
if (intent != null) {
|
||||
startActivity(intent);
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
this.inviteUri = xmppUri;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refreshUiReal() {
|
||||
|
||||
|
@ -41,6 +90,12 @@ public class WelcomeActivity extends XmppActivity {
|
|||
if (this.mTheme != theme) {
|
||||
recreate();
|
||||
}
|
||||
new InstallReferrerUtils(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -56,7 +111,7 @@ public class WelcomeActivity extends XmppActivity {
|
|||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
ActivityWelcomeBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_welcome);
|
||||
ActivityWelcomeBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_welcome);
|
||||
setSupportActionBar((Toolbar) binding.toolbar);
|
||||
configureActionBar(getSupportActionBar(), false);
|
||||
binding.registerNewAccount.setOnClickListener(v -> {
|
||||
|
@ -65,9 +120,9 @@ public class WelcomeActivity extends XmppActivity {
|
|||
startActivity(intent);
|
||||
});
|
||||
binding.useExisting.setOnClickListener(v -> {
|
||||
List<Account> accounts = xmppConnectionService.getAccounts();
|
||||
final List<Account> accounts = xmppConnectionService.getAccounts();
|
||||
Intent intent = new Intent(WelcomeActivity.this, EditAccountActivity.class);
|
||||
intent.putExtra(EditAccountActivity.EXTRA_FORCE_REGISTER,false);
|
||||
intent.putExtra(EditAccountActivity.EXTRA_FORCE_REGISTER, false);
|
||||
if (accounts.size() == 1) {
|
||||
intent.putExtra("jid", accounts.get(0).getJid().asBareJid().toString());
|
||||
intent.putExtra("init", true);
|
||||
|
@ -83,22 +138,29 @@ public class WelcomeActivity extends XmppActivity {
|
|||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.welcome_menu, menu);
|
||||
final MenuItem scan = menu.findItem(R.id.action_scan_qr_code);
|
||||
scan.setVisible(getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA));
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.action_import_backup) {
|
||||
if (hasStoragePermission(REQUEST_IMPORT_BACKUP)) {
|
||||
startActivity(new Intent(this, ImportBackupActivity.class));
|
||||
}
|
||||
return true;
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_import_backup:
|
||||
if (hasStoragePermission(REQUEST_IMPORT_BACKUP)) {
|
||||
startActivity(new Intent(this, ImportBackupActivity.class));
|
||||
}
|
||||
break;
|
||||
case R.id.action_scan_qr_code:
|
||||
UriHandlerActivity.scan(this);
|
||||
break;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
UriHandlerActivity.onRequestPermissionResult(this, requestCode, grantResults);
|
||||
if (grantResults.length > 0) {
|
||||
if (allGranted(grantResults)) {
|
||||
switch (requestCode) {
|
||||
|
@ -106,7 +168,7 @@ public class WelcomeActivity extends XmppActivity {
|
|||
startActivity(new Intent(this, ImportBackupActivity.class));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
} else if (Arrays.asList(permissions).contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
@ -117,15 +179,15 @@ public class WelcomeActivity extends XmppActivity {
|
|||
}
|
||||
}
|
||||
|
||||
public void addInviteUri(Intent intent) {
|
||||
StartConversationActivity.addInviteUri(intent, getIntent());
|
||||
}
|
||||
|
||||
public static void launch(AppCompatActivity activity) {
|
||||
Intent intent = new Intent(activity, WelcomeActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
activity.startActivity(intent);
|
||||
activity.overridePendingTransition(0, 0);
|
||||
public void addInviteUri(Intent to) {
|
||||
final Intent from = getIntent();
|
||||
if (from != null && from.hasExtra(StartConversationActivity.EXTRA_INVITE_URI)) {
|
||||
final String invite = from.getStringExtra(StartConversationActivity.EXTRA_INVITE_URI);
|
||||
to.putExtra(StartConversationActivity.EXTRA_INVITE_URI, invite);
|
||||
} else if (this.inviteUri != null) {
|
||||
Log.d(Config.LOGTAG, "injecting referrer uri into on-boarding flow");
|
||||
to.putExtra(StartConversationActivity.EXTRA_INVITE_URI, this.inviteUri.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,13 +8,31 @@ import eu.siacs.conversations.entities.Account;
|
|||
import eu.siacs.conversations.services.XmppConnectionService;
|
||||
import eu.siacs.conversations.ui.ConversationsActivity;
|
||||
import eu.siacs.conversations.ui.EditAccountActivity;
|
||||
import eu.siacs.conversations.ui.MagicCreateActivity;
|
||||
import eu.siacs.conversations.ui.ManageAccountActivity;
|
||||
import eu.siacs.conversations.ui.PickServerActivity;
|
||||
import eu.siacs.conversations.ui.StartConversationActivity;
|
||||
import eu.siacs.conversations.ui.WelcomeActivity;
|
||||
import rocks.xmpp.addr.Jid;
|
||||
|
||||
public class SignupUtils {
|
||||
|
||||
public static boolean isSupportTokenRegistry() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Intent getTokenRegistrationIntent(final Activity activity, Jid jid, String preAuth) {
|
||||
final Intent intent = new Intent(activity, MagicCreateActivity.class);
|
||||
if (jid.isDomainJid()) {
|
||||
intent.putExtra(MagicCreateActivity.EXTRA_DOMAIN, jid.getDomain());
|
||||
} else {
|
||||
intent.putExtra(MagicCreateActivity.EXTRA_DOMAIN, jid.getDomain());
|
||||
intent.putExtra(MagicCreateActivity.EXTRA_USERNAME, jid.getEscapedLocal());
|
||||
}
|
||||
intent.putExtra(MagicCreateActivity.EXTRA_PRE_AUTH, preAuth);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent getSignUpIntent(final Activity activity) {
|
||||
return getSignUpIntent(activity, false);
|
||||
}
|
||||
|
|
|
@ -1,86 +1,114 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<include layout="@layout/toolbar" />
|
||||
<LinearLayout
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true">
|
||||
<RelativeLayout
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/toolbar" android:id="@+id/toolbar"/>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/color_background_primary">
|
||||
android:fillViewport="true">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:minHeight="256dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp">
|
||||
<Space
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pick_your_username"
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Title"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/magic_create_text"
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Body1"/>
|
||||
<EditText
|
||||
android:id="@+id/username"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:hint="@string/username_hint"
|
||||
android:inputType="textNoSuggestions"/>
|
||||
<TextView
|
||||
android:id="@+id/full_jid"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/your_full_jid_will_be"
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Caption"
|
||||
android:visibility="invisible"/>
|
||||
<Button
|
||||
android:id="@+id/create_account"
|
||||
style="@style/Widget.Conversations.Button.Borderless"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="right"
|
||||
android:text="@string/next"
|
||||
android:textColor="?colorAccent"/>
|
||||
</LinearLayout>
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/linearLayout"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true">
|
||||
<ImageView
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/color_background_primary">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:minHeight="256dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<Space
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pick_your_username"
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/instructions"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/magic_create_text"
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Body1" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/username"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:hint="@string/username_hint"
|
||||
android:textColor="?attr/edit_text_color"
|
||||
android:inputType="textNoSuggestions" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/full_jid"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/your_full_jid_will_be"
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Caption"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/create_account"
|
||||
style="@style/Widget.Conversations.Button.Borderless"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="right"
|
||||
android:text="@string/next"
|
||||
android:textColor="?colorAccent" />
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/linearLayout"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/main_logo" />
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fine_print"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/main_logo"/>
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:text="@string/free_for_six_month"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/fineprint_size" />
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
</layout>
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_scan_qr_code"
|
||||
android:title="@string/scan_qr_code"
|
||||
app:showAsAction="ifRoom"
|
||||
android:orderInCategory="10"
|
||||
android:visible="@bool/show_qr_code_scan"
|
||||
android:icon="?attr/icon_scan_qr_code"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_import_backup"
|
||||
app:showAsAction="never"
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="pick_a_server">Изберете вашият XMPP доставчик</string>
|
||||
<string name="use_conversations.im">Използвайте conversations.im</string>
|
||||
<string name="create_new_account">Създаване не нов профил</string>
|
||||
<string name="do_you_have_an_account">Имате ли вече XMPP профил? Това може да се случи, ако вече използвате друг клиент на XMPP или сте използвали преди това Conversations. Ако не, можете да създадете нов XMPP профил в момента.\nСъвет: Някои доставчици на имейл също предоставят XMPP профили.
|
||||
</string>
|
||||
</resources>
|
|
@ -3,7 +3,9 @@
|
|||
<string name="pick_a_server">Wähle deinen XMPP-Provider</string>
|
||||
<string name="use_chat.sum7.eu">Benutze chat.sum7.eu</string>
|
||||
<string name="create_new_account">Neues Konto erstellen</string>
|
||||
<string name="do_you_have_an_account">Hast du bereits ein XMPP-Konto? Dies kann der Fall sein, wenn du bereits einen anderen XMPP-Client verwendest oder bereits Conv6sations verwendet hast. Wenn nicht, kannst du jetzt ein neues XMPP-Konto erstellen.\nTipp: Einige E-Mail-Anbieter bieten auch XMPP-Konten an.</string>
|
||||
<string name="server_select_text">XMPP ist ein anbieterunabhängiges Instant Messaging Netzwerk. Du kannst diesen Client mit jedem beliebigen XMPP-Server nutzen.\nUm es dir leicht zu machen, haben wir die Möglichkeit geschaffen, ein Konto auf chat.sum7.eu anzulegen; ein Anbieter, der speziell für die Verwendung mit Conv6sations geeignet ist.</string>
|
||||
|
||||
<string name="do_you_have_an_account">Hast du bereits ein XMPP-Konto? Dies kann der Fall sein, wenn du bereits einen anderen XMPP-Client verwendest oder bereits Conversations verwendet hast. Wenn nicht, kannst du jetzt ein neues XMPP-Konto erstellen.\nTipp: Einige E-Mail-Anbieter bieten auch XMPP-Konten an.</string>
|
||||
<string name="server_select_text">XMPP ist ein anbieterunabhängiges Instant Messaging Netzwerk. Du kannst diesen Client mit jedem beliebigen XMPP-Server nutzen.\nUm es dir leicht zu machen, haben wir die Möglichkeit geschaffen, ein Konto auf chat.sum7.eu anzulegen; ein Anbieter, der speziell für die Verwendung mit Conversations geeignet ist.</string>
|
||||
<string name="magic_create_text_on_x">Du wurdest zu %1$s eingeladen. Wir führen dich durch den Prozess der Kontoerstellung.\nWenn du %1$s als Provider wählst, kannst du mit Nutzern anderer Anbieter kommunizieren, indem du ihnen deine vollständige XMPP-Adresse gibst.</string>
|
||||
<string name="magic_create_text_fixed">Du wurdest zu %1$seingeladen. Ein Benutzername ist bereits für dich ausgewählt worden. Wir führen dich durch den Prozess der Kontoerstellung.\nDu kannst mit Nutzern anderer Anbieter kommunizieren, indem du ihnen deine vollständige XMPP-Adresse gibst.</string>
|
||||
<string name="your_server_invitation">Deine Einladung für den Server</string>
|
||||
</resources>
|
||||
|
|
|
@ -5,5 +5,4 @@
|
|||
<string name="create_new_account">Δημιουργία νέου λογαριασμού</string>
|
||||
<string name="do_you_have_an_account">Έχετε ήδη λογαριασμό XMPP; Αυτό μπορεί να συμβαίνει αν ήδη χρησιμοποιείτε ένα άλλο πρόγραμμα XMPP ή έχετε χρησιμοποιήσει το Conversations παλιότερα. Αν όχι, μπορείτε να δημιουργήσετε ένα νέο λογαριασμό XMPP τώρα.\nΧρήσιμη πληροφορία: Κάποιοι πάροχοι e-mail παρέχουν επίσης και λογαριασμούς XMPP.</string>
|
||||
<string name="server_select_text">Το XMPP είναι ένα δίκτυο άμεσης ανταλλαγής μηνυμάτων ανεξάρτητο παρόχου. Μπορείτε να χρησιμοποιήσετε αυτό το πρόγραμμα με όποιον διακομιστή XMPP επιθυμείτε.\nΓια διευκόλυνση πάντως μπορείτε να δημιουργήσετε έναν λογαριασμό στο chat.sum7.eu, έναν πάροχο ειδικά σχεδιασμένο για χρήση με το Conversations.</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -5,5 +5,4 @@
|
|||
<string name="create_new_account">Crear nueva cuenta</string>
|
||||
<string name="do_you_have_an_account">¿Ya tienes una cuenta XMPP? Este puede ser el caso si ya estás usando un cliente XMPP diferente o has usado Conversations anteriormente. Si no es así, puedes crear una nueva cuenta XMPP ahora mismo.\nConsejo: Algunos proveedores de email también ofrecen una cuenta XMPP.</string>
|
||||
<string name="server_select_text">XMPP es una red de mensajería instantánea independiente del proveedor. Puedes usar este cliente con cualquier servidor XMPP que elijas.\nSin embargo, para tu conveniencia, hacemos de forma sencilla la creación de una cuenta en chat.sum7.eu; un proveedor especializado para el uso con Conversations </string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -5,5 +5,4 @@
|
|||
<string name="create_new_account">Kontu berria sortu</string>
|
||||
<string name="do_you_have_an_account">XMPP kontu bat badaukazu dagoeneko? Horrela izan daiteke beste XMPP aplikazio bat erabiltzen baduzu edo Conversations lehenago erabili baduzu. Bestela XMPP kontu berri bat sortu dezakezu oraintxe bertan.\nIradokizuna: email hornitzaile batzuek XMPP kontuak hornitzen dituzte ere.</string>
|
||||
<string name="server_select_text">XMPP hornitzailez independientea den bat-bateko mezularitza sare bat da. Aplikazio hau nahi duzun XMPP zerbitzariarekin erabili dezakezu.\nHala ere zure erosotasunerako chat.sum7.eu-en, Conversationsekin bereziki erabiltzeko egokia den hornitzaile batean, kontu bat sortzea erraz egin dugu.</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -5,5 +5,4 @@
|
|||
<string name="create_new_account">Créer un nouveau compte</string>
|
||||
<string name="do_you_have_an_account">Avez-vous déjà un compte XMPP ? Cela peut être le cas si vous utilisez déjà un autre client XMPP ou si vous avez déjà utilisé Conversations auparavant. Sinon, vous pouvez créer un nouveau compte XMPP dès maintenant. Remarque : Certains fournisseurs de messagerie proposent également des comptes XMPP.</string>
|
||||
<string name="server_select_text">XMPP est un réseau de messagerie instantanée indépendant du fournisseur. Vous pouvez utiliser ce client avec n\'importe quel serveur XMPP de votre choix. Toutefois, pour votre commodité, nous avons facilité la création d\'un compte sur chat.sum7.eu ; un fournisseur spécialement conçu pour l\'utilisation avec Conversations.</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -5,5 +5,7 @@
|
|||
<string name="create_new_account">Crear nova conta</string>
|
||||
<string name="do_you_have_an_account">Xa posúe unha conta XMPP? Este pode ser o caso se xa está a utilizar outro cliente XMPP ou utilizou Conversations previamente. Se non é así pode crear unha nova conta agora mesmo.\nTruco: Algúns provedores de correo tamén proporcionan contas XMPP.</string>
|
||||
<string name="server_select_text">XMPP é unha rede de mensaxería independente do provedor. Pode utilizar este cliente con calquer provedor XMPP da súa elección.\nMais para a súa conveniencia fixemos que fose doado crear unha conta en chat.sum7.eu; un provedor especialmente axeitado para utilizar con Conversations.</string>
|
||||
|
||||
<string name="magic_create_text_on_x">Convidáronte a %1$s. Guiarémoste no proceso para crear unha conta.\nAo escoller %1$s como provedor poderás comunicarte con usuarias de outros provedores cando lles deas o teu enderezo XMPP completo.</string>
|
||||
<string name="magic_create_text_fixed">Convidáronte a %1$s. Escollemos un nome de usuaria por ti. Guiarémoste no proceso de crear unha conta.\nPoderás comunicarte con usuarias de outros provedores cando lles digas o teu enderezo XMPP completo.</string>
|
||||
<string name="your_server_invitation">O convite do teu servidor</string>
|
||||
</resources>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
<string name="pick_a_server">Válassza ki az XMPP szolgáltatóját</string>
|
||||
<string name="use_chat.sum7.eu">A chat.sum7.eu használata</string>
|
||||
<string name="create_new_account">Új fiók létrehozása</string>
|
||||
<string name="do_you_have_an_account">Már rendelkezik XMPP-fiókkal? Ez az eset állhat fenn, ha már egy másik XMPP-klienst használ, vagy ha már korábban használta a Conv6sations alkalmazást. Ha nem, akkor most létrehozhat egy új XMPP-fiókot.\nTipp: egyes e-mail szolgáltatók is biztosítanak XMPP-fiókokat.</string>
|
||||
<string name="server_select_text">Az XMPP egy szolgáltatófüggetlen, azonnali üzenetküldő hálózat. Ezt a kliensprogramot bármely XMPP-kiszolgálóhoz használhatja.\nAzonban a kényelem érdekében megkönnyítettük a chat.sum7.eu szolgáltatón való fióklétrehozást, ami kifejezetten a Conv6sations alkalmazással történő használatra lett tervezve.</string>
|
||||
|
||||
<string name="do_you_have_an_account">Már rendelkezik XMPP-fiókkal? Ez az eset állhat fenn, ha már egy másik XMPP-klienst használ, vagy ha már korábban használta a Conversations alkalmazást. Ha nem, akkor most létrehozhat egy új XMPP-fiókot.\nTipp: egyes e-mail szolgáltatók is biztosítanak XMPP-fiókokat.</string>
|
||||
<string name="server_select_text">Az XMPP egy szolgáltatófüggetlen, azonnali üzenetküldő hálózat. Ezt a kliensprogramot bármely XMPP-kiszolgálóhoz használhatja.\nAzonban a kényelem érdekében megkönnyítettük a chat.sum7.eu szolgáltatón való fióklétrehozást, ami kifejezetten a Conversations alkalmazással történő használatra lett tervezve.</string>
|
||||
</resources>
|
||||
|
|
|
@ -7,5 +7,4 @@
|
|||
Suggerimento: alcuni provider di email forniscono anche un account XMPP.</string>
|
||||
<string name="server_select_text">XMPP è una rete di instant messaging indipendente dal provider. Puoi usare questo client con qualsiasi server XMPP.
|
||||
In ogni caso per facilitare puoi creare facilmente un account su chat.sum7.eu, un provider pensato apposta per essere usato con Conversations.</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -5,5 +5,4 @@
|
|||
<string name="create_new_account">Nieuwe account registreren</string>
|
||||
<string name="do_you_have_an_account">Heb je al een XMPP-account? Als je al een andere XMPP-cliënt gebruikt, of Conversations vroeger al eens hebt gebruikt, is dit waarschijnlijk het geval. Zo niet, kan je nu een nieuwe XMPP-account aanmaken.\nTip: sommige e-mailproviders bieden ook XMPP-accounts aan.</string>
|
||||
<string name="server_select_text">XMPP is een provider-onafhankelijk berichtennetwerk. Je kan deze cliënt gebruiken met eender welke XMPP-server.\nOm het je gemakkelijker te maken kun je simpelweg een account aanmaken op chat.sum7.eu; een provider speciaal geschikt voor Conversations.</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -5,5 +5,4 @@
|
|||
<string name="create_new_account">Stwórz nowe konto</string>
|
||||
<string name="do_you_have_an_account">Czy masz już konto XMPP? Tak może być jeśli używasz już innego klienta XMPP lub używałeś już Conversations. Jeśli nie możesz stworzyć nowe konto XMPP teraz.\nPodpowiedź: Niektórzy dostawcy poczty oferują również konta XMPP.</string>
|
||||
<string name="server_select_text">XMPP to niezależna od dostawcy sieć komunikacji błyskawicznej. Możesz użyć tego klienta z dowolnym serwerem XMPP.\nDla twojej wygody jednak ułatwiliśmy stworzenie konta na chat.sum7.eu; dostawcy specjalnie dostosowanego do pracy z Conversations.</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -5,5 +5,7 @@
|
|||
<string name="create_new_account">Criar uma nova conta</string>
|
||||
<string name="do_you_have_an_account">Você já possui uma conta XMPP? Esse pode ser o seu caso caso já esteja usando um outro cliente XMPP ou tenha usado o Conversations antes. Caso contrário, você pode criar uma nova conta XMPP agora.\nDica: alguns provedores de e-mail também fornecem contas XMPP.</string>
|
||||
<string name="server_select_text">O XMPP é uma rede de mensageria instantânea independente de provedor. Você pode usar esse cliente com qualquer servidor XMPP que você escolher.\nEntretanto, para sua conveniência, nós simplificamos o processo de criação de uma conta em chat.sum7.eu, um provedor especialmente configurado para se usar com o Conversations.</string>
|
||||
|
||||
<string name="magic_create_text_on_x">Você foi convidado para %1$s. Nós iremos guiá-lo ao longo do processo de criação de uma conta.\nAo escolher %1$s como um provedor você conseguirá se comunicar com usuários de outros provedores dando a eles seu endereço XMPP completo.</string>
|
||||
<string name="magic_create_text_fixed">Você foi convidado para %1$s. Um nome de usuário já foi escolhido para você. Nós iremos guiá-lo ao longo do processo de criação de uma conta.\nVocê conseguirá se comunicar com usuários de outros provedores dando a eles seu endereço XMPP completo.</string>
|
||||
<string name="your_server_invitation">Seu convite do servidor</string>
|
||||
</resources>
|
||||
|
|
|
@ -5,5 +5,7 @@
|
|||
<string name="create_new_account">Creează un cont nou</string>
|
||||
<string name="do_you_have_an_account">Aveți deja un cont XMPP? S-ar putea să fie așa dacă deja utilizați un alt client XMPP sau dacă ați folosit Conversations în trecut. Dacă nu, puteți crea un cont nou XMPP chiar acum.\nIdee: Unii furnizori de e-mail oferă de asemenea și conturi XMPP.</string>
|
||||
<string name="server_select_text">XMPP este o rețea de mesagerie instant ce nu depinde de un anumit furnizor. Aveți posibilitatea să utilizați acest client cu orice server XMPP doriți.\nTotuși, pentru confortul dumneavoastră, am facilitat crearea unui cont pe chat.sum7.eu; un furnizor potrivit pentru utilizarea cu aplicația Conversations.</string>
|
||||
|
||||
<string name="magic_create_text_on_x">Ați fost invitați la %1$s. Vă vom ghida prin procesul de creare al unui cont.\nCând alegeți %1$s ca furnizor veți putea comunica cu utilizatorii altor furnizori oferindu-le adresa dumneavoastră completă XMPP.</string>
|
||||
<string name="magic_create_text_fixed">Ați fost invitați la %1$s. Un nume de utilizator a fost deja ales pentru dumneavoastră. Vă vom ghida prin procesul de creare al unui cont.\nVeți putea comunica cu utilizatorii altor furnizori oferindu-le adresa dumneavoastră completă XMPP.</string>
|
||||
<string name="your_server_invitation">Invitația serverului dumneavoastră</string>
|
||||
</resources>
|
||||
|
|
|
@ -5,5 +5,4 @@
|
|||
<string name="create_new_account">Створити новий обліковий запис</string>
|
||||
<string name="do_you_have_an_account">Вже маєте обліковий запис XMPP? Можливо, користуєтеся іншою програмою XMPP або користувалися цією програмою раніше. Якщо ні, можете створити новий обліковий запис XMPP просто зараз.\nЗверніть увагу: Деякі постачальники електронної пошти водночас надають облікові записи XMPP.</string>
|
||||
<string name="server_select_text">XMPP — це мережа обміну повідомленнями, незалежна від постачальників. Можете використовувати цю програму з будь-яким XMPP сервером, який оберете.\nПроте, для зручності, ми спростили створення облікового запису на conversations.im¹ — в постачальника, який спеціально налаштований на роботу з цією програмою.</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -5,5 +5,7 @@
|
|||
<string name="create_new_account">Create new account</string>
|
||||
<string name="do_you_have_an_account">Do you already have an XMPP account? This might be the case if you are already using a different XMPP client or have used Conversations before. If not you can create a new XMPP account right now.\nHint: Some email providers also provide XMPP accounts.</string>
|
||||
<string name="server_select_text">XMPP is a provider independent instant messaging network. You can use this client with what ever XMPP server you choose.\nHowever for your convenience we made it easy to create an account on chat.sum7.eu; a provider specially suited for the use with Conversations.</string>
|
||||
|
||||
<string name="magic_create_text_on_x">You have been invited to %1$s. We will guide you through the process of creating an account.\nWhen picking %1$s as a provider you will be able to communicate with users of other providers by giving them your full XMPP address.</string>
|
||||
<string name="magic_create_text_fixed">You have been invited to %1$s. A username has already been picked for you. We will guide you through the process of creating an account.\nYou will be able to communicate with users of other providers by giving them your full XMPP address.</string>
|
||||
<string name="your_server_invitation">Your server invitation</string>
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package eu.siacs.conversations.utils;
|
||||
|
||||
import eu.siacs.conversations.ui.MagicCreateActivity;
|
||||
import eu.siacs.conversations.ui.WelcomeActivity;
|
||||
|
||||
public class InstallReferrerUtils {
|
||||
|
||||
public InstallReferrerUtils(WelcomeActivity welcomeActivity) {
|
||||
|
||||
}
|
||||
|
||||
public static void markInstallReferrerExecuted(MagicCreateActivity magicCreateActivity) {
|
||||
//stub
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package eu.siacs.conversations.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.RemoteException;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.installreferrer.api.InstallReferrerClient;
|
||||
import com.android.installreferrer.api.InstallReferrerStateListener;
|
||||
import com.android.installreferrer.api.ReferrerDetails;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.ui.WelcomeActivity;
|
||||
|
||||
public class InstallReferrerUtils implements InstallReferrerStateListener {
|
||||
|
||||
private static final String PROCESSED_INSTALL_REFERRER = "processed_install_referrer";
|
||||
|
||||
|
||||
private final WelcomeActivity welcomeActivity;
|
||||
private final InstallReferrerClient installReferrerClient;
|
||||
|
||||
|
||||
public InstallReferrerUtils(WelcomeActivity welcomeActivity) {
|
||||
this.welcomeActivity = welcomeActivity;
|
||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(welcomeActivity);
|
||||
if (preferences.getBoolean(PROCESSED_INSTALL_REFERRER, false)) {
|
||||
Log.d(Config.LOGTAG, "install referrer already processed");
|
||||
this.installReferrerClient = null;
|
||||
return;
|
||||
}
|
||||
this.installReferrerClient = InstallReferrerClient.newBuilder(welcomeActivity).build();
|
||||
this.installReferrerClient.startConnection(this);
|
||||
}
|
||||
|
||||
public static void markInstallReferrerExecuted(final Activity context) {
|
||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
preferences.edit().putBoolean(PROCESSED_INSTALL_REFERRER, true).apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstallReferrerSetupFinished(int responseCode) {
|
||||
switch (responseCode) {
|
||||
case InstallReferrerClient.InstallReferrerResponse.OK:
|
||||
try {
|
||||
final ReferrerDetails referrerDetails = installReferrerClient.getInstallReferrer();
|
||||
final String referrer = referrerDetails.getInstallReferrer();
|
||||
welcomeActivity.onInstallReferrerDiscovered(referrer);
|
||||
} catch (RemoteException e) {
|
||||
Log.d(Config.LOGTAG, "unable to get install referrer", e);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log.d(Config.LOGTAG, "unable to setup install referrer client. code=" + responseCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstallReferrerServiceDisconnected() {
|
||||
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.location"
|
||||
|
@ -282,7 +283,9 @@
|
|||
<activity
|
||||
android:name=".ui.MucUsersActivity"
|
||||
android:label="@string/group_chat_members" />
|
||||
<activity android:label="@string/discover_channels" android:name=".ui.ChannelDiscoveryActivity"/>
|
||||
<activity
|
||||
android:name=".ui.ChannelDiscoveryActivity"
|
||||
android:label="@string/discover_channels" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -94,10 +94,13 @@ public final class Config {
|
|||
|
||||
public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||
|
||||
public static final long OMEMO_AUTO_EXPIRY = 14 * MILLISECONDS_IN_DAY;
|
||||
//remove *other* omemo devices from *your* device list announcement after not seeing any activity from them for 42 days. They will automatically add themselves after coming back online.
|
||||
public static final long OMEMO_AUTO_EXPIRY = 42 * MILLISECONDS_IN_DAY;
|
||||
|
||||
public static final boolean REMOVE_BROKEN_DEVICES = false;
|
||||
public static final boolean OMEMO_PADDING = false;
|
||||
public static final boolean PUT_AUTH_TAG_INTO_KEY = true;
|
||||
public static final boolean TWELVE_BYTE_IV = false;
|
||||
|
||||
public static final boolean USE_BOOKMARKS2 = false;
|
||||
|
||||
|
|
|
@ -165,8 +165,8 @@ public class XmppAxolotlMessage {
|
|||
}
|
||||
|
||||
private static byte[] generateIv() {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] iv = new byte[16];
|
||||
final SecureRandom random = new SecureRandom();
|
||||
byte[] iv = new byte[Config.TWELVE_BYTE_IV ? 12 : 16];
|
||||
random.nextBytes(iv);
|
||||
return iv;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
|
|||
public static final String RESOURCE = "resource";
|
||||
|
||||
public static final String PINNED_MECHANISM_KEY = "pinned_mechanism";
|
||||
public static final String PRE_AUTH_REGISTRATION_TOKEN = "pre_auth_registration";
|
||||
|
||||
public static final int OPTION_USETLS = 0;
|
||||
public static final int OPTION_DISABLED = 1;
|
||||
|
@ -60,6 +61,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
|
|||
public static final int OPTION_LOGGED_IN_SUCCESSFULLY = 6;
|
||||
public static final int OPTION_HTTP_UPLOAD_AVAILABLE = 7;
|
||||
public static final int OPTION_UNVERIFIED = 8;
|
||||
public static final int OPTION_FIXED_USERNAME = 9;
|
||||
private static final String KEY_PGP_SIGNATURE = "pgp_signature";
|
||||
private static final String KEY_PGP_ID = "pgp_id";
|
||||
public final HashSet<Pair<String, String>> inProgressDiscoFetches = new HashSet<>();
|
||||
|
@ -619,6 +621,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
|
|||
REGISTRATION_CONFLICT(true, false),
|
||||
REGISTRATION_NOT_SUPPORTED(true, false),
|
||||
REGISTRATION_PLEASE_WAIT(true, false),
|
||||
REGISTRATION_INVALID_TOKEN(true,false),
|
||||
REGISTRATION_PASSWORD_TOO_WEAK(true, false),
|
||||
TLS_ERROR,
|
||||
INCOMPATIBLE_SERVER,
|
||||
|
@ -683,6 +686,8 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
|
|||
return R.string.account_status_regis_success;
|
||||
case REGISTRATION_NOT_SUPPORTED:
|
||||
return R.string.account_status_regis_not_sup;
|
||||
case REGISTRATION_INVALID_TOKEN:
|
||||
return R.string.account_status_regis_invalid_token;
|
||||
case TLS_ERROR:
|
||||
return R.string.account_status_tls_error;
|
||||
case INCOMPATIBLE_SERVER:
|
||||
|
|
|
@ -653,6 +653,10 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isOOb() {
|
||||
return oob;
|
||||
}
|
||||
|
||||
public static class MergeSeparator {
|
||||
}
|
||||
|
||||
|
@ -802,7 +806,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
|
|||
if (this.transferable != null) {
|
||||
fileParams.size = this.transferable.getFileSize();
|
||||
}
|
||||
String parts[] = body == null ? new String[0] : body.split("\\|");
|
||||
final String[] parts = body == null ? new String[0] : body.split("\\|");
|
||||
switch (parts.length) {
|
||||
case 1:
|
||||
try {
|
||||
|
|
|
@ -4,7 +4,10 @@ import android.os.PowerManager;
|
|||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
@ -69,10 +72,22 @@ public class HttpDownloadConnection implements Transferable {
|
|||
}
|
||||
|
||||
public void init(boolean interactive) {
|
||||
if (message.isDeleted()) {
|
||||
if (message.getType() == Message.TYPE_PRIVATE_FILE) {
|
||||
message.setType(Message.TYPE_PRIVATE);
|
||||
} else if (message.isFileOrImage()) {
|
||||
message.setType(Message.TYPE_TEXT);
|
||||
}
|
||||
message.setDeleted(false);
|
||||
mXmppConnectionService.updateMessage(message);
|
||||
}
|
||||
this.message.setTransferable(this);
|
||||
try {
|
||||
final Message.FileParams fileParams = message.getFileParams();
|
||||
if (message.hasFileOnRemoteHost()) {
|
||||
mUrl = CryptoHelper.toHttpsUrl(message.getFileParams().url);
|
||||
mUrl = CryptoHelper.toHttpsUrl(fileParams.url);
|
||||
} else if (message.isOOb() && fileParams.url != null && fileParams.size > 0) {
|
||||
mUrl = fileParams.url;
|
||||
} else {
|
||||
mUrl = CryptoHelper.toHttpsUrl(new URL(message.getBody().split("\n")[0]));
|
||||
}
|
||||
|
@ -90,7 +105,12 @@ public class HttpDownloadConnection implements Transferable {
|
|||
ext = extension.main;
|
||||
}
|
||||
message.setRelativeFilePath(message.getUuid() + (ext != null ? ("." + ext) : ""));
|
||||
this.file = mXmppConnectionService.getFileBackend().getFile(message, false);
|
||||
if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) {
|
||||
this.file = new DownloadableFile(mXmppConnectionService.getCacheDir().getAbsolutePath() + "/" + message.getUuid());
|
||||
Log.d(Config.LOGTAG, "create temporary OMEMO encrypted file: " + this.file.getAbsolutePath() + "(" + message.getMimeType() + ")");
|
||||
} else {
|
||||
this.file = mXmppConnectionService.getFileBackend().getFile(message, false);
|
||||
}
|
||||
final String reference = mUrl.getRef();
|
||||
if (reference != null && AesGcmURLStreamHandler.IV_KEY.matcher(reference).matches()) {
|
||||
this.file.setKeyAndIv(CryptoHelper.hexToBytes(reference));
|
||||
|
@ -131,6 +151,37 @@ public class HttpDownloadConnection implements Transferable {
|
|||
mHttpConnectionManager.updateConversationUi(true);
|
||||
}
|
||||
|
||||
private void decryptOmemoFile() {
|
||||
final DownloadableFile outputFile = mXmppConnectionService.getFileBackend().getFile(message, true);
|
||||
|
||||
if (outputFile.getParentFile().mkdirs()) {
|
||||
Log.d(Config.LOGTAG, "created parent directories for " + outputFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
try {
|
||||
outputFile.createNewFile();
|
||||
final InputStream is = new FileInputStream(this.file);
|
||||
|
||||
outputFile.setKey(this.file.getKey());
|
||||
outputFile.setIv(this.file.getIv());
|
||||
final OutputStream os = AbstractConnectionManager.createOutputStream(outputFile, false, true);
|
||||
|
||||
ByteStreams.copy(is, os);
|
||||
|
||||
FileBackend.close(is);
|
||||
FileBackend.close(os);
|
||||
|
||||
if (!file.delete()) {
|
||||
Log.w(Config.LOGTAG,"unable to delete temporary OMEMO encrypted file " + file.getAbsolutePath());
|
||||
}
|
||||
|
||||
message.setRelativeFilePath(outputFile.getPath());
|
||||
} catch (IOException e) {
|
||||
message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
|
||||
mXmppConnectionService.updateMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void finish() {
|
||||
message.setTransferable(null);
|
||||
mHttpConnectionManager.finishConnection(this);
|
||||
|
@ -140,6 +191,7 @@ public class HttpDownloadConnection implements Transferable {
|
|||
}
|
||||
mHttpConnectionManager.updateConversationUi(true);
|
||||
final boolean notifyAfterScan = notify;
|
||||
final DownloadableFile file = mXmppConnectionService.getFileBackend().getFile(message, true);
|
||||
mXmppConnectionService.getFileBackend().updateMediaScanner(file, () -> {
|
||||
if (notifyAfterScan) {
|
||||
mXmppConnectionService.getNotificationService().push(message);
|
||||
|
@ -147,6 +199,12 @@ public class HttpDownloadConnection implements Transferable {
|
|||
});
|
||||
}
|
||||
|
||||
private void decryptIfNeeded() {
|
||||
if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) {
|
||||
decryptOmemoFile();
|
||||
}
|
||||
}
|
||||
|
||||
private void changeStatus(int status) {
|
||||
this.mStatus = status;
|
||||
mHttpConnectionManager.updateConversationUi(true);
|
||||
|
@ -254,6 +312,10 @@ public class HttpDownloadConnection implements Transferable {
|
|||
retrieveFailed(e);
|
||||
return;
|
||||
}
|
||||
final Message.FileParams fileParams = message.getFileParams();
|
||||
FileBackend.updateFileParams(message, fileParams.url, size);
|
||||
message.setOob(true);
|
||||
mXmppConnectionService.databaseBackend.updateMessage(message, true);
|
||||
file.setExpectedSize(size);
|
||||
message.resetFileParams();
|
||||
if (mHttpConnectionManager.hasStoragePermission()
|
||||
|
@ -337,6 +399,7 @@ public class HttpDownloadConnection implements Transferable {
|
|||
try {
|
||||
changeStatus(STATUS_DOWNLOADING);
|
||||
download();
|
||||
decryptIfNeeded();
|
||||
updateImageBounds();
|
||||
finish();
|
||||
} catch (SSLHandshakeException e) {
|
||||
|
@ -369,12 +432,12 @@ public class HttpDownloadConnection implements Transferable {
|
|||
connection.setUseCaches(false);
|
||||
connection.setRequestProperty("User-Agent", mXmppConnectionService.getIqGenerator().getUserAgent());
|
||||
final long expected = file.getExpectedSize();
|
||||
final boolean tryResume = file.exists() && file.getKey() == null && file.getSize() > 0 && file.getSize() < expected;
|
||||
final boolean tryResume = file.exists() && file.getSize() > 0 && file.getSize() < expected;
|
||||
long resumeSize = 0;
|
||||
|
||||
if (tryResume) {
|
||||
resumeSize = file.getSize();
|
||||
Log.d(Config.LOGTAG, "http download trying resume after" + resumeSize + " of " + expected);
|
||||
Log.d(Config.LOGTAG, "http download trying resume after " + resumeSize + " of " + expected);
|
||||
connection.setRequestProperty("Range", "bytes=" + resumeSize + "-");
|
||||
}
|
||||
connection.setConnectTimeout(Config.SOCKET_TIMEOUT * 1000);
|
||||
|
@ -388,7 +451,7 @@ public class HttpDownloadConnection implements Transferable {
|
|||
Log.d(Config.LOGTAG, "server resumed");
|
||||
transmitted = file.getSize();
|
||||
updateProgress(Math.round(((double) transmitted / expected) * 100));
|
||||
os = AbstractConnectionManager.createAppendedOutputStream(file);
|
||||
os = AbstractConnectionManager.createOutputStream(file, true, false);
|
||||
if (os == null) {
|
||||
throw new FileWriterException();
|
||||
}
|
||||
|
@ -406,7 +469,7 @@ public class HttpDownloadConnection implements Transferable {
|
|||
if (!file.exists() && !file.createNewFile()) {
|
||||
throw new FileWriterException();
|
||||
}
|
||||
os = AbstractConnectionManager.createOutputStream(file);
|
||||
os = AbstractConnectionManager.createOutputStream(file, false, false);
|
||||
}
|
||||
int count;
|
||||
byte[] buffer = new byte[4096];
|
||||
|
|
|
@ -109,7 +109,7 @@ public class HttpUploadConnection implements Transferable {
|
|||
if (Config.ENCRYPT_ON_HTTP_UPLOADED
|
||||
|| message.getEncryption() == Message.ENCRYPTION_AXOLOTL
|
||||
|| message.getEncryption() == Message.ENCRYPTION_OTR) {
|
||||
this.key = new byte[48];
|
||||
this.key = new byte[Config.TWELVE_BYTE_IV ? 44 : 48];
|
||||
mXmppConnectionService.getRNG().nextBytes(this.key);
|
||||
this.file.setKeyAndIv(this.key);
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ public class PresenceParser extends AbstractParser implements
|
|||
final Jid alternate;
|
||||
if (gone != null) {
|
||||
final XmppUri xmppUri = new XmppUri(gone);
|
||||
if (xmppUri.isJidValid()) {
|
||||
if (xmppUri.isValidJid()) {
|
||||
alternate = xmppUri.getJid();
|
||||
} else {
|
||||
alternate = null;
|
||||
|
|
|
@ -3,7 +3,6 @@ package eu.siacs.conversations.persistance;
|
|||
import android.annotation.TargetApi;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
@ -74,10 +73,8 @@ public class FileBackend {
|
|||
private static final SimpleDateFormat IMAGE_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US);
|
||||
|
||||
private static final String FILE_PROVIDER = ".files";
|
||||
|
||||
private XmppConnectionService mXmppConnectionService;
|
||||
|
||||
private static final float IGNORE_PADDING = 0.15f;
|
||||
private XmppConnectionService mXmppConnectionService;
|
||||
|
||||
public FileBackend(XmppConnectionService service) {
|
||||
this.mXmppConnectionService = service;
|
||||
|
@ -158,7 +155,7 @@ public class FileBackend {
|
|||
}
|
||||
|
||||
public static String getBackupDirectory(String app) {
|
||||
return Environment.getExternalStorageDirectory().getAbsolutePath() + "/"+app+"/Backup/";
|
||||
return Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + app + "/Backup/";
|
||||
}
|
||||
|
||||
private static Bitmap rotate(Bitmap bitmap, int degree) {
|
||||
|
@ -257,31 +254,6 @@ public class FileBackend {
|
|||
return inSampleSize;
|
||||
}
|
||||
|
||||
public Bitmap getPreviewForUri(Attachment attachment, int size, boolean cacheOnly) {
|
||||
final String key = "attachment_"+attachment.getUuid().toString()+"_"+String.valueOf(size);
|
||||
final LruCache<String, Bitmap> cache = mXmppConnectionService.getBitmapCache();
|
||||
Bitmap bitmap = cache.get(key);
|
||||
if (bitmap != null || cacheOnly) {
|
||||
return bitmap;
|
||||
}
|
||||
if (attachment.getMime() != null && attachment.getMime().startsWith("video/")) {
|
||||
bitmap = cropCenterSquareVideo(attachment.getUri(), size);
|
||||
drawOverlay(bitmap, paintOverlayBlack(bitmap) ? R.drawable.play_video_black : R.drawable.play_video_white, 0.75f);
|
||||
} else {
|
||||
bitmap = cropCenterSquare(attachment.getUri(), size);
|
||||
if (bitmap != null && "image/gif".equals(attachment.getMime())) {
|
||||
Bitmap withGifOverlay = bitmap.copy(Bitmap.Config.ARGB_8888, true);
|
||||
drawOverlay(withGifOverlay, paintOverlayBlack(withGifOverlay) ? R.drawable.play_gif_black : R.drawable.play_gif_white, 1.0f);
|
||||
bitmap.recycle();
|
||||
bitmap = withGifOverlay;
|
||||
}
|
||||
}
|
||||
if (bitmap != null) {
|
||||
cache.put(key, bitmap);
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
private static Dimensions getVideoDimensions(Context context, Uri uri) throws NotAVideoFile {
|
||||
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
|
||||
try {
|
||||
|
@ -421,19 +393,6 @@ public class FileBackend {
|
|||
}
|
||||
}
|
||||
|
||||
private void createNoMedia(File diretory) {
|
||||
final File noMedia = new File(diretory, ".nomedia");
|
||||
if (!noMedia.exists()) {
|
||||
try {
|
||||
if (!noMedia.createNewFile()) {
|
||||
Log.d(Config.LOGTAG, "created nomedia file " + noMedia.getAbsolutePath());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.d(Config.LOGTAG, "could not create nomedia file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Uri getMediaUri(Context context, File file) {
|
||||
final String filePath = file.getAbsolutePath();
|
||||
final Cursor cursor;
|
||||
|
@ -455,6 +414,50 @@ public class FileBackend {
|
|||
}
|
||||
}
|
||||
|
||||
public static void updateFileParams(Message message, URL url, long size) {
|
||||
final StringBuilder body = new StringBuilder();
|
||||
body.append(url.toString()).append('|').append(size);
|
||||
message.setBody(body.toString());
|
||||
}
|
||||
|
||||
public Bitmap getPreviewForUri(Attachment attachment, int size, boolean cacheOnly) {
|
||||
final String key = "attachment_" + attachment.getUuid().toString() + "_" + String.valueOf(size);
|
||||
final LruCache<String, Bitmap> cache = mXmppConnectionService.getBitmapCache();
|
||||
Bitmap bitmap = cache.get(key);
|
||||
if (bitmap != null || cacheOnly) {
|
||||
return bitmap;
|
||||
}
|
||||
if (attachment.getMime() != null && attachment.getMime().startsWith("video/")) {
|
||||
bitmap = cropCenterSquareVideo(attachment.getUri(), size);
|
||||
drawOverlay(bitmap, paintOverlayBlack(bitmap) ? R.drawable.play_video_black : R.drawable.play_video_white, 0.75f);
|
||||
} else {
|
||||
bitmap = cropCenterSquare(attachment.getUri(), size);
|
||||
if (bitmap != null && "image/gif".equals(attachment.getMime())) {
|
||||
Bitmap withGifOverlay = bitmap.copy(Bitmap.Config.ARGB_8888, true);
|
||||
drawOverlay(withGifOverlay, paintOverlayBlack(withGifOverlay) ? R.drawable.play_gif_black : R.drawable.play_gif_white, 1.0f);
|
||||
bitmap.recycle();
|
||||
bitmap = withGifOverlay;
|
||||
}
|
||||
}
|
||||
if (bitmap != null) {
|
||||
cache.put(key, bitmap);
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
private void createNoMedia(File diretory) {
|
||||
final File noMedia = new File(diretory, ".nomedia");
|
||||
if (!noMedia.exists()) {
|
||||
try {
|
||||
if (!noMedia.createNewFile()) {
|
||||
Log.d(Config.LOGTAG, "created nomedia file " + noMedia.getAbsolutePath());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.d(Config.LOGTAG, "could not create nomedia file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateMediaScanner(File file) {
|
||||
updateMediaScanner(file, null);
|
||||
}
|
||||
|
@ -472,7 +475,7 @@ public class FileBackend {
|
|||
if (callback != null && file.getAbsolutePath().equals(path)) {
|
||||
callback.run();
|
||||
} else {
|
||||
Log.d(Config.LOGTAG,"media scanner scanned wrong file");
|
||||
Log.d(Config.LOGTAG, "media scanner scanned wrong file");
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
|
@ -506,7 +509,7 @@ public class FileBackend {
|
|||
}
|
||||
|
||||
public DownloadableFile getFileForPath(String path) {
|
||||
return getFileForPath(path,MimeUtils.guessMimeTypeFromExtension(MimeUtils.extractRelevantExtension(path)));
|
||||
return getFileForPath(path, MimeUtils.guessMimeTypeFromExtension(MimeUtils.extractRelevantExtension(path)));
|
||||
}
|
||||
|
||||
public DownloadableFile getFileForPath(String path, String mime) {
|
||||
|
@ -548,7 +551,7 @@ public class FileBackend {
|
|||
|
||||
public List<Attachment> convertToAttachments(List<DatabaseBackend.FilePath> relativeFilePaths) {
|
||||
List<Attachment> attachments = new ArrayList<>();
|
||||
for(DatabaseBackend.FilePath relativeFilePath : relativeFilePaths) {
|
||||
for (DatabaseBackend.FilePath relativeFilePath : relativeFilePaths) {
|
||||
final String mime = MimeUtils.guessMimeTypeFromExtension(MimeUtils.extractRelevantExtension(relativeFilePath.path));
|
||||
final File file = getFileForPath(relativeFilePath.path, mime);
|
||||
attachments.add(Attachment.of(relativeFilePath.uuid, file, mime));
|
||||
|
@ -988,7 +991,7 @@ public class FileBackend {
|
|||
avatar.height = bitmap.getHeight();
|
||||
return avatar;
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.d(Config.LOGTAG,"unable to convert avatar to base64 due to low memory");
|
||||
Log.d(Config.LOGTAG, "unable to convert avatar to base64 due to low memory");
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
|
@ -1116,7 +1119,7 @@ public class FileBackend {
|
|||
return cropCenterSquare(input, size);
|
||||
}
|
||||
} catch (FileNotFoundException | SecurityException e) {
|
||||
Log.d(Config.LOGTAG,"unable to open file "+image.toString(), e);
|
||||
Log.d(Config.LOGTAG, "unable to open file " + image.toString(), e);
|
||||
return null;
|
||||
} finally {
|
||||
close(is);
|
||||
|
@ -1228,7 +1231,6 @@ public class FileBackend {
|
|||
message.setType(privateMessage ? Message.TYPE_PRIVATE_FILE : (image ? Message.TYPE_IMAGE : Message.TYPE_FILE));
|
||||
}
|
||||
|
||||
|
||||
private int getMediaRuntime(File file) {
|
||||
try {
|
||||
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
|
||||
|
|
|
@ -53,20 +53,11 @@ public class AbstractConnectionManager {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static OutputStream createAppendedOutputStream(DownloadableFile file) {
|
||||
return createOutputStream(file, true);
|
||||
}
|
||||
|
||||
public static OutputStream createOutputStream(DownloadableFile file) {
|
||||
return createOutputStream(file, false);
|
||||
}
|
||||
|
||||
private static OutputStream createOutputStream(DownloadableFile file, boolean append) {
|
||||
public static OutputStream createOutputStream(DownloadableFile file, boolean append, boolean decrypt) {
|
||||
FileOutputStream os;
|
||||
try {
|
||||
os = new FileOutputStream(file, append);
|
||||
if (file.getKey() == null) {
|
||||
if (file.getKey() == null || !decrypt) {
|
||||
return os;
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
|
|
|
@ -58,6 +58,8 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
|
|||
private static final String PREFIX_ACCOUNT = "account";
|
||||
private static final String PREFIX_GENERIC = "generic";
|
||||
|
||||
private static final String CHANNEL_SYMBOL = "#";
|
||||
|
||||
final private ArrayList<Integer> sizes = new ArrayList<>();
|
||||
final private HashMap<String, Set<String>> conversationDependentKeys = new HashMap<>();
|
||||
|
||||
|
@ -95,7 +97,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
|
|||
if (conversation != null) {
|
||||
return get(conversation,size,cacheOnly);
|
||||
}
|
||||
return get(result.getName(), room != null ? room.asBareJid().toEscapedString() : result.getName(), size, cacheOnly);
|
||||
return get(CHANNEL_SYMBOL, room != null ? room.asBareJid().toEscapedString() : result.getName(), size, cacheOnly);
|
||||
}
|
||||
|
||||
private Bitmap get(final Contact contact, final int size, boolean cachedOnly) {
|
||||
|
@ -339,12 +341,16 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
|
|||
bitmap = mXmppConnectionService.getFileBackend().getAvatar(mucOptions.getAvatar(), size);
|
||||
|
||||
if (bitmap == null) {
|
||||
final List<MucOptions.User> users = mucOptions.getUsersRelevantForNameAndAvatar();
|
||||
if (users.size() == 0) {
|
||||
Conversation c = mucOptions.getConversation();
|
||||
bitmap = getImpl(c.getName().toString(), c.getJid().asBareJid().toString(), size);
|
||||
Conversation c = mucOptions.getConversation();
|
||||
if (mucOptions.isPrivateAndNonAnonymous()) {
|
||||
final List<MucOptions.User> users = mucOptions.getUsersRelevantForNameAndAvatar();
|
||||
if (users.size() == 0) {
|
||||
bitmap = getImpl(c.getName().toString(), c.getJid().asBareJid().toString(), size);
|
||||
} else {
|
||||
bitmap = getImpl(users, size);
|
||||
}
|
||||
} else {
|
||||
bitmap = getImpl(users, size);
|
||||
bitmap = getImpl(CHANNEL_SYMBOL, c.getJid().asBareJid().toString(), size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -628,7 +634,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
|
|||
|
||||
private static boolean drawTile(Canvas canvas, String name, String seed, int left, int top, int right, int bottom) {
|
||||
if (name != null) {
|
||||
final String letter = getFirstLetter(name);
|
||||
final String letter = name.equals(CHANNEL_SYMBOL) ? name : getFirstLetter(name);
|
||||
final int color = UIHelper.getColorForName(seed == null ? name : seed);
|
||||
drawTile(canvas, letter, color, left, top, right, bottom);
|
||||
return true;
|
||||
|
|
|
@ -348,7 +348,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
|
|||
if (activityResult.resultCode == RESULT_OK && activityResult.requestCode == ScanActivity.REQUEST_SCAN_QR_CODE) {
|
||||
String result = activityResult.data.getStringExtra(ScanActivity.INTENT_EXTRA_RESULT);
|
||||
XmppUri uri = new XmppUri(result == null ? "" : result);
|
||||
if (uri.isJidValid()) {
|
||||
if (uri.isValidJid()) {
|
||||
showEnterJidDialog(uri);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -551,6 +551,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
|||
this.mUserPreviewAdapter.submitList(MucOptions.sub(users, GridManager.getCurrentColumnCount(binding.users)));
|
||||
this.binding.invite.setVisibility(mucOptions.canInvite() ? View.VISIBLE : View.GONE);
|
||||
this.binding.showUsers.setVisibility(users.size() > 0 ? View.VISIBLE : View.GONE);
|
||||
this.binding.showUsers.setText(getResources().getQuantityString(R.plurals.view_users, users.size(), users.size()));
|
||||
this.binding.usersWrapper.setVisibility(users.size() > 0 || mucOptions.canInvite() ? View.VISIBLE : View.GONE);
|
||||
if (users.size() == 0) {
|
||||
this.binding.noUsersHints.setText(mucOptions.isPrivateAndNonAnonymous() ? R.string.no_users_hint_group_chat : R.string.no_users_hint_channel);
|
||||
|
|
|
@ -1424,8 +1424,10 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
|||
Log.d(Config.LOGTAG, "type: " + transferable.getClass().getName());
|
||||
Toast.makeText(getActivity(), R.string.not_connected_try_again, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} else if (message.treatAsDownloadable() || message.hasFileOnRemoteHost()) {
|
||||
} else if (message.treatAsDownloadable() || message.hasFileOnRemoteHost() || MessageUtils.unInitiatedButKnownSize(message)) {
|
||||
createNewConnection(message);
|
||||
} else {
|
||||
Log.d(Config.LOGTAG,message.getConversation().getAccount()+": unable to start downloadable");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,12 +41,10 @@ import android.content.Intent;
|
|||
import android.content.pm.PackageManager;
|
||||
import android.databinding.DataBindingUtil;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.IdRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
|
@ -73,7 +71,6 @@ import eu.siacs.conversations.ui.interfaces.OnConversationArchived;
|
|||
import eu.siacs.conversations.ui.interfaces.OnConversationRead;
|
||||
import eu.siacs.conversations.ui.interfaces.OnConversationSelected;
|
||||
import eu.siacs.conversations.ui.interfaces.OnConversationsListItemUpdated;
|
||||
import eu.siacs.conversations.ui.service.EmojiService;
|
||||
import eu.siacs.conversations.ui.util.ActivityResult;
|
||||
import eu.siacs.conversations.ui.util.ConversationMenuConfigurator;
|
||||
import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
|
||||
|
@ -277,7 +274,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
UriHandlerActivity.onRequestPermissionResult(this, requestCode, grantResults);
|
||||
if (grantResults.length > 0) {
|
||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
|
@ -460,7 +457,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
|||
|
||||
public boolean onXmppUriClicked(Uri uri) {
|
||||
XmppUri xmppUri = new XmppUri(uri);
|
||||
if (xmppUri.isJidValid() && !xmppUri.hasFingerprints()) {
|
||||
if (xmppUri.isValidJid() && !xmppUri.hasFingerprints()) {
|
||||
final Conversation conversation = xmppConnectionService.findUniqueConversationByJid(xmppUri);
|
||||
if (conversation != null) {
|
||||
openConversation(conversation, null);
|
||||
|
|
|
@ -403,8 +403,26 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
|||
xmppConnectionService.deleteAccount(mAccount);
|
||||
}
|
||||
|
||||
final boolean magicCreate = mAccount != null && mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE) && !mAccount.isOptionSet(Account.OPTION_LOGGED_IN_SUCCESSFULLY);
|
||||
final Jid jid = mAccount == null ? null : mAccount.getJid();
|
||||
|
||||
if (SignupUtils.isSupportTokenRegistry() && jid != null && magicCreate && !jid.getDomain().equals(Config.MAGIC_CREATE_DOMAIN)) {
|
||||
final Jid preset;
|
||||
if (mAccount.isOptionSet(Account.OPTION_FIXED_USERNAME)) {
|
||||
preset = jid.asBareJid();
|
||||
} else {
|
||||
preset = Jid.ofDomain(jid.getDomain());
|
||||
}
|
||||
final Intent intent = SignupUtils.getTokenRegistrationIntent(this, preset, mAccount.getKey(Account.PRE_AUTH_REGISTRATION_TOKEN));
|
||||
StartConversationActivity.addInviteUri(intent, getIntent());
|
||||
startActivity(intent);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (xmppConnectionService.getAccounts().size() == 0 && Config.MAGIC_CREATE_DOMAIN != null) {
|
||||
Intent intent = SignupUtils.getSignUpIntent(this, mForceRegister != null && mForceRegister);
|
||||
StartConversationActivity.addInviteUri(intent, getIntent());
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
@ -425,6 +443,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
|||
if (wasFirstAccount) {
|
||||
intent.putExtra("init", true);
|
||||
}
|
||||
intent.putExtra(EXTRA_ACCOUNT, mAccount.getJid().asBareJid().toEscapedString());
|
||||
} else {
|
||||
intent = new Intent(getApplicationContext(), PublishProfilePictureActivity.class);
|
||||
intent.putExtra(EXTRA_ACCOUNT, mAccount.getJid().asBareJid().toString());
|
||||
|
@ -604,7 +623,6 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
|||
if (Config.DISALLOW_REGISTRATION_IN_UI) {
|
||||
this.binding.accountRegisterNew.setVisibility(View.GONE);
|
||||
}
|
||||
this.binding.yourNameBox.setVisibility(QuickConversationsService.isQuicksy() ? View.VISIBLE : View.GONE);
|
||||
this.binding.actionEditYourName.setOnClickListener(this::onEditYourNameClicked);
|
||||
}
|
||||
|
||||
|
@ -817,6 +835,9 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
|||
return false;
|
||||
}
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
deleteAccountAndReturnIfNecessary();
|
||||
break;
|
||||
case R.id.action_show_block_list:
|
||||
final Intent showBlocklistIntent = new Intent(this, BlocklistActivity.class);
|
||||
showBlocklistIntent.putExtra(EXTRA_ACCOUNT, mAccount.getJid().toString());
|
||||
|
@ -959,7 +980,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
|||
|
||||
}
|
||||
|
||||
final boolean editable = !mAccount.isOptionSet(Account.OPTION_LOGGED_IN_SUCCESSFULLY) && QuickConversationsService.isConversations();
|
||||
final boolean editable = !mAccount.isOptionSet(Account.OPTION_LOGGED_IN_SUCCESSFULLY) && !mAccount.isOptionSet(Account.OPTION_FIXED_USERNAME) && QuickConversationsService.isConversations();
|
||||
this.binding.accountJid.setEnabled(editable);
|
||||
this.binding.accountJid.setFocusable(editable);
|
||||
this.binding.accountJid.setFocusableInTouchMode(editable);
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
|
|||
import org.osmdroid.util.GeoPoint;
|
||||
import org.osmdroid.views.CustomZoomButtonsController;
|
||||
import org.osmdroid.views.MapView;
|
||||
import org.osmdroid.views.overlay.CopyrightOverlay;
|
||||
import org.osmdroid.views.overlay.Overlay;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -130,6 +131,7 @@ public abstract class LocationActivity extends ActionBarActivity implements Loca
|
|||
|
||||
protected void setupMapView(MapView mapView, final GeoPoint pos) {
|
||||
map = mapView;
|
||||
map.getOverlays().add(new CopyrightOverlay(this));
|
||||
map.setTileSource(TileSourceFactory.MAPNIK);
|
||||
map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
|
||||
map.setMultiTouchControls(true);
|
||||
|
|
|
@ -55,6 +55,7 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
|
|||
Intent intent = new Intent(getApplicationContext(), StartConversationActivity.class);
|
||||
StartConversationActivity.addInviteUri(intent, getIntent());
|
||||
intent.putExtra("init", true);
|
||||
intent.putExtra(EXTRA_ACCOUNT, account.getJid().asBareJid().toEscapedString());
|
||||
startActivity(intent);
|
||||
}
|
||||
Toast.makeText(PublishProfilePictureActivity.this,
|
||||
|
@ -95,11 +96,12 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
|
|||
});
|
||||
this.cancelButton.setOnClickListener(v -> {
|
||||
if (mInitialAccountSetup) {
|
||||
Intent intent = new Intent(getApplicationContext(), StartConversationActivity.class);
|
||||
final Intent intent = new Intent(getApplicationContext(), StartConversationActivity.class);
|
||||
if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) {
|
||||
StartConversationActivity.addInviteUri(intent, getIntent());
|
||||
intent.putExtra("init", true);
|
||||
}
|
||||
StartConversationActivity.addInviteUri(intent, getIntent());
|
||||
intent.putExtra(EXTRA_ACCOUNT, account.getJid().asBareJid().toEscapedString());
|
||||
startActivity(intent);
|
||||
}
|
||||
finish();
|
||||
|
|
|
@ -499,7 +499,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
|||
getString(R.string.add_contact),
|
||||
getString(R.string.add),
|
||||
prefilledJid,
|
||||
null,
|
||||
invite == null ? null : invite.account,
|
||||
invite == null || !invite.hasFingerprints(),
|
||||
true
|
||||
);
|
||||
|
@ -821,8 +821,9 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
|||
protected boolean processViewIntent(@NonNull Intent intent) {
|
||||
final String inviteUri = intent.getStringExtra(EXTRA_INVITE_URI);
|
||||
if (inviteUri != null) {
|
||||
Invite invite = new Invite(inviteUri);
|
||||
if (invite.isJidValid()) {
|
||||
final Invite invite = new Invite(inviteUri);
|
||||
invite.account = intent.getStringExtra(EXTRA_ACCOUNT);
|
||||
if (invite.isValidJid()) {
|
||||
return invite.invite();
|
||||
}
|
||||
}
|
||||
|
@ -836,7 +837,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
|||
Uri uri = intent.getData();
|
||||
if (uri != null) {
|
||||
Invite invite = new Invite(intent.getData(), intent.getBooleanExtra("scanned", false));
|
||||
invite.account = intent.getStringExtra("account");
|
||||
invite.account = intent.getStringExtra(EXTRA_ACCOUNT);
|
||||
invite.forceDialog = intent.getBooleanExtra("force_dialog", false);
|
||||
return invite.invite();
|
||||
} else {
|
||||
|
@ -1019,7 +1020,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
|||
conferenceJid = Jid.of(input);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
final XmppUri xmppUri = new XmppUri(input);
|
||||
if (xmppUri.isJidValid() && xmppUri.isAction(XmppUri.ACTION_JOIN)) {
|
||||
if (xmppUri.isValidJid() && xmppUri.isAction(XmppUri.ACTION_JOIN)) {
|
||||
final Editable editable = jid.getEditableText();
|
||||
editable.clear();
|
||||
editable.append(xmppUri.getJid().toEscapedString());
|
||||
|
@ -1279,7 +1280,8 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
|||
|
||||
public static void addInviteUri(Intent to, Intent from) {
|
||||
if (from != null && from.hasExtra(EXTRA_INVITE_URI)) {
|
||||
to.putExtra(EXTRA_INVITE_URI, from.getStringExtra(EXTRA_INVITE_URI));
|
||||
final String invite = from.getStringExtra(EXTRA_INVITE_URI);
|
||||
to.putExtra(EXTRA_INVITE_URI, invite);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1287,22 +1289,19 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
|||
|
||||
public String account;
|
||||
|
||||
public boolean forceDialog = false;
|
||||
boolean forceDialog = false;
|
||||
|
||||
public Invite(final Uri uri) {
|
||||
|
||||
Invite(final String uri) {
|
||||
super(uri);
|
||||
}
|
||||
|
||||
public Invite(final String uri) {
|
||||
super(uri);
|
||||
}
|
||||
|
||||
public Invite(Uri uri, boolean safeSource) {
|
||||
Invite(Uri uri, boolean safeSource) {
|
||||
super(uri, safeSource);
|
||||
}
|
||||
|
||||
boolean invite() {
|
||||
if (!isJidValid()) {
|
||||
if (!isValidJid()) {
|
||||
Toast.makeText(StartConversationActivity.this, R.string.invalid_jid, Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public class UriHandlerActivity extends AppCompatActivity {
|
|||
public static final String ACTION_SCAN_QR_CODE = "scan_qr_code";
|
||||
private static final int REQUEST_SCAN_QR_CODE = 0x1234;
|
||||
private static final int REQUEST_CAMERA_PERMISSIONS_TO_SCAN = 0x6789;
|
||||
|
||||
private static final Pattern VCARD_XMPP_PATTERN = Pattern.compile("\nIMPP([^:]*):(xmpp:.+)\n");
|
||||
private boolean handled = false;
|
||||
|
||||
public static void scan(Activity activity) {
|
||||
|
@ -87,8 +87,28 @@ public class UriHandlerActivity extends AppCompatActivity {
|
|||
final XmppUri xmppUri = new XmppUri(uri);
|
||||
final List<Jid> accounts = DatabaseBackend.getInstance(this).getAccountJids(true);
|
||||
|
||||
if (SignupUtils.isSupportTokenRegistry() && xmppUri.isValidJid()) {
|
||||
final String preauth = xmppUri.getParamater("preauth");
|
||||
final Jid jid = xmppUri.getJid();
|
||||
if (xmppUri.isAction(XmppUri.ACTION_REGISTER)) {
|
||||
if (jid.getEscapedLocal() != null && accounts.contains(jid.asBareJid())) {
|
||||
Toast.makeText(this, R.string.account_already_exists, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
intent = SignupUtils.getTokenRegistrationIntent(this, jid, preauth);
|
||||
startActivity(intent);
|
||||
return;
|
||||
}
|
||||
if (xmppUri.isAction(XmppUri.ACTION_ROSTER) && "y".equals(xmppUri.getParamater("ibr"))) {
|
||||
intent = SignupUtils.getTokenRegistrationIntent(this, Jid.ofDomain(jid.getDomain()), preauth);
|
||||
intent.putExtra(StartConversationActivity.EXTRA_INVITE_URI, xmppUri.toString());
|
||||
startActivity(intent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (accounts.size() == 0) {
|
||||
if (xmppUri.isJidValid()) {
|
||||
if (xmppUri.isValidJid()) {
|
||||
intent = SignupUtils.getSignUpIntent(this);
|
||||
intent.putExtra(StartConversationActivity.EXTRA_INVITE_URI, xmppUri.toString());
|
||||
startActivity(intent);
|
||||
|
@ -135,7 +155,7 @@ public class UriHandlerActivity extends AppCompatActivity {
|
|||
intent.putExtra("jid", xmppUri.getJid().asBareJid().toString());
|
||||
intent.setData(uri);
|
||||
intent.putExtra("scanned", scanned);
|
||||
} else if (xmppUri.isJidValid()) {
|
||||
} else if (xmppUri.isValidJid()) {
|
||||
intent = new Intent(getApplicationContext(), StartConversationActivity.class);
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
|
@ -174,8 +194,6 @@ public class UriHandlerActivity extends AppCompatActivity {
|
|||
finish();
|
||||
}
|
||||
|
||||
private static final Pattern VCARD_XMPP_PATTERN = Pattern.compile("\nIMPP([^:]*):(xmpp:.+)\n");
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
super.onActivityResult(requestCode, requestCode, intent);
|
||||
|
|
|
@ -70,6 +70,7 @@ import eu.siacs.conversations.utils.CryptoHelper;
|
|||
import eu.siacs.conversations.utils.EmojiWrapper;
|
||||
import eu.siacs.conversations.utils.Emoticons;
|
||||
import eu.siacs.conversations.utils.GeoHelper;
|
||||
import eu.siacs.conversations.utils.MessageUtils;
|
||||
import eu.siacs.conversations.utils.StylingHelper;
|
||||
import eu.siacs.conversations.utils.UIHelper;
|
||||
import eu.siacs.conversations.xmpp.mam.MamReference;
|
||||
|
@ -183,7 +184,7 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
|
|||
final Transferable transferable = message.getTransferable();
|
||||
boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI
|
||||
&& message.getMergedStatus() <= Message.STATUS_RECEIVED;
|
||||
if (message.isFileOrImage() || transferable != null) {
|
||||
if (message.isFileOrImage() || transferable != null || MessageUtils.unInitiatedButKnownSize(message)) {
|
||||
FileParams params = message.getFileParams();
|
||||
filesize = params.size > 0 ? UIHelper.filesizeToString(params.size) : null;
|
||||
if (transferable != null && (transferable.getStatus() == Transferable.STATUS_FAILED || transferable.getStatus() == Transferable.STATUS_CANCELLED)) {
|
||||
|
@ -206,6 +207,8 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
|
|||
break;
|
||||
case Message.STATUS_SEND_RECEIVED:
|
||||
case Message.STATUS_SEND_DISPLAYED:
|
||||
viewHolder.indicatorReceived.setImageResource(darkBackground ? R.drawable.ic_done_white_18dp : R.drawable.ic_done_black_18dp);
|
||||
viewHolder.indicatorReceived.setAlpha(darkBackground ? 0.7f : 0.57f);
|
||||
viewHolder.indicatorReceived.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
case Message.STATUS_SEND_FAILED:
|
||||
|
@ -732,8 +735,9 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
|
|||
});
|
||||
|
||||
final Transferable transferable = message.getTransferable();
|
||||
if (message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) {
|
||||
if (transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER) {
|
||||
final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(message);
|
||||
if (unInitiatedButKnownSize || message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) {
|
||||
if (unInitiatedButKnownSize || transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER) {
|
||||
displayDownloadableMessage(viewHolder, message, activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message)), darkBackground);
|
||||
} else if (transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER_CHECK_FILESIZE) {
|
||||
displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message)), darkBackground);
|
||||
|
|
|
@ -91,7 +91,7 @@ public class MyLinkify {
|
|||
|
||||
private static final Linkify.MatchFilter XMPPURI_MATCH_FILTER = (s, start, end) -> {
|
||||
XmppUri uri = new XmppUri(s.subSequence(start, end).toString());
|
||||
return uri.isJidValid();
|
||||
return uri.isValidJid();
|
||||
};
|
||||
|
||||
private static boolean isAlphabetic(final int code) {
|
||||
|
|
|
@ -132,7 +132,7 @@ public class ShareUtil {
|
|||
Matcher xmppPatternMatcher = Patterns.XMPP_PATTERN.matcher(body);
|
||||
if (xmppPatternMatcher.find()) {
|
||||
try {
|
||||
return new XmppUri(body.substring(xmppPatternMatcher.start(), xmppPatternMatcher.end())).isJidValid();
|
||||
return new XmppUri(body.substring(xmppPatternMatcher.start(), xmppPatternMatcher.end())).isValidJid();
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -125,9 +125,13 @@ public class GeoHelper {
|
|||
}
|
||||
|
||||
public static boolean openInOsmAnd(Context context, Message message) {
|
||||
final GeoPoint geoPoint = parseGeoPoint(message.getBody());
|
||||
final String label = getLabel(context, message);
|
||||
return geoIntent(geoPoint,label).resolveActivity(context.getPackageManager()) != null;
|
||||
try {
|
||||
final GeoPoint geoPoint = parseGeoPoint(message.getBody());
|
||||
final String label = getLabel(context, message);
|
||||
return geoIntent(geoPoint, label).resolveActivity(context.getPackageManager()) != null;
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getLabel(Context context, Message message) {
|
||||
|
|
|
@ -91,4 +91,8 @@ public class MessageUtils {
|
|||
public static String filterLtrRtl(String body) {
|
||||
return LTR_RTL.matcher(body).replaceFirst(EMPTY_STRING);
|
||||
}
|
||||
|
||||
public static boolean unInitiatedButKnownSize(Message message) {
|
||||
return message.getType() == Message.TYPE_TEXT && message.getTransferable() == null && message.isOOb() && message.getFileParams().size > 0 && message.getFileParams().url != null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package eu.siacs.conversations.utils;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -268,6 +269,7 @@ public final class MimeUtils {
|
|||
add("image/ico", "cur");
|
||||
add("image/ico", "ico");
|
||||
add("image/ief", "ief");
|
||||
add("image/heic","heic");
|
||||
// add ".jpg" first so it will be the default for guessExtensionFromMimeType
|
||||
add("image/jpeg", "jpg");
|
||||
add("image/jpeg", "jpeg");
|
||||
|
|
|
@ -306,7 +306,7 @@ public class UIHelper {
|
|||
UIHelper.getMessageDisplayName(message) + " "), false);
|
||||
} else if (message.isGeoUri()) {
|
||||
return new Pair<>(context.getString(R.string.location), true);
|
||||
} else if (message.treatAsDownloadable()) {
|
||||
} else if (message.treatAsDownloadable() || MessageUtils.unInitiatedButKnownSize(message)) {
|
||||
return new Pair<>(context.getString(R.string.x_file_offered_for_download,
|
||||
getFileDescriptionString(context, message)), true);
|
||||
} else {
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
package eu.siacs.conversations.utils;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import rocks.xmpp.addr.Jid;
|
||||
|
||||
public class XmppUri {
|
||||
|
@ -17,15 +21,15 @@ public class XmppUri {
|
|||
protected Uri uri;
|
||||
protected String jid;
|
||||
private List<Fingerprint> fingerprints = new ArrayList<>();
|
||||
private String body;
|
||||
private String name;
|
||||
private String action;
|
||||
private Map<String,String> parameters = Collections.emptyMap();
|
||||
private boolean safeSource = true;
|
||||
|
||||
private static final String OMEMO_URI_PARAM = "omemo-sid-";
|
||||
|
||||
public static final String ACTION_JOIN = "join";
|
||||
public static final String ACTION_MESSAGE = "message";
|
||||
public static final String ACTION_REGISTER = "register";
|
||||
public static final String ACTION_ROSTER = "roster";
|
||||
|
||||
public XmppUri(String uri) {
|
||||
try {
|
||||
|
@ -66,7 +70,6 @@ public class XmppUri {
|
|||
try {
|
||||
jid = Jid.of(lameUrlDecode(segments.get(1))).toString();
|
||||
} catch (Exception e) {
|
||||
Log.d(Config.LOGTAG, "parsing failed ", e);
|
||||
jid = null;
|
||||
}
|
||||
} else if (segments.size() >= 3) {
|
||||
|
@ -74,33 +77,24 @@ public class XmppUri {
|
|||
jid = segments.get(1) + "@" + segments.get(2);
|
||||
}
|
||||
if (segments.size() > 1 && "j".equalsIgnoreCase(segments.get(0))) {
|
||||
action = ACTION_JOIN;
|
||||
this.parameters = ImmutableMap.of(ACTION_JOIN, "");
|
||||
}
|
||||
fingerprints = parseFingerprints(uri.getQuery(), '&');
|
||||
final Map<String,String> parameters = parseParameters(uri.getQuery(), '&');
|
||||
this.fingerprints = parseFingerprints(parameters);
|
||||
} else if ("xmpp".equalsIgnoreCase(scheme)) {
|
||||
// sample: xmpp:foo@bar.com
|
||||
|
||||
final String query = uri.getQuery();
|
||||
|
||||
if (hasAction(query, ACTION_JOIN)) {
|
||||
this.action = ACTION_JOIN;
|
||||
} else if (hasAction(query, ACTION_MESSAGE)) {
|
||||
this.action = ACTION_MESSAGE;
|
||||
}
|
||||
|
||||
this.parameters = parseParameters(uri.getQuery(), ';');
|
||||
if (uri.getAuthority() != null) {
|
||||
jid = uri.getAuthority();
|
||||
} else {
|
||||
String[] parts = uri.getSchemeSpecificPart().split("\\?");
|
||||
final String[] parts = uri.getSchemeSpecificPart().split("\\?");
|
||||
if (parts.length > 0) {
|
||||
jid = parts[0];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.fingerprints = parseFingerprints(uri.getQuery());
|
||||
this.body = parseParameter("body", uri.getQuery());
|
||||
this.name = parseParameter("name", uri.getQuery());
|
||||
this.fingerprints = parseFingerprints(parameters);
|
||||
} else if ("imto".equalsIgnoreCase(scheme)) {
|
||||
// sample: imto://xmpp/foo@bar.com
|
||||
try {
|
||||
|
@ -117,6 +111,35 @@ public class XmppUri {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static Map<String,String> parseParameters(final String query, final char seperator) {
|
||||
final ImmutableMap.Builder<String,String> builder = new ImmutableMap.Builder<>();
|
||||
final String[] pairs = query == null ? new String[0] : query.split(String.valueOf(seperator));
|
||||
for (String pair : pairs) {
|
||||
final String[] parts = pair.split("=", 2);
|
||||
if (parts.length == 0) {
|
||||
continue;
|
||||
}
|
||||
final String key = parts[0].toLowerCase(Locale.US);
|
||||
final String value;
|
||||
if (parts.length == 2) {
|
||||
String decoded;
|
||||
try {
|
||||
decoded = URLDecoder.decode(parts[1],"UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
decoded = "";
|
||||
}
|
||||
value = decoded;
|
||||
} else {
|
||||
value = "";
|
||||
}
|
||||
builder.put(key, value);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
if (uri != null) {
|
||||
return uri.toString();
|
||||
|
@ -124,58 +147,25 @@ public class XmppUri {
|
|||
return "";
|
||||
}
|
||||
|
||||
private List<Fingerprint> parseFingerprints(String query) {
|
||||
return parseFingerprints(query, ';');
|
||||
}
|
||||
|
||||
private List<Fingerprint> parseFingerprints(String query, char seperator) {
|
||||
List<Fingerprint> fingerprints = new ArrayList<>();
|
||||
String[] pairs = query == null ? new String[0] : query.split(String.valueOf(seperator));
|
||||
for (String pair : pairs) {
|
||||
String[] parts = pair.split("=", 2);
|
||||
if (parts.length == 2) {
|
||||
String key = parts[0].toLowerCase(Locale.US);
|
||||
String value = parts[1].toLowerCase(Locale.US);
|
||||
if (key.startsWith(OMEMO_URI_PARAM)) {
|
||||
try {
|
||||
int id = Integer.parseInt(key.substring(OMEMO_URI_PARAM.length()));
|
||||
fingerprints.add(new Fingerprint(FingerprintType.OMEMO, value, id));
|
||||
} catch (Exception e) {
|
||||
//ignoring invalid device id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fingerprints;
|
||||
}
|
||||
|
||||
private String parseParameter(String key, String query) {
|
||||
for (String pair : query == null ? new String[0] : query.split(";")) {
|
||||
final String[] parts = pair.split("=", 2);
|
||||
if (parts.length == 2 && key.equals(parts[0].toLowerCase(Locale.US))) {
|
||||
private static List<Fingerprint> parseFingerprints(Map<String,String> parameters) {
|
||||
ImmutableList.Builder<Fingerprint> builder = new ImmutableList.Builder<>();
|
||||
for (Map.Entry<String, String> parameter : parameters.entrySet()) {
|
||||
final String key = parameter.getKey();
|
||||
final String value = parameter.getValue().toLowerCase(Locale.US);
|
||||
if (key.startsWith(OMEMO_URI_PARAM)) {
|
||||
try {
|
||||
return URLDecoder.decode(parts[1], "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return null;
|
||||
final int id = Integer.parseInt(key.substring(OMEMO_URI_PARAM.length()));
|
||||
builder.add(new Fingerprint(FingerprintType.OMEMO, value, id));
|
||||
} catch (Exception e) {
|
||||
//ignoring invalid device id
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean hasAction(String query, String action) {
|
||||
for (String pair : query == null ? new String[0] : query.split(";")) {
|
||||
final String[] parts = pair.split("=", 2);
|
||||
if (parts.length == 1 && parts[0].toLowerCase(Locale.US).startsWith(action)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public boolean isAction(final String action) {
|
||||
return this.action != null && this.action.equals(action);
|
||||
|
||||
return parameters.containsKey(action);
|
||||
}
|
||||
|
||||
public Jid getJid() {
|
||||
|
@ -186,7 +176,7 @@ public class XmppUri {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isJidValid() {
|
||||
public boolean isValidJid() {
|
||||
if (jid == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -199,11 +189,15 @@ public class XmppUri {
|
|||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
return parameters.get("body");
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
return parameters.get("name");
|
||||
}
|
||||
|
||||
public String getParamater(String key) {
|
||||
return this.parameters.get(key);
|
||||
}
|
||||
|
||||
public List<Fingerprint> getFingerprints() {
|
||||
|
@ -218,7 +212,7 @@ public class XmppUri {
|
|||
OMEMO
|
||||
}
|
||||
|
||||
public static String getFingerprintUri(String base, List<XmppUri.Fingerprint> fingerprints, char seperator) {
|
||||
public static String getFingerprintUri(String base, List<XmppUri.Fingerprint> fingerprints, char separator) {
|
||||
StringBuilder builder = new StringBuilder(base);
|
||||
builder.append('?');
|
||||
for (int i = 0; i < fingerprints.size(); ++i) {
|
||||
|
@ -230,7 +224,7 @@ public class XmppUri {
|
|||
builder.append('=');
|
||||
builder.append(fingerprints.get(i).fingerprint);
|
||||
if (i != fingerprints.size() - 1) {
|
||||
builder.append(seperator);
|
||||
builder.append(separator);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
|
@ -247,9 +241,10 @@ public class XmppUri {
|
|||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return type.toString() + ": " + fingerprint + (deviceId != 0 ? " " + String.valueOf(deviceId) : "");
|
||||
return type.toString() + ": " + fingerprint + (deviceId != 0 ? " " + deviceId : "");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,4 +37,6 @@ public final class Namespace {
|
|||
public static final String MUC_USER = "http://jabber.org/protocol/muc#user";
|
||||
public static final String BOOKMARKS2 = "urn:xmpp:bookmarks:0";
|
||||
public static final String BOOKMARKS2_COMPAT = BOOKMARKS2+"#compat";
|
||||
public static final String INVITE = "urn:xmpp:invite";
|
||||
public static final String PARS = "urn:xmpp:pars:0";
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@ public class XmppConnection implements Runnable {
|
|||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
||||
if (packet.getType() == IqPacket.TYPE.RESULT) {
|
||||
account.setOption(Account.OPTION_REGISTER, false);
|
||||
Log.d(Config.LOGTAG, account.getJid().asBareJid()+": successfully registered new account on server");
|
||||
throw new StateChangingError(Account.State.REGISTRATION_SUCCESSFUL);
|
||||
} else {
|
||||
final List<String> PASSWORD_TOO_WEAK_MSGS = Arrays.asList(
|
||||
|
@ -806,7 +807,7 @@ public class XmppConnection implements Runnable {
|
|||
sendStartTLS();
|
||||
} else if (this.streamFeatures.hasChild("register") && account.isOptionSet(Account.OPTION_REGISTER)) {
|
||||
if (isSecure) {
|
||||
sendRegistryRequest();
|
||||
register();
|
||||
} else {
|
||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": unable to find STARTTLS for registration process "+ XmlHelper.printElementNames(this.streamFeatures));
|
||||
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
|
||||
|
@ -880,6 +881,26 @@ public class XmppConnection implements Runnable {
|
|||
return mechanisms;
|
||||
}
|
||||
|
||||
|
||||
private void register() {
|
||||
final String preAuth = account.getKey(Account.PRE_AUTH_REGISTRATION_TOKEN);
|
||||
if (preAuth != null && features.invite()) {
|
||||
final IqPacket preAuthRequest = new IqPacket(IqPacket.TYPE.SET);
|
||||
preAuthRequest.addChild("preauth", Namespace.PARS).setAttribute("token", preAuth);
|
||||
sendUnmodifiedIqPacket(preAuthRequest, (account, response) -> {
|
||||
if (response.getType() == IqPacket.TYPE.RESULT) {
|
||||
sendRegistryRequest();
|
||||
} else {
|
||||
final Element error = response.getError();
|
||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": failed to pre auth. "+error);
|
||||
throw new StateChangingError(Account.State.REGISTRATION_INVALID_TOKEN);
|
||||
}
|
||||
}, true);
|
||||
} else {
|
||||
sendRegistryRequest();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendRegistryRequest() {
|
||||
final IqPacket register = new IqPacket(IqPacket.TYPE.GET);
|
||||
register.query(Namespace.REGISTER);
|
||||
|
@ -1744,6 +1765,10 @@ public class XmppConnection implements Runnable {
|
|||
return hasDiscoFeature(Jid.of(account.getServer()), Namespace.REGISTER);
|
||||
}
|
||||
|
||||
public boolean invite() {
|
||||
return connection.streamFeatures != null && connection.streamFeatures.hasChild("register", Namespace.INVITE);
|
||||
}
|
||||
|
||||
public boolean sm() {
|
||||
return streamId != null
|
||||
|| (connection.streamFeatures != null && connection.streamFeatures.hasChild("sm"));
|
||||
|
|
|
@ -213,7 +213,7 @@ public class JingleConnection implements Transferable {
|
|||
}
|
||||
this.file.getParentFile().mkdirs();
|
||||
this.file.createNewFile();
|
||||
this.mFileOutputStream = AbstractConnectionManager.createOutputStream(this.file);
|
||||
this.mFileOutputStream = AbstractConnectionManager.createOutputStream(this.file, false, true);
|
||||
return this.mFileOutputStream;
|
||||
}
|
||||
|
||||
|
|
After Width: | Height: | Size: 149 B |
After Width: | Height: | Size: 157 B |
Before Width: | Height: | Size: 560 B |
After Width: | Height: | Size: 138 B |
Before Width: | Height: | Size: 130 B |
After Width: | Height: | Size: 144 B |
Before Width: | Height: | Size: 402 B |
Before Width: | Height: | Size: 177 B After Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 188 B |
After Width: | Height: | Size: 188 B |
Before Width: | Height: | Size: 717 B |
After Width: | Height: | Size: 199 B |
After Width: | Height: | Size: 217 B |
Before Width: | Height: | Size: 1016 B |
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 277 B |
After Width: | Height: | Size: 255 B |
Before Width: | Height: | Size: 1.3 KiB |
|
@ -471,16 +471,11 @@
|
|||
</TableRow>
|
||||
</TableLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/your_name_box"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
android:layout_marginTop="24dp">
|
||||
android:layout_marginTop="12dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -522,7 +517,7 @@
|
|||
android:id="@+id/pgp_fingerprint_box"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="16dp">
|
||||
android:layout_marginTop="12dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -563,7 +558,7 @@
|
|||
android:id="@+id/axolotl_fingerprint_box"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="16dp">
|
||||
android:layout_marginTop="12dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -278,7 +279,7 @@
|
|||
android:minWidth="0dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:text="@string/view_users"
|
||||
tools:text="View n Participants"
|
||||
android:textColor="?attr/colorAccent" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="?attr/dialog_vertical_padding"
|
||||
android:paddingLeft="?attr/dialog_horizontal_padding"
|
||||
android:paddingTop="?attr/dialog_vertical_padding"
|
||||
android:paddingRight="?attr/dialog_horizontal_padding"
|
||||
android:paddingTop="?attr/dialog_vertical_padding">
|
||||
android:paddingBottom="?attr/dialog_vertical_padding">
|
||||
|
||||
<TextView
|
||||
style="@style/InputLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/your_account"/>
|
||||
android:text="@string/your_account" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/account"
|
||||
|
@ -35,8 +35,8 @@
|
|||
style="@style/Widget.Conversations.EditText"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textEmailAddress"
|
||||
android:imeOptions="actionDone|flagNoExtractUi"/>
|
||||
android:imeOptions="actionDone|flagNoExtractUi"
|
||||
android:inputType="textEmailAddress" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
</LinearLayout>
|
||||
</layout>
|
||||
|
|
|
@ -1,49 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="3dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingTop="3dp">
|
||||
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingTop="3dp"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingBottom="3dp">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/message_photo_box"
|
||||
android:orientation="vertical"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true">
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.makeramen.roundedimageview.RoundedImageView
|
||||
android:id="@+id/message_photo"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:scaleType="fitXY"
|
||||
app:riv_corner_radius="2dp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/placeholder"
|
||||
android:layout_height="3dp"
|
||||
android:layout_width="48dp"
|
||||
/>
|
||||
android:layout_height="3dp" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/message_box"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginLeft="-4dp"
|
||||
android:layout_toLeftOf="@+id/message_photo_box"
|
||||
android:background="?attr/message_bubble_sent"
|
||||
android:minHeight="53dp"
|
||||
android:layout_marginLeft="-4dp"
|
||||
android:longClickable="true">
|
||||
android:longClickable="true"
|
||||
android:minHeight="53dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -52,7 +51,7 @@
|
|||
android:orientation="vertical"
|
||||
android:padding="2dp">
|
||||
|
||||
<include layout="@layout/message_content"/>
|
||||
<include layout="@layout/message_content" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -66,16 +65,17 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="4sp"
|
||||
android:layout_marginRight="4sp"
|
||||
android:gravity="center_vertical"
|
||||
android:text="@string/sending"
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Caption"/>
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Caption" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/security_indicator"
|
||||
android:layout_width="?attr/TextSizeCaption"
|
||||
android:layout_height="?attr/TextSizeCaption"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="4sp"
|
||||
android:alpha="0.54"
|
||||
android:gravity="center_vertical"
|
||||
android:src="@drawable/ic_lock_black_18dp" />
|
||||
|
@ -85,20 +85,18 @@
|
|||
android:layout_width="?attr/TextSizeCaption"
|
||||
android:layout_height="?attr/TextSizeCaption"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="4sp"
|
||||
android:alpha="0.54"
|
||||
android:gravity="center_vertical"
|
||||
android:src="@drawable/ic_mode_edit_black_18dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/indicator_received"
|
||||
android:layout_width="?attr/TextSizeCaption"
|
||||
android:layout_height="?attr/TextSizeCaption"
|
||||
android:layout_width="?attr/TextSizeSubhead"
|
||||
android:layout_height="?attr/TextSizeSubhead"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="4sp"
|
||||
android:alpha="0.54"
|
||||
android:gravity="center_vertical"
|
||||
android:src="@drawable/ic_received_indicator" />
|
||||
android:src="@drawable/ic_done_black_18dp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2006 The Android Open Source Project
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2006 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -15,11 +14,12 @@
|
|||
-->
|
||||
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@android:id/text1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Body1"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall" />
|
||||
android:id="@android:id/text1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Body1"
|
||||
android:textColor="?attr/edit_text_color" />
|
||||
|
|
|
@ -655,7 +655,6 @@
|
|||
<string name="pref_more_notification_settings_summary">الأهمية ، الصوت ، الإهتزاز</string>
|
||||
<string name="video_compression_channel_name">ضغط الفيديو</string>
|
||||
<string name="view_media">اعرض الوسائط</string>
|
||||
<string name="view_users">اعرض المشارِكين</string>
|
||||
<string name="group_chat_members">المشارِكون</string>
|
||||
<string name="pref_video_compression">جودة الفيديو</string>
|
||||
<string name="video_360p">متوسط (360ب)</string>
|
||||
|
|
|
@ -155,6 +155,7 @@
|
|||
<string name="account_status_regis_conflict">Benutzername wird bereits verwendet</string>
|
||||
<string name="account_status_regis_success">Registrierung abgeschlossen</string>
|
||||
<string name="account_status_regis_not_sup">Der Server unterstützt keine Registrierung</string>
|
||||
<string name="account_status_regis_invalid_token">Ungültiger Registrierungstoken</string>
|
||||
<string name="account_status_tls_error">TLS-Aushandlung fehlgeschlagen</string>
|
||||
<string name="account_status_policy_violation">Verstoß gegen die Richtlinien</string>
|
||||
<string name="account_status_incompatible_server">Inkompatibler Server</string>
|
||||
|
@ -749,7 +750,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Wichtigkeit, Klang, Vibrationen</string>
|
||||
<string name="video_compression_channel_name">Video komprimieren</string>
|
||||
<string name="view_media">Medien anzeigen</string>
|
||||
<string name="view_users">Teilnehmer anzeigen</string>
|
||||
<string name="group_chat_members">Teilnehmer</string>
|
||||
<string name="media_browser">Medienbrowser</string>
|
||||
<string name="security_violation_not_attaching_file">Datei wurde aufgrund von Sicherheitsverletzungen ausgelassen.</string>
|
||||
|
@ -878,4 +878,8 @@
|
|||
<string name="pref_channel_discovery">Channelsuchmethode</string>
|
||||
<string name="backup">Sicherungskopie</string>
|
||||
<string name="category_about">Über</string>
|
||||
<plurals name="view_users">
|
||||
<item quantity="one">%1$d Teilnehmer anzeigen</item>
|
||||
<item quantity="other">%1$d Teilnehmer anzeigen</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
|
|
@ -745,7 +745,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Σημασία, Ήχος, Δόνηση</string>
|
||||
<string name="video_compression_channel_name">Συμπίεση βίντεο</string>
|
||||
<string name="view_media">Εμφάνιση μέσου</string>
|
||||
<string name="view_users">Εμφάνιση συμμετεχόντων</string>
|
||||
<string name="group_chat_members">Συμμετέχοντες</string>
|
||||
<string name="media_browser">Περιηγητης μέσων</string>
|
||||
<string name="security_violation_not_attaching_file">Το αρχείο παραλείπεται λόγω παραβίασης ασφάλειας.</string>
|
||||
|
|
|
@ -749,7 +749,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Importancia, Sonido, Vibración</string>
|
||||
<string name="video_compression_channel_name">Compresión de video</string>
|
||||
<string name="view_media">Ver galería</string>
|
||||
<string name="view_users">Ver participantes</string>
|
||||
<string name="group_chat_members">Participantes</string>
|
||||
<string name="media_browser">Galería</string>
|
||||
<string name="security_violation_not_attaching_file">Fichero omitido por violación de seguridad</string>
|
||||
|
@ -878,4 +877,8 @@
|
|||
<string name="pref_channel_discovery">Método para la búsqueda de Canales</string>
|
||||
<string name="backup">Copia de respaldo</string>
|
||||
<string name="category_about">Acerca de</string>
|
||||
<plurals name="view_users">
|
||||
<item quantity="one">Ver %1$d Participante</item>
|
||||
<item quantity="other">Ver %1$d Participantes</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
|
|
@ -744,7 +744,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Garrantzia, soinua, dardara</string>
|
||||
<string name="video_compression_channel_name">Bideoen konprimatzea</string>
|
||||
<string name="view_media">Ikusi multimedia</string>
|
||||
<string name="view_users">Parte-hartzaileak ikusi</string>
|
||||
<string name="group_chat_members">Parte-hartzaileak</string>
|
||||
<string name="media_browser">Multimedia nabigatzailea</string>
|
||||
<string name="security_violation_not_attaching_file">Fitxategia alde batera utzita segurtasun hauste bategatik.</string>
|
||||
|
|
|
@ -747,7 +747,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Importance, son, vibration</string>
|
||||
<string name="video_compression_channel_name">Compression vidéo</string>
|
||||
<string name="view_media">Voir les média</string>
|
||||
<string name="view_users">Voir les participants</string>
|
||||
<string name="group_chat_members">Participants</string>
|
||||
<string name="media_browser">Navigateur de média</string>
|
||||
<string name="security_violation_not_attaching_file">Fichier omis en raison d\'une violation de la sécurité.</string>
|
||||
|
|
|
@ -155,6 +155,7 @@
|
|||
<string name="account_status_regis_conflict">O identificador xa está en uso</string>
|
||||
<string name="account_status_regis_success">Rexistro completado</string>
|
||||
<string name="account_status_regis_not_sup">O servidor non soporta rexistros</string>
|
||||
<string name="account_status_regis_invalid_token">O testemuño de rexistro non é válido</string>
|
||||
<string name="account_status_tls_error">Fallo a negociación TLS</string>
|
||||
<string name="account_status_policy_violation">Violación da política</string>
|
||||
<string name="account_status_incompatible_server">Servidor incompatible</string>
|
||||
|
@ -285,7 +286,7 @@
|
|||
<string name="pref_autojoin">Sincronizar cos marcadores</string>
|
||||
<string name="pref_autojoin_summary">Unirse e deixar conversas de grupo de acordo coa marca auto-unirse nos seus marcadores.</string>
|
||||
<string name="toast_message_omemo_fingerprint">Copiouse a pegada dixital OMEMO ao portapapeis!</string>
|
||||
<string name="conference_banned">Vostede non pode acceder a esta conversa en grupo</string>
|
||||
<string name="conference_banned">Non podes acceder a esta conversa en grupo</string>
|
||||
<string name="conference_members_only">Esta conversa en grupo é so para membros</string>
|
||||
<string name="conference_resource_constraint">Restrición do recurso</string>
|
||||
<string name="conference_kicked">Xa foi expulsado de esta conversa en grupo</string>
|
||||
|
@ -387,7 +388,7 @@
|
|||
<string name="members_only">Privada, só para membros</string>
|
||||
<string name="non_anonymous">Facer os enderezos XMPP visibles para calquera</string>
|
||||
<string name="moderated">Establecer canal como moderado</string>
|
||||
<string name="you_are_not_participating">Vostede non está a participar</string>
|
||||
<string name="you_are_not_participating">Non estás a participar</string>
|
||||
<string name="modified_conference_options">¡Opcións da conversa en grupo modificadas!</string>
|
||||
<string name="could_not_modify_conference_options">Non se puideron modificar as opcións da conversa en grupo</string>
|
||||
<string name="never">Nunca</string>
|
||||
|
@ -525,7 +526,7 @@
|
|||
<string name="security_error_invalid_file_access">Fallo na seguridade: Acceso non válido ao ficheiro</string>
|
||||
<string name="no_application_to_share_uri">Non se atopou un aplicativo para compartir URI</string>
|
||||
<string name="share_uri_with">Compartir URI con...</string>
|
||||
<string name="welcome_text_quicksy"><![CDATA[Quicksy é un derivado do popular cliente XMPP Conversations con descubrimento automático de contactos.<br><br>Pode rexistrarse co seu número de teléfono e Quicksy suxeriralle automáticamente —tomando os números da súa libreta de enderezos como referencia— posibles contactos para vostede.<br><br>Ao rexistarse vostede acepta a nosa <a href="https://quicksy.im/#privacy">política de intimidade</a>.]]></string>
|
||||
<string name="welcome_text_quicksy"><![CDATA[Quicksy é un derivado do popular cliente XMPP Conversations con descubrimento automático de contactos.<br><br>Podes rexistrarte co teu número de teléfono e Quicksy suxerillache automáticamente —tomando os números da túa libreta de enderezos como referencia— posibles contactos para ti.<br><br>Ao rexistrarte aceptas a nosa <a href="https://quicksy.im/#privacy">política de intimidade</a>.]]></string>
|
||||
<string name="agree_and_continue">Aceptar & continuar</string>
|
||||
<string name="magic_create_text">Guiarémola a través do proceso de creación de unha conta en chat.sum7.eu.\nAo escoller a chat.sum7.eu como fornecedor poderá comunicar con usuarias de outros fornecedores proporcionándolles o seu enderezo XMPP completo.</string>
|
||||
<string name="your_full_jid_will_be">O seu enderezo XMPP completo será: %s</string>
|
||||
|
@ -751,7 +752,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Importancia, Son, Vibrar</string>
|
||||
<string name="video_compression_channel_name">Compresión de vídeo</string>
|
||||
<string name="view_media">Ver medios</string>
|
||||
<string name="view_users">Ver participantes</string>
|
||||
<string name="group_chat_members">Participantes</string>
|
||||
<string name="media_browser">Navegador de medios</string>
|
||||
<string name="security_violation_not_attaching_file">Ficheiro omitido debido a transgresión da seguridade.</string>
|
||||
|
@ -803,7 +803,7 @@
|
|||
<string name="the_app_is_out_of_date">Está a utilizar unha versión desactualizada de esta app.</string>
|
||||
<string name="update">Actualizar</string>
|
||||
<string name="logged_in_with_another_device">Este número de teléfono está actualmente ligado a outro dispositivo.</string>
|
||||
<string name="enter_your_name_instructions">Por favor, introduza o seu nome para permitir que a xente que non o ten na axenda de enderezos sepa quen é vostede.</string>
|
||||
<string name="enter_your_name_instructions">Por favor, escribe o teu nome para permitir que a xente que non te ten na axenda de enderezos sepa quen es.</string>
|
||||
<string name="your_name">O seu nome</string>
|
||||
<string name="enter_your_name">Introduza o seu nome</string>
|
||||
<string name="no_name_set_instructions">Utilice o botón editar para escribir o seu nome.</string>
|
||||
|
@ -880,4 +880,8 @@
|
|||
<string name="pref_channel_discovery">Método de descubrimento de canles</string>
|
||||
<string name="backup">Respaldo</string>
|
||||
<string name="category_about">Acerca de</string>
|
||||
<plurals name="view_users">
|
||||
<item quantity="one">Ver %1$d Participante</item>
|
||||
<item quantity="other">Ver %1$d Participantes</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<string name="action_unblock_participant">Résztvevő tiltásának feloldása</string>
|
||||
<string name="title_activity_manage_accounts">Fiókok kezelése</string>
|
||||
<string name="title_activity_settings">Beállítások</string>
|
||||
<string name="title_activity_sharewith">Megosztás a Conversationnel</string>
|
||||
<string name="title_activity_sharewith">Megosztás a Conversations alkalmazással</string>
|
||||
<string name="title_activity_start_conversation">Beszélgetés indítása</string>
|
||||
<string name="title_activity_choose_contact">Partner kiválasztása</string>
|
||||
<string name="title_activity_choose_contacts">Partnerek kiválasztása</string>
|
||||
|
@ -499,7 +499,7 @@
|
|||
<string name="shared_images_with_x">%s partnerrel megosztott képek</string>
|
||||
<string name="shared_text_with_x">%s partnerrel megosztott szöveg</string>
|
||||
<string name="no_storage_permission">A Conversations alkalmazásnak hozzáférésre van szüksége a külső tárolóhoz</string>
|
||||
<string name="no_camera_permission">A Conversations alkalmazásnak hozzáférésre van szüksége a kamerához</string>
|
||||
<string name="no_camera_permission">A Conversations alkalmazásnak kamera-hozzáférésre van szüksége</string>
|
||||
<string name="sync_with_contacts">Szinkronizálás a partnerekkel</string>
|
||||
<string name="sync_with_contacts_long">A Conversations szeretné megfeleltetni a kiszolgáló oldali partnerlistát a helyi címjegyzékkel, hogy megjelenítse a partnerek teljes nevét és profilképét.\n\nA Conversations csak olvassa a névjegyeit, és helyileg felelteti meg őket, anélkül hogy feltöltené azokat a kiszolgálóra.\n\nMost arra fogják kérni, hogy adjon jogosultságot a névjegyek eléréséhez.</string>
|
||||
<string name="sync_with_contacts_quicksy"><![CDATA[A Quicksy alkalmazásnak hozzáférés szükséges a partnerei telefonszámához, hogy javaslatokat tegyen a lehetséges partnerekről, akik már csatlakoztak a Quicksy-hez.<br><br>A telefonszámok másolatát nem fogjuk eltárolni.\n\nTovábbi információkért olvassa el az <a href="https://quicksy.im/#privacy">adatvédelmi irányelveinket</a>.<br><br>Most arra fogják kérni, hogy adjon jogosultságot a névjegyek eléréséhez.]]></string>
|
||||
|
@ -678,7 +678,7 @@
|
|||
<string name="mtm_connect_anyway">Mindenképp szeretne csatlakozni?</string>
|
||||
<string name="mtm_cert_details">Tanúsítvány részletei:</string>
|
||||
<string name="once">Egyszer</string>
|
||||
<string name="qr_code_scanner_needs_access_to_camera">A QR-kód olvasónak kamerahozzáférésre van szüksége</string>
|
||||
<string name="qr_code_scanner_needs_access_to_camera">A QR-kód olvasónak kamera-hozzáférésre van szüksége</string>
|
||||
<string name="pref_scroll_to_bottom">Görgessen az aljára</string>
|
||||
<string name="pref_scroll_to_bottom_summary">Görgessen le egy üzenet elküldése után</string>
|
||||
<string name="edit_status_message_title">Állapotüzenet szerkesztése</string>
|
||||
|
@ -717,7 +717,7 @@
|
|||
<string name="share">Megosztás</string>
|
||||
<string name="unable_to_start_recording">Nem sikerült elindítani a rögzítést</string>
|
||||
<string name="please_wait">Kérem várjon…</string>
|
||||
<string name="no_microphone_permission">A Conversations alkalmazásnak mikrofonhozzáférésre van szüksége</string>
|
||||
<string name="no_microphone_permission">A Conversations alkalmazásnak mikrofon-hozzáférésre van szüksége</string>
|
||||
<string name="search_messages">Üzenetek keresése</string>
|
||||
<string name="gif">GIF</string>
|
||||
<string name="view_conversation">Beszélgetés megtekintése</string>
|
||||
|
@ -739,7 +739,7 @@
|
|||
<string name="conference_destroyed">Ezt a csoportos csevegést megszüntették</string>
|
||||
<string name="unable_to_save_recording">Nem sikerült elmenteni a felvételt</string>
|
||||
<string name="foreground_service_channel_name">Előtér szolgáltatás</string>
|
||||
<string name="foreground_service_channel_description">Ezt az értesítési kategóriát egy állandó értesítés megjelenítéséhez használják, beleértve azt is, hogy a Conversations fut.</string>
|
||||
<string name="foreground_service_channel_description">Ezt az értesítési kategóriát egy állandó értesítés megjelenítéséhez használják, jelezve azt, hogy a Conversations fut.</string>
|
||||
<string name="notification_group_status_information">Állapotinformációk</string>
|
||||
<string name="error_channel_name">Kapcsolódási problémák</string>
|
||||
<string name="error_channel_description">Ezt az értesítési kategóriát egy értesítés megjelenítéséhez használják abban az esetben, ha probléma merül fel a fiókhoz való kapcsolódásnál.</string>
|
||||
|
@ -751,7 +751,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Fontosság, hang, rezgés</string>
|
||||
<string name="video_compression_channel_name">Videó tömörítése</string>
|
||||
<string name="view_media">Média megtekintése</string>
|
||||
<string name="view_users">Résztvevők megtekintése</string>
|
||||
<string name="group_chat_members">Résztvevők</string>
|
||||
<string name="media_browser">Médiaböngésző</string>
|
||||
<string name="security_violation_not_attaching_file">A fájl ki lett hagyva a biztonság megsértése miatt.</string>
|
||||
|
|
|
@ -749,7 +749,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Importanza, suono, vibrazione</string>
|
||||
<string name="video_compression_channel_name">Compressione video</string>
|
||||
<string name="view_media">Vedi i media</string>
|
||||
<string name="view_users">Vedi i partecipanti</string>
|
||||
<string name="group_chat_members">Partecipanti</string>
|
||||
<string name="media_browser">Browser multimediale</string>
|
||||
<string name="security_violation_not_attaching_file">File omesso per violazione di sicurezza.</string>
|
||||
|
|
|
@ -745,7 +745,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Belang, geluid, trillen</string>
|
||||
<string name="video_compression_channel_name">Videocompressie</string>
|
||||
<string name="view_media">Media bekijken</string>
|
||||
<string name="view_users">Deelnemers bekijken</string>
|
||||
<string name="group_chat_members">Deelnemers</string>
|
||||
<string name="media_browser">Mediabrowser</string>
|
||||
<string name="security_violation_not_attaching_file">Bestand weggelaten wegens beveiligingsovertreding.</string>
|
||||
|
|
|
@ -766,7 +766,6 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż
|
|||
<string name="pref_more_notification_settings_summary">Ważność, Dźwięk, Wibracja</string>
|
||||
<string name="video_compression_channel_name">Kompresja wideo</string>
|
||||
<string name="view_media">Pokaż media</string>
|
||||
<string name="view_users">Pokaż członków</string>
|
||||
<string name="group_chat_members">Uczestnicy</string>
|
||||
<string name="media_browser">Przeglądarka mediów</string>
|
||||
<string name="security_violation_not_attaching_file">Plik pominięty w związku z naruszeniem bezpieczeństwa.</string>
|
||||
|
@ -895,4 +894,10 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż
|
|||
<string name="pref_channel_discovery">Metoda odkrywania kanałów</string>
|
||||
<string name="backup">Kopia zapasowa</string>
|
||||
<string name="category_about">O aplikacji</string>
|
||||
<plurals name="view_users">
|
||||
<item quantity="one">Pokaż %1$d uczestnika</item>
|
||||
<item quantity="few">Pokaż %1$d uczestników</item>
|
||||
<item quantity="many">Pokaż %1$d uczestników</item>
|
||||
<item quantity="other">Pokaż %1$d uczestników</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
|
|
@ -155,6 +155,7 @@
|
|||
<string name="account_status_regis_conflict">Esse nome de usuário já está em uso</string>
|
||||
<string name="account_status_regis_success">Registro efetuado com sucesso</string>
|
||||
<string name="account_status_regis_not_sup">O servidor não aceita o registro</string>
|
||||
<string name="account_status_regis_invalid_token">Token de registro inválido</string>
|
||||
<string name="account_status_tls_error">Não foi possível efetuar a negociação TLS</string>
|
||||
<string name="account_status_policy_violation">Violação de política</string>
|
||||
<string name="account_status_incompatible_server">Servidor incompatível</string>
|
||||
|
@ -508,7 +509,7 @@
|
|||
<string name="notify_never">Notificações desabilitadas</string>
|
||||
<string name="notify_paused">Notificações pausadas</string>
|
||||
<string name="pref_picture_compression">Compressão de imagem</string>
|
||||
<string name="pref_picture_compression_summary">Dica: Use \'Selecione o arquivo\' em vez de \'Selecionar uma imagem\' para enviar uma cópia da imagem original, sem redução de qualidade.</string>
|
||||
<string name="pref_picture_compression_summary">Dica: Use \'Selecionar o arquivo\' ao invés de \'Selecionar a imagem\' para enviar uma cópia da imagem original, sem redução de qualidade.</string>
|
||||
<string name="always">Sempre</string>
|
||||
<string name="large_images_only">Apenas imagens grandes</string>
|
||||
<string name="battery_optimizations_enabled">Otimizações de bateria habilitadas</string>
|
||||
|
@ -748,7 +749,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Importância, som, vibração.</string>
|
||||
<string name="video_compression_channel_name">Compressão de vídeo</string>
|
||||
<string name="view_media">Ver mídia</string>
|
||||
<string name="view_users">Ver participantes</string>
|
||||
<string name="group_chat_members">Participantes</string>
|
||||
<string name="media_browser">Navegador de mídia</string>
|
||||
<string name="security_violation_not_attaching_file">Arquivo omitido devido a violação de segurança</string>
|
||||
|
@ -870,11 +870,15 @@
|
|||
<string name="unable_to_perform_this_action">Não foi possível executar essa ação</string>
|
||||
<string name="open_join_dialog">Entrar no canal público...</string>
|
||||
<string name="sharing_application_not_grant_permission">O aplicativo de compartilhamento não permitiu o acesso a esse arquivo.</string>
|
||||
<string name="group_chats_and_channels"><![CDATA[Conversas em grupo & Canais]]></string>
|
||||
<string name="group_chats_and_channels"><![CDATA[Conversas em Grupo & Canais]]></string>
|
||||
<string name="jabber_network">jabber.network</string>
|
||||
<string name="local_server">Servidor local</string>
|
||||
<string name="pref_channel_discovery_summary">A maioria dos usuários devem escolher \'jabber.network\' para melhores sugestões de toda rede pública do XMPP</string>
|
||||
<string name="pref_channel_discovery_summary">A maioria dos usuários deve escolher \'jabber.network\' para melhores sugestões de toda rede pública do XMPP.</string>
|
||||
<string name="pref_channel_discovery">Método de descoberta de canais</string>
|
||||
<string name="backup">Backup</string>
|
||||
<string name="category_about">Sobre</string>
|
||||
<plurals name="view_users">
|
||||
<item quantity="one">Ver %1$d participante</item>
|
||||
<item quantity="other">Ver %1$d participantes</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
<string name="send_pgp_message">Trimite mesaj criptat cu OpenPGP</string>
|
||||
<string name="your_nick_has_been_changed">Numele dumneavoastră a fost schimbat</string>
|
||||
<string name="send_unencrypted">Trimite necriptat</string>
|
||||
<string name="decryption_failed">Decriptarea a eșuat. Poate nu aveții cheia privată corectă.</string>
|
||||
<string name="decryption_failed">Decriptarea a eșuat. Poate nu aveți cheia privată corectă.</string>
|
||||
<string name="openkeychain_required">OpenKeychain</string>
|
||||
<string name="openkeychain_required_long">Conversations utilizează o aplicație externă <b>OpenKeychain</b> pentru a cripta și decripta mesaje și a administra cheile publice.\n\nOpenKeychain este licențiat sub GPLv3 și se poate instala din F-Droid și Google Play.\n\n<small>(Vă rugăm să reporniți Conversations după)</small></string>
|
||||
<string name="restart">Repornește</string>
|
||||
|
@ -155,6 +155,7 @@
|
|||
<string name="account_status_regis_conflict">Nume de utilizator deja alocat</string>
|
||||
<string name="account_status_regis_success">Înregistrare completă</string>
|
||||
<string name="account_status_regis_not_sup">Acest server nu permite înregistrarea</string>
|
||||
<string name="account_status_regis_invalid_token">Simbol de înregistrare invalid</string>
|
||||
<string name="account_status_tls_error">Negociere TLS eşuată</string>
|
||||
<string name="account_status_policy_violation">Încălcare condiții furnizare serviciu</string>
|
||||
<string name="account_status_incompatible_server">Server incompatibil</string>
|
||||
|
@ -175,11 +176,11 @@
|
|||
<string name="mgmt_account_are_you_sure">Sigur doriți asta?</string>
|
||||
<string name="mgmt_account_delete_confirm_text">Dacă vă ștergeți contul, întregul istoric de conversații va fi pierdut</string>
|
||||
<string name="attach_record_voice">Înregistrare voce</string>
|
||||
<string name="account_settings_jabber_id">Adresä XMPP</string>
|
||||
<string name="account_settings_jabber_id">Adresă XMPP</string>
|
||||
<string name="block_jabber_id">Blochează adresă XMPP</string>
|
||||
<string name="account_settings_example_jabber_id">numeutilizator@exemplu.ro</string>
|
||||
<string name="password">Parolă</string>
|
||||
<string name="invalid_jid">Acesta nu este o adresă XMPP valabilă</string>
|
||||
<string name="invalid_jid">Aceasta nu este o adresă XMPP valabilă</string>
|
||||
<string name="error_out_of_memory">Memorie epuizată. Imaginea este prea mare.</string>
|
||||
<string name="add_phone_book_text">Vreți să adăugați pe %s în lista de contacte?</string>
|
||||
<string name="server_info_show_more">Informații server</string>
|
||||
|
@ -231,7 +232,7 @@
|
|||
<string name="delete_bookmark">Șterge semn de carte</string>
|
||||
<string name="destroy_room">Distruge discuția de grup</string>
|
||||
<string name="destroy_channel">Distruge canal</string>
|
||||
<string name="destroy_room_dialog">Sigur doriți distrugerea acestei discuții de grup?\n\n<b>Atenție:</b> Discuția de grup v-a fi complet ștearsä de pe server.</string>
|
||||
<string name="destroy_room_dialog">Sigur doriți distrugerea acestei discuții de grup?\n\n<b>Atenție:</b> Discuția de grup v-a fi complet ștearsă de pe server.</string>
|
||||
<string name="destroy_channel_dialog">Sigur doriți distrugerea acestui canal public?\n\n<b>Atenție:</b> Canalul public v-a fi complet șters de pe server.</string>
|
||||
<string name="could_not_destroy_room">Nu s-a putut distruge discuția de grup</string>
|
||||
<string name="could_not_destroy_channel">Nu s-a putut distruge canalul</string>
|
||||
|
@ -559,8 +560,8 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați
|
|||
<string name="pref_privacy">Intimitate</string>
|
||||
<string name="pref_theme_options">Temă</string>
|
||||
<string name="pref_theme_options_summary">Selecție paletă culori interfață</string>
|
||||
<string name="pref_theme_light">Tema luminoasă</string>
|
||||
<string name="pref_theme_dark">Tema întunecată</string>
|
||||
<string name="pref_theme_light">Luminoasă</string>
|
||||
<string name="pref_theme_dark">Întunecată</string>
|
||||
<string name="unable_to_connect_to_keychain">Nu s-a putut contacta OpenKeychain</string>
|
||||
<string name="this_device_is_no_longer_in_use">Acest dispozitiv nu mai este in uz</string>
|
||||
<string name="type_pc">PC</string>
|
||||
|
@ -686,7 +687,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați
|
|||
<string name="mtm_cert_details">Detalii certificat:</string>
|
||||
<string name="once">Doar o dată</string>
|
||||
<string name="qr_code_scanner_needs_access_to_camera">Scanerul de coduri QR are nevoie de acces la camera foto</string>
|
||||
<string name="pref_scroll_to_bottom">Derulează în jos</string>
|
||||
<string name="pref_scroll_to_bottom">Derulează până jos</string>
|
||||
<string name="pref_scroll_to_bottom_summary">După trimiterea unui mesaj derulează până la sfârșit</string>
|
||||
<string name="edit_status_message_title">Editare mesaj de stare</string>
|
||||
<string name="edit_status_message">Editare mesaj de stare</string>
|
||||
|
@ -758,20 +759,19 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați
|
|||
<string name="pref_more_notification_settings_summary">Importanță, sunete, vibrații</string>
|
||||
<string name="video_compression_channel_name">Compresie video</string>
|
||||
<string name="view_media">Vizualizare fișiere media</string>
|
||||
<string name="view_users">Arată participanții</string>
|
||||
<string name="group_chat_members">Participanți</string>
|
||||
<string name="media_browser">Vizualizare fișiere media</string>
|
||||
<string name="security_violation_not_attaching_file">Fișier omis ca urmare a unei probleme de securitate.</string>
|
||||
<string name="pref_video_compression">Calitate video</string>
|
||||
<string name="pref_video_compression_summary">O calitate micä înseamnă fișiere mai mici</string>
|
||||
<string name="pref_video_compression_summary">O calitate mică înseamnă fișiere mai mici</string>
|
||||
<string name="video_360p">Medie (360p)</string>
|
||||
<string name="video_720p">Mare (720p)</string>
|
||||
<string name="cancelled">anulat</string>
|
||||
<string name="already_drafting_message">Deja aveți ciorna unui mesaj.</string>
|
||||
<string name="feature_not_implemented">Opțiune neimplementată</string>
|
||||
<string name="invalid_country_code">Cod de țarä invalid</string>
|
||||
<string name="choose_a_country">Alegeți o țarä</string>
|
||||
<string name="phone_number">numär de telefon</string>
|
||||
<string name="invalid_country_code">Cod de țară invalid</string>
|
||||
<string name="choose_a_country">Alegeți o țară</string>
|
||||
<string name="phone_number">număr de telefon</string>
|
||||
<string name="verify_your_phone_number">Verificare număr de telefon</string>
|
||||
<string name="enter_country_code_and_phone_number">Quicksy va trimite un mesaj SMS (pot exista costuri în funcție de furnizor) pentru a vă verifica numărul de telefon. Introduceți codul țării dumneavoastră si numărul de telefon:</string>
|
||||
<string name="we_will_be_verifying"><![CDATA[Vă vom verifica numărul de telefon<br/><br/><b>%s</b><br/><br/>Este în regulă sau ați dori să editați numărul?]]></string>
|
||||
|
@ -787,7 +787,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați
|
|||
<string name="wait_x">%s</string>
|
||||
<string name="back">înapoi</string>
|
||||
<string name="possible_pin">S-a copiat automat un posibil cod din memorie</string>
|
||||
<string name="please_enter_pin">Vä rugăm să vă introduceți codul de 6 cifre.</string>
|
||||
<string name="please_enter_pin">Vă rugăm să vă introduceți codul de 6 cifre.</string>
|
||||
<string name="abort_registration_procedure">Sigur doriți să anulați procedura de înregistrare?</string>
|
||||
<string name="yes">Da</string>
|
||||
<string name="no">Nu</string>
|
||||
|
@ -796,7 +796,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați
|
|||
<string name="incorrect_pin">Codul introdus este incorect.</string>
|
||||
<string name="pin_expired">Codul pe care vi l-am trimis a expirat.</string>
|
||||
<string name="unknown_api_error_network">Eroare de rețea necunoscută.</string>
|
||||
<string name="unknown_api_error_response">Räspuns necunoscut de la server.</string>
|
||||
<string name="unknown_api_error_response">Răspuns necunoscut de la server.</string>
|
||||
<string name="unable_to_connect_to_server">Nu se poate face conexiunea la server.</string>
|
||||
<string name="unable_to_establish_secure_connection">Nu se poate realiza o conexiune securizată.</string>
|
||||
<string name="unable_to_find_server">Nu se poate găsi serverul.</string>
|
||||
|
@ -812,7 +812,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați
|
|||
<string name="logged_in_with_another_device">Acest număr de telefon este momentan autentificat pe un alt dispozitiv.</string>
|
||||
<string name="enter_your_name_instructions">Vă rugăm să vă introduceți numele pentru a informa persoanele care nu vă au în agendă cine sunteți.</string>
|
||||
<string name="your_name">Numele dumneavoastă</string>
|
||||
<string name="enter_your_name">Introducețivä numele</string>
|
||||
<string name="enter_your_name">Introducețivă numele</string>
|
||||
<string name="no_name_set_instructions">Folosiți butonul de editare pentru a vă seta numele.</string>
|
||||
<string name="reject_request">Refuză cererea</string>
|
||||
<string name="install_orbot">Instalare Orbot</string>
|
||||
|
@ -837,7 +837,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați
|
|||
<string name="create_private_group_chat">Creează discuție de grup privată</string>
|
||||
<string name="create_public_channel">Creează canal public</string>
|
||||
<string name="create_dialog_channel_name">Nume canal</string>
|
||||
<string name="xmpp_address">Adresä XMPP</string>
|
||||
<string name="xmpp_address">Adresă XMPP</string>
|
||||
<string name="please_enter_name">Vă rugăm să furnizați un nume pentru canal</string>
|
||||
<string name="please_enter_xmpp_address">Vă rugăm să furnizați o adresă XMPP</string>
|
||||
<string name="this_is_an_xmpp_address">Aceasta este o adresă XMPP. Vă rugăm să furnizați un nume.</string>
|
||||
|
@ -874,7 +874,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați
|
|||
<string name="conversations_backup">Copie de siguranță Conversations</string>
|
||||
<string name="event">Eveniment</string>
|
||||
<string name="open_backup">Deschide o copie de siguranță</string>
|
||||
<string name="not_a_backup_file">Fișierul selectat nu este o copie de siguranța Conversations</string>
|
||||
<string name="not_a_backup_file">Fișierul selectat nu este o copie de siguranță Conversations</string>
|
||||
<string name="account_already_setup">Acest cont a fost deja configurat</string>
|
||||
<string name="please_enter_password">Va rugăm să introduceți parola pentru acest cont</string>
|
||||
<string name="unable_to_perform_this_action">Nu se poate realiza această acțiune</string>
|
||||
|
@ -887,4 +887,9 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați
|
|||
<string name="pref_channel_discovery">Metoda de descoperire a canalelor</string>
|
||||
<string name="backup">Copie de siguranță</string>
|
||||
<string name="category_about">Despre</string>
|
||||
<plurals name="view_users">
|
||||
<item quantity="one">Arată %1$d participant</item>
|
||||
<item quantity="few">Arată %1$d participanți</item>
|
||||
<item quantity="other">Arată %1$d de participanți</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
|
|
@ -759,7 +759,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Важливість, звук, вібрація</string>
|
||||
<string name="video_compression_channel_name">Стиснення відео</string>
|
||||
<string name="view_media">Перегляд медіа</string>
|
||||
<string name="view_users">Переглянути учасників</string>
|
||||
<string name="group_chat_members">Учасники</string>
|
||||
<string name="media_browser">Переглядач медіа</string>
|
||||
<string name="security_violation_not_attaching_file">Файл пропущено через порушення безпеки.</string>
|
||||
|
|
|
@ -738,7 +738,6 @@
|
|||
<string name="pref_more_notification_settings_summary">重要性,声音,振动</string>
|
||||
<string name="video_compression_channel_name">视频压缩</string>
|
||||
<string name="view_media">查看媒体文件</string>
|
||||
<string name="view_users">查看成员</string>
|
||||
<string name="group_chat_members">成员</string>
|
||||
<string name="media_browser">媒体浏览器</string>
|
||||
<string name="security_violation_not_attaching_file">文件由于违反安全策略而被删除。</string>
|
||||
|
|
|
@ -155,6 +155,7 @@
|
|||
<string name="account_status_regis_conflict">Username already in use</string>
|
||||
<string name="account_status_regis_success">Registration completed</string>
|
||||
<string name="account_status_regis_not_sup">Server does not support registration</string>
|
||||
<string name="account_status_regis_invalid_token">Invalid registration token</string>
|
||||
<string name="account_status_tls_error">TLS negotiation failed</string>
|
||||
<string name="account_status_policy_violation">Policy violation</string>
|
||||
<string name="account_status_incompatible_server">Incompatible server</string>
|
||||
|
@ -751,7 +752,6 @@
|
|||
<string name="pref_more_notification_settings_summary">Importance, Sound, Vibrate</string>
|
||||
<string name="video_compression_channel_name">Video compression</string>
|
||||
<string name="view_media">View media</string>
|
||||
<string name="view_users">View participants</string>
|
||||
<string name="group_chat_members">Participants</string>
|
||||
<string name="media_browser">Media browser</string>
|
||||
<string name="security_violation_not_attaching_file">File omitted due to security violation.</string>
|
||||
|
@ -880,4 +880,8 @@
|
|||
<string name="pref_channel_discovery">Channel discovery method</string>
|
||||
<string name="backup">Backup</string>
|
||||
<string name="category_about">About</string>
|
||||
<plurals name="view_users">
|
||||
<item quantity="one">View %1$d Participant</item>
|
||||
<item quantity="other">View %1$d Participants</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
|
|
@ -87,7 +87,6 @@
|
|||
<item type="reference" name="icon_edit">@drawable/ic_edit_white_24dp</item>
|
||||
<item type="reference" name="icon_edit_body">@drawable/ic_edit_black_24dp</item>
|
||||
<item type="reference" name="icon_save">@drawable/ic_save_black_24dp</item>
|
||||
<item type="reference" name="icon_done">@drawable/ic_done_black_24dp</item>
|
||||
<item type="reference" name="icon_group">@drawable/ic_group_white_24dp</item>
|
||||
<item type="reference" name="icon_new">@drawable/ic_add_white_24dp</item>
|
||||
<item type="reference" name="icon_quote">@drawable/ic_reply_white_24dp</item>
|
||||
|
@ -202,7 +201,6 @@
|
|||
<item type="reference" name="icon_edit">@drawable/ic_edit_white_24dp</item>
|
||||
<item type="reference" name="icon_edit_body">@drawable/ic_edit_white_24dp</item>
|
||||
<item type="reference" name="icon_save">@drawable/ic_save_white_24dp</item>
|
||||
<item type="reference" name="icon_done">@drawable/ic_done_black_24dp</item>
|
||||
<item type="reference" name="icon_group">@drawable/ic_group_white_24dp</item>
|
||||
<item type="reference" name="icon_new">@drawable/ic_add_white_24dp</item>
|
||||
<item type="reference" name="icon_quote">@drawable/ic_reply_white_24dp</item>
|
||||
|
|
|
@ -9,10 +9,12 @@ import android.util.Log;
|
|||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.ui.ConversationsActivity;
|
||||
import eu.siacs.conversations.ui.EditAccountActivity;
|
||||
import eu.siacs.conversations.ui.EnterPhoneNumberActivity;
|
||||
import eu.siacs.conversations.ui.StartConversationActivity;
|
||||
import eu.siacs.conversations.ui.TosActivity;
|
||||
import eu.siacs.conversations.ui.VerifyActivity;
|
||||
import rocks.xmpp.addr.Jid;
|
||||
|
||||
public class SignupUtils {
|
||||
|
||||
|
@ -45,4 +47,12 @@ public class SignupUtils {
|
|||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static boolean isSupportTokenRegistry() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Intent getTokenRegistrationIntent(Activity activity, Jid preset, String key) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,26 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="crash_report_title">A Quicksy összeomlott</string>
|
||||
<string name="crash_report_message">A verem nyomkövetések beküldésével segíthet a Quicksy folyamatos fejlesztésében\n<b>Figyelem:</b> Ez az XMPP fiókját fogja használni az adatok fejlesztőhöz való elküldéshez.</string>
|
||||
<string name="openkeychain_required_long">A Quicksy egy harmadik fél által biztosított alkalmazást, az <b>OpenKeychain</b>-t használja az üzenetek titkosítására és a nyilvános kulcsok kezelésére.\n\nAz OpenKeychain GPLv3 engedélyes és letölthető az F-Droid-ról és a Google Play-ről.\n\n<small>(Kérjük, ezután indítsa újra a Quicksy-t.)</small></string>
|
||||
<string name="contact_has_no_pgp_key">A Quicksy nem tudja titkosítani az üzeneteit, mert a kapcsolata nem jelenti be a nyilvános kulcsát.\n\n<small>Kérje meg a kapcsolatát, hogy állítsa be az OpenPGP-t.</small></string>
|
||||
<string name="contacts_have_no_pgp_keys">A Quicksy nem képes titkosítani az üzeneteket, mert az ismerősei nem jelentik be a nyilvános kulcsaikat.\n\n<small> Kérje meg az ismerőseit, hogy állítsák be az OpenPGP-t.</small></string>
|
||||
<string name="pref_notification_grace_period_summary">A Quicksy csendben marad ennyi ideig, miután aktivitást észlelt másik eszközön</string>
|
||||
<string name="pref_never_send_crash_summary">A verem nyomkövetések beküldésével segíthet a Quicksy folyamatos fejlesztésében</string>
|
||||
<string name="no_storage_permission">A Quicksy-nek hozzáférésre lenne szüksége a külső tárhelyhez</string>
|
||||
<string name="no_camera_permission">A Quicksy-nek hozzáférésre lenne szüksége a kamerához</string>
|
||||
<string name="battery_optimizations_enabled_explained">A készülék erős akkumulátor optimalizálást végez a Quicksy programon, ami késleltetett értesítésekhez, vagy akár üzenetek elvesztéséhet is vezethet.\nJavasolt kikapcsolni ezt.</string>
|
||||
<string name="battery_optimizations_enabled_dialog">A készülék erős akkumulátor optimalizálást végez a Quicksy programon, ami késleltetett értesítésekhez, vagy akár üzenetek elvesztéséhet is vezethet.\nMost megkérnénk az optimalizáció letiltására.</string>
|
||||
<string name="pref_broadcast_last_activity_summary">Jelezze az ismerőseinek, hogy mikor használja a Quicksy-t</string>
|
||||
<string name="data_saver_enabled_explained">Az operációs rendszer korlátozza a Quicksy hozzáférését az internethez, amikor az a háttérben fut. Ahhoz, hogy értesítéseket kapjon az új üzenetekről aktív Adatspórolás esetén is, lehetővé kell tennie a Quicksy korlátlan hozzáférését.\nA Quicksy továbbra is arra törekszik, hogy spóroljon az adatforgalmon, ha ez lehetséges.</string>
|
||||
<string name="device_does_not_support_data_saver">Az eszköze nem támogatja az adatspórolás letiltását.</string>
|
||||
<string name="huawei_protected_apps_summary">Ha értesítést szeretne kapni, még akkor is, ha a képernyő ki van kapcsolva, hozzá kell adnia a Quicksy-t a védett alkalmazások listájához.</string>
|
||||
<string name="error_trustkey_general">A Quicksy nem tud titkosított üzeneteket küldeni neki: %1$s. Ez azért történhetett, mert a kapcsolattartója olyan elavult kiszolgálót vagy ügyfélprogramot használ ami nem tudja kezelni az OMEMO-t.</string>
|
||||
<string name="no_microphone_permission">A Quicksy-nek hozzáférésre lenne szüksége a mikrofonhoz</string>
|
||||
<string name="foreground_service_channel_description">Ez az értesítési kategória állandó értesítést jelenít meg arról, hogy a Quicksy fut.</string>
|
||||
<string name="crash_report_message">A veremkiíratások elküldésével segíti a Quicksy alkalmazás folyamatos fejlesztését\n<b>Figyelmeztetés:</b> Ez a XMPP-fiókját fogja használni a veremkövetés elküldéséhez a fejlesztő számára.</string>
|
||||
<string name="openkeychain_required_long">A Quicksy egy <b>OpenKeychain</b> nevű, harmadik fél által fejlesztett alkalmazást használ az üzenetek titkosításához és visszafejtéséhez, valamint a személyes kulcsai kezeléséhez.n\nAz OpenKeychain GPLv3 szerint licencelt, és elérhető az F-Droid és a Google Play szoftveráruházakban.\n\n<small>(Ezután indítsa újra a Quicksy alkalmazást.)</small></string>
|
||||
<string name="contact_has_no_pgp_key">A Quicksy nem tudja titkosítani az üzeneteit, mert a partnere nem közölte a nyilvános kulcsát.\n\n<small>Kérje meg a partnerét, hogy állítsa be az OpenPGP-t.</small></string>
|
||||
<string name="contacts_have_no_pgp_keys">A Quicksy nem tudja titkosítani az üzeneteit, mert a partnerei nem közölték a nyilvános kulcsukat.\n\n<small>Kérje meg a partnereit, hogy állítsák be az OpenPGP-t.</small></string>
|
||||
<string name="pref_notification_grace_period_summary">A Quicksy csendben marad ennyi ideig, miután aktivitást észlelt egy másik eszközön</string>
|
||||
<string name="pref_never_send_crash_summary">A veremkiíratások elküldésével segíti a Quicksy alkalmazás folyamatos fejlesztését</string>
|
||||
<string name="no_storage_permission">A Quicksy alkalmazásnak hozzáférésre van szüksége a külső tárolóhoz</string>
|
||||
<string name="no_camera_permission">A Quicksy alkalmazásnak kamera-hozzáférésre van szüksége</string>
|
||||
<string name="battery_optimizations_enabled_explained">A készülék erős akkumulátor-optimalizálást végez a Quicksy programon, ami késleltetett értesítésekhez, vagy akár üzenetek elvesztéséhez is vezethet.\nAjánlott kikapcsolni ezeket.</string>
|
||||
<string name="battery_optimizations_enabled_dialog">A készülék erős akkumulátor-optimalizálást végez a Quicksy programon, ami késleltetett értesítésekhez, vagy akár üzenetek elvesztéséhez is vezethet.\nMost arra fogják kérni, hogy tiltsa le azokat.</string>
|
||||
<string name="pref_broadcast_last_activity_summary">Tudassa az összes partnerével, hogy a Quicksy alkalmazást használja</string>
|
||||
<string name="data_saver_enabled_explained">Az operációs rendszer korlátozza a Quicksy hozzáférését az internethez, amikor az a háttérben fut. Ahhoz, hogy értesítéseket kapjon az új üzenetekről aktív adatspórolás esetén is, lehetővé kell tennie a Quicksy korlátlan hozzáférését.\nA Quicksy továbbra is arra törekszik, hogy spóroljon az adatforgalmon, ahol lehetséges.</string>
|
||||
<string name="device_does_not_support_data_saver">Az eszköze nem támogatja az adatspórolás letiltását a Quicksy alkalmazásnál.</string>
|
||||
<string name="huawei_protected_apps_summary">Ha akkor is szeretne értesítéseket kapni, amikor a kijelző ki van kapcsolva, hozzá kell adnia a Quicksy alkalmazást a védett alkalmazások listájához.</string>
|
||||
<string name="error_trustkey_general">A Quicksy nem tud titkosított üzeneteket küldeni %1$s részére. Ez amiatt lehet, hogy a partnere elavult kiszolgálót vagy kliensprogramot használ, amely nem tudja kezelni az OMEMO-t.</string>
|
||||
<string name="no_microphone_permission">A Quicksy alkalmazásnak mikrofon-hozzáférésre van szüksége</string>
|
||||
<string name="foreground_service_channel_description">Ezt az értesítési kategóriát egy állandó értesítés megjelenítéséhez használják, jelezve azt, hogy a Quicksy fut.</string>
|
||||
<string name="set_profile_picture">Quicksy profilkép</string>
|
||||
<string name="not_available_in_your_country">A Quicksy nem érhető el az Ön országában.</string>
|
||||
<string name="unable_to_verify_server_identity">Nem sikerült ellenőrizni a szerver azonosságát.</string>
|
||||
<string name="unable_to_verify_server_identity">Nem sikerült ellenőrizni a kiszolgáló személyazonosságát.</string>
|
||||
<string name="unknown_security_error">Ismeretlen biztonsági hiba.</string>
|
||||
<string name="timeout_while_connecting_to_server">Időtúllépés történt a szerverhez való csatlakozás közben.</string>
|
||||
<string name="timeout_while_connecting_to_server">Időtúllépés a kiszolgálóhoz való csatlakozáskor.</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="omemo_setting_default">always</string>
|
||||
</resources>
|
||||
|
|