apply Material 3 theme to all activites
This commit is contained in:
parent
4968bde774
commit
6e43248135
|
@ -74,7 +74,7 @@ dependencies {
|
||||||
implementation 'org.hsluv:hsluv:0.2'
|
implementation 'org.hsluv:hsluv:0.2'
|
||||||
implementation 'org.conscrypt:conscrypt-android:2.5.2'
|
implementation 'org.conscrypt:conscrypt-android:2.5.2'
|
||||||
implementation 'me.drakeet.support:toastcompat:1.1.0'
|
implementation 'me.drakeet.support:toastcompat:1.1.0'
|
||||||
implementation "com.leinardi.android:speed-dial:3.2.0"
|
implementation "com.leinardi.android:speed-dial:3.3.0"
|
||||||
|
|
||||||
implementation "com.squareup.retrofit2:retrofit:2.9.0"
|
implementation "com.squareup.retrofit2:retrofit:2.9.0"
|
||||||
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
|
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ManageAccountActivity"
|
android:name=".ui.ManageAccountActivity"
|
||||||
android:label="@string/title_activity_manage_accounts"
|
android:label="@string/title_activity_manage_accounts"
|
||||||
|
android:theme="@style/Theme.Conversations3"
|
||||||
android:launchMode="singleTask" />
|
android:launchMode="singleTask" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.WelcomeActivity"
|
android:name=".ui.WelcomeActivity"
|
||||||
|
|
|
@ -225,7 +225,7 @@ public class ImportBackupService extends Service {
|
||||||
NotificationCompat.Builder mBuilder =
|
NotificationCompat.Builder mBuilder =
|
||||||
new NotificationCompat.Builder(getBaseContext(), "backup");
|
new NotificationCompat.Builder(getBaseContext(), "backup");
|
||||||
mBuilder.setContentTitle(getString(R.string.restoring_backup))
|
mBuilder.setContentTitle(getString(R.string.restoring_backup))
|
||||||
.setSmallIcon(R.drawable.ic_unarchive_white_24dp)
|
.setSmallIcon(R.drawable.ic_unarchive_24dp)
|
||||||
.setProgress(max, progress, max == 1 && progress == 0);
|
.setProgress(max, progress, max == 1 && progress == 0);
|
||||||
return mBuilder.build();
|
return mBuilder.build();
|
||||||
}
|
}
|
||||||
|
@ -415,7 +415,7 @@ public class ImportBackupService extends Service {
|
||||||
? PendingIntent.FLAG_IMMUTABLE
|
? PendingIntent.FLAG_IMMUTABLE
|
||||||
| PendingIntent.FLAG_UPDATE_CURRENT
|
| PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
: PendingIntent.FLAG_UPDATE_CURRENT))
|
: PendingIntent.FLAG_UPDATE_CURRENT))
|
||||||
.setSmallIcon(R.drawable.ic_unarchive_white_24dp);
|
.setSmallIcon(R.drawable.ic_unarchive_24dp);
|
||||||
notificationManager.notify(NOTIFICATION_ID, mBuilder.build());
|
notificationManager.notify(NOTIFICATION_ID, mBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package eu.siacs.conversations.ui;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -11,8 +12,10 @@ import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
|
@ -23,19 +26,20 @@ import eu.siacs.conversations.services.BarcodeProvider;
|
||||||
import eu.siacs.conversations.utils.EasyOnboardingInvite;
|
import eu.siacs.conversations.utils.EasyOnboardingInvite;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
|
||||||
public class EasyOnboardingInviteActivity extends XmppActivity implements EasyOnboardingInvite.OnInviteRequested {
|
public class EasyOnboardingInviteActivity extends XmppActivity
|
||||||
|
implements EasyOnboardingInvite.OnInviteRequested {
|
||||||
|
|
||||||
private ActivityEasyInviteBinding binding;
|
private ActivityEasyInviteBinding binding;
|
||||||
|
|
||||||
private EasyOnboardingInvite easyOnboardingInvite;
|
private EasyOnboardingInvite easyOnboardingInvite;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(final Bundle bundle) {
|
public void onCreate(final Bundle bundle) {
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_easy_invite);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_easy_invite);
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar(), true);
|
configureActionBar(getSupportActionBar(), true);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
this.binding.shareButton.setOnClickListener(v -> share());
|
this.binding.shareButton.setOnClickListener(v -> share());
|
||||||
if (bundle != null && bundle.containsKey("invite")) {
|
if (bundle != null && bundle.containsKey("invite")) {
|
||||||
this.easyOnboardingInvite = bundle.getParcelable("invite");
|
this.easyOnboardingInvite = bundle.getParcelable("invite");
|
||||||
|
@ -65,11 +69,11 @@ public class EasyOnboardingInviteActivity extends XmppActivity implements EasyOn
|
||||||
}
|
}
|
||||||
|
|
||||||
private void share() {
|
private void share() {
|
||||||
final String shareText = getString(
|
final String shareText =
|
||||||
R.string.easy_invite_share_text,
|
getString(
|
||||||
easyOnboardingInvite.getDomain(),
|
R.string.easy_invite_share_text,
|
||||||
easyOnboardingInvite.getShareableLink()
|
easyOnboardingInvite.getDomain(),
|
||||||
);
|
easyOnboardingInvite.getShareableLink());
|
||||||
final Intent sendIntent = new Intent();
|
final Intent sendIntent = new Intent();
|
||||||
sendIntent.setAction(Intent.ACTION_SEND);
|
sendIntent.setAction(Intent.ACTION_SEND);
|
||||||
sendIntent.putExtra(Intent.EXTRA_TEXT, shareText);
|
sendIntent.putExtra(Intent.EXTRA_TEXT, shareText);
|
||||||
|
@ -95,16 +99,47 @@ public class EasyOnboardingInviteActivity extends XmppActivity implements EasyOn
|
||||||
private void showInvite(final EasyOnboardingInvite invite) {
|
private void showInvite(final EasyOnboardingInvite invite) {
|
||||||
this.binding.inProgress.setVisibility(View.GONE);
|
this.binding.inProgress.setVisibility(View.GONE);
|
||||||
this.binding.invite.setVisibility(View.VISIBLE);
|
this.binding.invite.setVisibility(View.VISIBLE);
|
||||||
this.binding.tapToShare.setText(getString(R.string.tap_share_button_send_invite, invite.getDomain()));
|
this.binding.tapToShare.setText(
|
||||||
|
getString(R.string.tap_share_button_send_invite, invite.getDomain()));
|
||||||
final Point size = new Point();
|
final Point size = new Point();
|
||||||
getWindowManager().getDefaultDisplay().getSize(size);
|
getWindowManager().getDefaultDisplay().getSize(size);
|
||||||
final int width = Math.min(size.x, size.y);
|
final int width = Math.min(size.x, size.y);
|
||||||
final Bitmap bitmap = BarcodeProvider.create2dBarcodeBitmap(invite.getShareableLink(), width);
|
final boolean nightMode =
|
||||||
|
(this.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)
|
||||||
|
== Configuration.UI_MODE_NIGHT_YES;
|
||||||
|
final int black;
|
||||||
|
final int white;
|
||||||
|
if (nightMode) {
|
||||||
|
black =
|
||||||
|
MaterialColors.getColor(
|
||||||
|
this,
|
||||||
|
com.google.android.material.R.attr.colorSurface,
|
||||||
|
"No surface color configured");
|
||||||
|
white =
|
||||||
|
MaterialColors.getColor(
|
||||||
|
this,
|
||||||
|
com.google.android.material.R.attr.colorSurfaceInverse,
|
||||||
|
"No inverse surface color configured");
|
||||||
|
} else {
|
||||||
|
black =
|
||||||
|
MaterialColors.getColor(
|
||||||
|
this,
|
||||||
|
com.google.android.material.R.attr.colorSurfaceInverse,
|
||||||
|
"No inverse surface color configured");
|
||||||
|
white =
|
||||||
|
MaterialColors.getColor(
|
||||||
|
this,
|
||||||
|
com.google.android.material.R.attr.colorSurface,
|
||||||
|
"No surface color configured");
|
||||||
|
}
|
||||||
|
final Bitmap bitmap =
|
||||||
|
BarcodeProvider.create2dBarcodeBitmap(
|
||||||
|
invite.getShareableLink(), width, black, white);
|
||||||
binding.qrCode.setImageBitmap(bitmap);
|
binding.qrCode.setImageBitmap(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle bundle) {
|
public void onSaveInstanceState(@NonNull Bundle bundle) {
|
||||||
super.onSaveInstanceState(bundle);
|
super.onSaveInstanceState(bundle);
|
||||||
if (easyOnboardingInvite != null) {
|
if (easyOnboardingInvite != null) {
|
||||||
bundle.putParcelable("invite", easyOnboardingInvite);
|
bundle.putParcelable("invite", easyOnboardingInvite);
|
||||||
|
@ -141,11 +176,12 @@ public class EasyOnboardingInviteActivity extends XmppActivity implements EasyOn
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inviteRequestFailed(final String message) {
|
public void inviteRequestFailed(final String message) {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(
|
||||||
if (!Strings.isNullOrEmpty(message)) {
|
() -> {
|
||||||
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
|
if (!Strings.isNullOrEmpty(message)) {
|
||||||
}
|
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
|
||||||
finish();
|
}
|
||||||
});
|
finish();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -31,7 +32,6 @@ import eu.siacs.conversations.services.ImportBackupService;
|
||||||
import eu.siacs.conversations.ui.adapter.BackupFileAdapter;
|
import eu.siacs.conversations.ui.adapter.BackupFileAdapter;
|
||||||
import eu.siacs.conversations.ui.util.SettingsUtils;
|
import eu.siacs.conversations.ui.util.SettingsUtils;
|
||||||
import eu.siacs.conversations.utils.BackupFileHeader;
|
import eu.siacs.conversations.utils.BackupFileHeader;
|
||||||
import eu.siacs.conversations.utils.ThemeHelper;
|
|
||||||
|
|
||||||
public class ImportBackupActivity extends ActionBarActivity implements ServiceConnection, ImportBackupService.OnBackupFilesLoaded, BackupFileAdapter.OnItemClickedListener, ImportBackupService.OnBackupProcessed {
|
public class ImportBackupActivity extends ActionBarActivity implements ServiceConnection, ImportBackupService.OnBackupFilesLoaded, BackupFileAdapter.OnItemClickedListener, ImportBackupService.OnBackupProcessed {
|
||||||
|
|
||||||
|
@ -46,10 +46,9 @@ public class ImportBackupActivity extends ActionBarActivity implements ServiceCo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(final Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
this.mTheme = ThemeHelper.find(this);
|
|
||||||
setTheme(this.mTheme);
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
binding = DataBindingUtil.setContentView(this, R.layout.activity_import_backup);
|
binding = DataBindingUtil.setContentView(this, R.layout.activity_import_backup);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
setLoadingState(savedInstanceState != null && savedInstanceState.getBoolean("loading_state", false));
|
setLoadingState(savedInstanceState != null && savedInstanceState.getBoolean("loading_state", false));
|
||||||
this.backupFileAdapter = new BackupFileAdapter();
|
this.backupFileAdapter = new BackupFileAdapter();
|
||||||
|
@ -57,12 +56,6 @@ public class ImportBackupActivity extends ActionBarActivity implements ServiceCo
|
||||||
this.backupFileAdapter.setOnItemClickedListener(this);
|
this.backupFileAdapter.setOnItemClickedListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume(){
|
|
||||||
super.onResume();
|
|
||||||
SettingsUtils.applyScreenshotPreventionSetting(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(final Menu menu) {
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.import_backup, menu);
|
getMenuInflater().inflate(R.menu.import_backup, menu);
|
||||||
|
@ -80,12 +73,7 @@ public class ImportBackupActivity extends ActionBarActivity implements ServiceCo
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
final int theme = ThemeHelper.find(this);
|
bindService(new Intent(this, ImportBackupService.class), this, Context.BIND_AUTO_CREATE);
|
||||||
if (this.mTheme != theme) {
|
|
||||||
recreate();
|
|
||||||
} else {
|
|
||||||
bindService(new Intent(this, ImportBackupService.class), this, Context.BIND_AUTO_CREATE);
|
|
||||||
}
|
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction()) && !this.mLoadingState) {
|
if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction()) && !this.mLoadingState) {
|
||||||
Uri uri = intent.getData();
|
Uri uri = intent.getData();
|
||||||
|
@ -146,7 +134,7 @@ public class ImportBackupActivity extends ActionBarActivity implements ServiceCo
|
||||||
final DialogEnterPasswordBinding enterPasswordBinding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.dialog_enter_password, null, false);
|
final DialogEnterPasswordBinding enterPasswordBinding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.dialog_enter_password, null, false);
|
||||||
Log.d(Config.LOGTAG, "attempting to import " + backupFile.getUri());
|
Log.d(Config.LOGTAG, "attempting to import " + backupFile.getUri());
|
||||||
enterPasswordBinding.explain.setText(getString(R.string.enter_password_to_restore, backupFile.getHeader().getJid().toString()));
|
enterPasswordBinding.explain.setText(getString(R.string.enter_password_to_restore, backupFile.getHeader().getJid().toString()));
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setView(enterPasswordBinding.getRoot());
|
builder.setView(enterPasswordBinding.getRoot());
|
||||||
builder.setTitle(R.string.enter_password);
|
builder.setTitle(R.string.enter_password);
|
||||||
builder.setNegativeButton(R.string.cancel, (dialog, which) -> {
|
builder.setNegativeButton(R.string.cancel, (dialog, which) -> {
|
||||||
|
@ -186,6 +174,7 @@ public class ImportBackupActivity extends ActionBarActivity implements ServiceCo
|
||||||
binding.coordinator.setVisibility(loadingState ? View.GONE : View.VISIBLE);
|
binding.coordinator.setVisibility(loadingState ? View.GONE : View.VISIBLE);
|
||||||
binding.inProgress.setVisibility(loadingState ? View.VISIBLE : View.GONE);
|
binding.inProgress.setVisibility(loadingState ? View.VISIBLE : View.GONE);
|
||||||
setTitle(loadingState ? R.string.restoring_backup : R.string.restore_backup);
|
setTitle(loadingState ? R.string.restoring_backup : R.string.restore_backup);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
configureActionBar(getSupportActionBar(), !loadingState);
|
configureActionBar(getSupportActionBar(), !loadingState);
|
||||||
this.mLoadingState = loadingState;
|
this.mLoadingState = loadingState;
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
|
|
|
@ -10,45 +10,32 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.MagicCreateBinding;
|
import eu.siacs.conversations.databinding.ActivityMagicCreateBinding;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
import eu.siacs.conversations.utils.CryptoHelper;
|
||||||
import eu.siacs.conversations.utils.InstallReferrerUtils;
|
import eu.siacs.conversations.utils.InstallReferrerUtils;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
public class MagicCreateActivity extends XmppActivity implements TextWatcher {
|
public class MagicCreateActivity extends XmppActivity implements TextWatcher {
|
||||||
|
|
||||||
public static final String EXTRA_DOMAIN = "domain";
|
public static final String EXTRA_DOMAIN = "domain";
|
||||||
public static final String EXTRA_PRE_AUTH = "pre_auth";
|
public static final String EXTRA_PRE_AUTH = "pre_auth";
|
||||||
public static final String EXTRA_USERNAME = "username";
|
public static final String EXTRA_USERNAME = "username";
|
||||||
|
|
||||||
private MagicCreateBinding binding;
|
private ActivityMagicCreateBinding binding;
|
||||||
private String domain;
|
private String domain;
|
||||||
private String username;
|
private String username;
|
||||||
private String preAuth;
|
private String preAuth;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void refreshUiReal() {
|
protected void refreshUiReal() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onBackendConnected() {
|
void onBackendConnected() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
final int theme = findTheme();
|
|
||||||
if (this.mTheme != theme) {
|
|
||||||
recreate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(final Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
|
@ -60,7 +47,8 @@ public class MagicCreateActivity extends XmppActivity implements TextWatcher {
|
||||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||||
}
|
}
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.magic_create);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_magic_create);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(this.binding.toolbar);
|
setSupportActionBar(this.binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar(), this.domain == null);
|
configureActionBar(getSupportActionBar(), this.domain == null);
|
||||||
if (username != null && domain != null) {
|
if (username != null && domain != null) {
|
||||||
|
@ -72,51 +60,64 @@ public class MagicCreateActivity extends XmppActivity implements TextWatcher {
|
||||||
} else if (domain != null) {
|
} else if (domain != null) {
|
||||||
binding.instructions.setText(getString(R.string.magic_create_text_on_x, domain));
|
binding.instructions.setText(getString(R.string.magic_create_text_on_x, domain));
|
||||||
}
|
}
|
||||||
binding.createAccount.setOnClickListener(v -> {
|
binding.createAccount.setOnClickListener(
|
||||||
try {
|
v -> {
|
||||||
final String username = binding.username.getText().toString();
|
try {
|
||||||
final Jid jid;
|
final String username = binding.username.getText().toString();
|
||||||
final boolean fixedUsername;
|
final Jid jid;
|
||||||
if (this.domain != null && this.username != null) {
|
final boolean fixedUsername;
|
||||||
fixedUsername = true;
|
if (this.domain != null && this.username != null) {
|
||||||
jid = Jid.ofLocalAndDomainEscaped(this.username, this.domain);
|
fixedUsername = true;
|
||||||
} else if (this.domain != null) {
|
jid = Jid.ofLocalAndDomainEscaped(this.username, this.domain);
|
||||||
fixedUsername = false;
|
} else if (this.domain != null) {
|
||||||
jid = Jid.ofLocalAndDomainEscaped(username, this.domain);
|
fixedUsername = false;
|
||||||
} else {
|
jid = Jid.ofLocalAndDomainEscaped(username, this.domain);
|
||||||
fixedUsername = false;
|
} else {
|
||||||
jid = Jid.ofLocalAndDomainEscaped(username, Config.MAGIC_CREATE_DOMAIN);
|
fixedUsername = false;
|
||||||
}
|
jid = Jid.ofLocalAndDomainEscaped(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.KEY_PRE_AUTH_REGISTRATION_TOKEN, this.preAuth);
|
|
||||||
}
|
}
|
||||||
xmppConnectionService.createAccount(account);
|
if (!jid.getEscapedLocal().equals(jid.getLocal())
|
||||||
|
|| (this.username == null && username.length() < 3)) {
|
||||||
|
binding.usernameLayout.setError(getString(R.string.invalid_username));
|
||||||
|
binding.username.requestFocus();
|
||||||
|
} else {
|
||||||
|
binding.usernameLayout.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.KEY_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 (final IllegalArgumentException e) {
|
||||||
|
binding.usernameLayout.setError(getString(R.string.invalid_username));
|
||||||
|
binding.username.requestFocus();
|
||||||
}
|
}
|
||||||
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);
|
binding.username.addTextChangedListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,14 +128,10 @@ public class MagicCreateActivity extends XmppActivity implements TextWatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(final Editable s) {
|
public void afterTextChanged(final Editable s) {
|
||||||
|
@ -153,8 +150,10 @@ public class MagicCreateActivity extends XmppActivity implements TextWatcher {
|
||||||
} else {
|
} else {
|
||||||
jid = Jid.ofLocalAndDomainEscaped(username, this.domain);
|
jid = Jid.ofLocalAndDomainEscaped(username, this.domain);
|
||||||
}
|
}
|
||||||
binding.fullJid.setText(getString(R.string.your_full_jid_will_be, jid.toEscapedString()));
|
binding.fullJid.setText(
|
||||||
} catch (IllegalArgumentException e) {
|
getString(R.string.your_full_jid_will_be, jid.toEscapedString()));
|
||||||
|
binding.usernameLayout.setError(null);
|
||||||
|
} catch (final IllegalArgumentException e) {
|
||||||
binding.fullJid.setVisibility(View.INVISIBLE);
|
binding.fullJid.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
package eu.siacs.conversations.ui;
|
package eu.siacs.conversations.ui;
|
||||||
|
|
||||||
|
import static eu.siacs.conversations.utils.PermissionUtils.allGranted;
|
||||||
|
import static eu.siacs.conversations.utils.PermissionUtils.writeGranted;
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.security.KeyChain;
|
import android.security.KeyChain;
|
||||||
import android.security.KeyChainAliasCallback;
|
import android.security.KeyChainAliasCallback;
|
||||||
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
import android.view.ContextMenu.ContextMenuInfo;
|
||||||
|
@ -12,23 +16,17 @@ import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
import android.widget.AdapterView.AdapterContextMenuInfo;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.ActionBar;
|
import androidx.appcompat.app.ActionBar;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
import org.openintents.openpgp.util.OpenPgpApi;
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.databinding.ActivityManageAccountsBinding;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
|
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
|
||||||
|
@ -37,10 +35,17 @@ import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
import eu.siacs.conversations.xmpp.XmppConnection;
|
import eu.siacs.conversations.xmpp.XmppConnection;
|
||||||
|
|
||||||
import static eu.siacs.conversations.utils.PermissionUtils.allGranted;
|
import org.openintents.openpgp.util.OpenPgpApi;
|
||||||
import static eu.siacs.conversations.utils.PermissionUtils.writeGranted;
|
|
||||||
|
|
||||||
public class ManageAccountActivity extends XmppActivity implements OnAccountUpdate, KeyChainAliasCallback, XmppConnectionService.OnAccountCreated, AccountAdapter.OnTglAccountState {
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
public class ManageAccountActivity extends XmppActivity
|
||||||
|
implements OnAccountUpdate,
|
||||||
|
KeyChainAliasCallback,
|
||||||
|
XmppConnectionService.OnAccountCreated,
|
||||||
|
AccountAdapter.OnTglAccountState {
|
||||||
|
|
||||||
private final String STATE_SELECTED_ACCOUNT = "selected_account";
|
private final String STATE_SELECTED_ACCOUNT = "selected_account";
|
||||||
|
|
||||||
|
@ -50,7 +55,6 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
protected Jid selectedAccountJid = null;
|
protected Jid selectedAccountJid = null;
|
||||||
|
|
||||||
protected final List<Account> accountList = new ArrayList<>();
|
protected final List<Account> accountList = new ArrayList<>();
|
||||||
protected ListView accountListView;
|
|
||||||
protected AccountAdapter mAccountAdapter;
|
protected AccountAdapter mAccountAdapter;
|
||||||
protected AtomicBoolean mInvokedAddAccount = new AtomicBoolean(false);
|
protected AtomicBoolean mInvokedAddAccount = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
@ -67,7 +71,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
accountList.clear();
|
accountList.clear();
|
||||||
accountList.addAll(xmppConnectionService.getAccounts());
|
accountList.addAll(xmppConnectionService.getAccounts());
|
||||||
}
|
}
|
||||||
ActionBar actionBar = getSupportActionBar();
|
final ActionBar actionBar = getSupportActionBar();
|
||||||
if (actionBar != null) {
|
if (actionBar != null) {
|
||||||
actionBar.setHomeButtonEnabled(this.accountList.size() > 0);
|
actionBar.setHomeButtonEnabled(this.accountList.size() > 0);
|
||||||
actionBar.setDisplayHomeAsUpEnabled(this.accountList.size() > 0);
|
actionBar.setDisplayHomeAsUpEnabled(this.accountList.size() > 0);
|
||||||
|
@ -81,8 +85,11 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setContentView(R.layout.activity_manage_accounts);
|
ActivityManageAccountsBinding binding =
|
||||||
setSupportActionBar(findViewById(R.id.toolbar));
|
DataBindingUtil.setContentView(this, R.layout.activity_manage_accounts);
|
||||||
|
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
String jid = savedInstanceState.getString(STATE_SELECTED_ACCOUNT);
|
String jid = savedInstanceState.getString(STATE_SELECTED_ACCOUNT);
|
||||||
|
@ -95,26 +102,19 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
accountListView = findViewById(R.id.account_list);
|
|
||||||
this.mAccountAdapter = new AccountAdapter(this, accountList);
|
this.mAccountAdapter = new AccountAdapter(this, accountList);
|
||||||
accountListView.setAdapter(this.mAccountAdapter);
|
binding.accountList.setAdapter(this.mAccountAdapter);
|
||||||
accountListView.setOnItemClickListener((arg0, view, position, arg3) -> switchToAccount(accountList.get(position)));
|
binding.accountList.setOnItemClickListener(
|
||||||
registerForContextMenu(accountListView);
|
(arg0, view, position, arg3) -> switchToAccount(accountList.get(position)));
|
||||||
|
registerForContextMenu(binding.accountList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
final int theme = findTheme();
|
|
||||||
if (this.mTheme != theme) {
|
|
||||||
recreate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(final Bundle savedInstanceState) {
|
public void onSaveInstanceState(@NonNull final Bundle savedInstanceState) {
|
||||||
if (selectedAccount != null) {
|
if (selectedAccount != null) {
|
||||||
savedInstanceState.putString(STATE_SELECTED_ACCOUNT, selectedAccount.getJid().asBareJid().toEscapedString());
|
savedInstanceState.putString(
|
||||||
|
STATE_SELECTED_ACCOUNT, selectedAccount.getJid().asBareJid().toEscapedString());
|
||||||
}
|
}
|
||||||
super.onSaveInstanceState(savedInstanceState);
|
super.onSaveInstanceState(savedInstanceState);
|
||||||
}
|
}
|
||||||
|
@ -122,8 +122,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||||
super.onCreateContextMenu(menu, v, menuInfo);
|
super.onCreateContextMenu(menu, v, menuInfo);
|
||||||
ManageAccountActivity.this.getMenuInflater().inflate(
|
ManageAccountActivity.this.getMenuInflater().inflate(R.menu.manageaccounts_context, menu);
|
||||||
R.menu.manageaccounts_context, menu);
|
|
||||||
AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
|
AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
|
||||||
this.selectedAccount = accountList.get(acmi.position);
|
this.selectedAccount = accountList.get(acmi.position);
|
||||||
if (this.selectedAccount.isEnabled()) {
|
if (this.selectedAccount.isEnabled()) {
|
||||||
|
@ -144,9 +143,10 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
}
|
}
|
||||||
refreshUiReal();
|
refreshUiReal();
|
||||||
if (this.mPostponedActivityResult != null) {
|
if (this.mPostponedActivityResult != null) {
|
||||||
this.onActivityResult(mPostponedActivityResult.first, RESULT_OK, mPostponedActivityResult.second);
|
this.onActivityResult(
|
||||||
|
mPostponedActivityResult.first, RESULT_OK, mPostponedActivityResult.second);
|
||||||
}
|
}
|
||||||
if (Config.X509_VERIFICATION && this.accountList.size() == 0) {
|
if (Config.X509_VERIFICATION && this.accountList.isEmpty()) {
|
||||||
if (mInvokedAddAccount.compareAndSet(false, true)) {
|
if (mInvokedAddAccount.compareAndSet(false, true)) {
|
||||||
addAccountFromKey();
|
addAccountFromKey();
|
||||||
}
|
}
|
||||||
|
@ -233,9 +233,9 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
public void onRequestPermissionsResult(
|
||||||
|
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
if (grantResults.length > 0) {
|
if (grantResults.length > 0) {
|
||||||
if (allGranted(grantResults)) {
|
if (allGranted(grantResults)) {
|
||||||
|
@ -258,13 +258,14 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
@Override
|
@Override
|
||||||
public boolean onNavigateUp() {
|
public boolean onNavigateUp() {
|
||||||
if (xmppConnectionService.getConversations().size() == 0) {
|
if (xmppConnectionService.getConversations().size() == 0) {
|
||||||
Intent contactsIntent = new Intent(this,
|
Intent contactsIntent = new Intent(this, StartConversationActivity.class);
|
||||||
StartConversationActivity.class);
|
|
||||||
contactsIntent.setFlags(
|
contactsIntent.setFlags(
|
||||||
// if activity exists in stack, pop the stack and go back to it
|
// if activity exists in stack, pop the stack and go back to it
|
||||||
Intent.FLAG_ACTIVITY_CLEAR_TOP |
|
Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||||
|
|
|
||||||
// otherwise, make a new task for it
|
// otherwise, make a new task for it
|
||||||
Intent.FLAG_ACTIVITY_NEW_TASK |
|
Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
|
|
||||||
// don't use the new activity animation; finish
|
// don't use the new activity animation; finish
|
||||||
// animation runs instead
|
// animation runs instead
|
||||||
Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||||
|
@ -286,16 +287,17 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAccountFromKey() {
|
private void addAccountFromKey() {
|
||||||
|
Log.d(Config.LOGTAG, "add account from key");
|
||||||
try {
|
try {
|
||||||
KeyChain.choosePrivateKeyAlias(this, this, null, null, null, -1, null);
|
KeyChain.choosePrivateKeyAlias(this, this, null, null, null, -1, null);
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (final ActivityNotFoundException e) {
|
||||||
Toast.makeText(this, R.string.device_does_not_support_certificates, Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.device_does_not_support_certificates, Toast.LENGTH_LONG)
|
||||||
|
.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void publishAvatar(Account account) {
|
private void publishAvatar(Account account) {
|
||||||
Intent intent = new Intent(getApplicationContext(),
|
Intent intent = new Intent(getApplicationContext(), PublishProfilePictureActivity.class);
|
||||||
PublishProfilePictureActivity.class);
|
|
||||||
intent.putExtra(EXTRA_ACCOUNT, account.getJid().asBareJid().toEscapedString());
|
intent.putExtra(EXTRA_ACCOUNT, account.getJid().asBareJid().toEscapedString());
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
@ -377,7 +379,6 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
@ -385,7 +386,8 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
if (xmppConnectionServiceBound) {
|
if (xmppConnectionServiceBound) {
|
||||||
if (requestCode == REQUEST_CHOOSE_PGP_ID) {
|
if (requestCode == REQUEST_CHOOSE_PGP_ID) {
|
||||||
if (data.getExtras().containsKey(OpenPgpApi.EXTRA_SIGN_KEY_ID)) {
|
if (data.getExtras().containsKey(OpenPgpApi.EXTRA_SIGN_KEY_ID)) {
|
||||||
selectedAccount.setPgpSignId(data.getExtras().getLong(OpenPgpApi.EXTRA_SIGN_KEY_ID));
|
selectedAccount.setPgpSignId(
|
||||||
|
data.getExtras().getLong(OpenPgpApi.EXTRA_SIGN_KEY_ID));
|
||||||
announcePgp(selectedAccount, null, null, onOpenPGPKeyPublished);
|
announcePgp(selectedAccount, null, null, onOpenPGPKeyPublished);
|
||||||
} else {
|
} else {
|
||||||
choosePgpSignId(selectedAccount);
|
choosePgpSignId(selectedAccount);
|
||||||
|
@ -402,9 +404,17 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void alias(final String alias) {
|
public void alias(final String alias) {
|
||||||
if (alias != null) {
|
if (Strings.isNullOrEmpty(alias)) {
|
||||||
xmppConnectionService.createAccountFromKey(alias, this);
|
runOnUiThread(
|
||||||
|
() ->
|
||||||
|
Toast.makeText(
|
||||||
|
this,
|
||||||
|
R.string.no_certificate_selected,
|
||||||
|
Toast.LENGTH_LONG)
|
||||||
|
.show());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
xmppConnectionService.createAccountFromKey(alias, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -417,6 +427,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void informUser(final int r) {
|
public void informUser(final int r) {
|
||||||
runOnUiThread(() -> Toast.makeText(ManageAccountActivity.this, r, Toast.LENGTH_LONG).show());
|
runOnUiThread(
|
||||||
|
() -> Toast.makeText(ManageAccountActivity.this, r, Toast.LENGTH_LONG).show());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,6 @@ public class PickServerActivity extends XmppActivity {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
final int theme = findTheme();
|
|
||||||
if (this.mTheme != theme) {
|
|
||||||
recreate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
|
@ -53,7 +44,8 @@ public class PickServerActivity extends XmppActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNewIntent(Intent intent) {
|
public void onNewIntent(final Intent intent) {
|
||||||
|
super.onNewIntent(intent);
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
setIntent(intent);
|
setIntent(intent);
|
||||||
}
|
}
|
||||||
|
@ -66,6 +58,7 @@ public class PickServerActivity extends XmppActivity {
|
||||||
}
|
}
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
ActivityPickServerBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_pick_server);
|
ActivityPickServerBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_pick_server);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
binding.useCim.setOnClickListener(v -> {
|
binding.useCim.setOnClickListener(v -> {
|
||||||
|
@ -81,7 +74,7 @@ public class PickServerActivity extends XmppActivity {
|
||||||
if (accounts.size() == 1) {
|
if (accounts.size() == 1) {
|
||||||
intent.putExtra("jid", accounts.get(0).getJid().asBareJid().toString());
|
intent.putExtra("jid", accounts.get(0).getJid().asBareJid().toString());
|
||||||
intent.putExtra("init", true);
|
intent.putExtra("init", true);
|
||||||
} else if (accounts.size() >= 1) {
|
} else if (!accounts.isEmpty()) {
|
||||||
intent = new Intent(this, ManageAccountActivity.class);
|
intent = new Intent(this, ManageAccountActivity.class);
|
||||||
}
|
}
|
||||||
addInviteUri(intent);
|
addInviteUri(intent);
|
||||||
|
|
|
@ -56,15 +56,6 @@ public class ShareViaAccountActivity extends XmppActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
final int theme = findTheme();
|
|
||||||
if (this.mTheme != theme) {
|
|
||||||
recreate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onBackendConnected() {
|
void onBackendConnected() {
|
||||||
final int numAccounts = xmppConnectionService.getAccounts().size();
|
final int numAccounts = xmppConnectionService.getAccounts().size();
|
||||||
|
|
|
@ -34,7 +34,10 @@ import eu.siacs.conversations.xmpp.Jid;
|
||||||
import static eu.siacs.conversations.utils.PermissionUtils.allGranted;
|
import static eu.siacs.conversations.utils.PermissionUtils.allGranted;
|
||||||
import static eu.siacs.conversations.utils.PermissionUtils.writeGranted;
|
import static eu.siacs.conversations.utils.PermissionUtils.writeGranted;
|
||||||
|
|
||||||
public class WelcomeActivity extends XmppActivity implements XmppConnectionService.OnAccountCreated, KeyChainAliasCallback {
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
|
public class WelcomeActivity extends XmppActivity
|
||||||
|
implements XmppConnectionService.OnAccountCreated, KeyChainAliasCallback {
|
||||||
|
|
||||||
private static final int REQUEST_IMPORT_BACKUP = 0x63fb;
|
private static final int REQUEST_IMPORT_BACKUP = 0x63fb;
|
||||||
|
|
||||||
|
@ -66,7 +69,8 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
|
||||||
final Intent intent;
|
final Intent intent;
|
||||||
if (xmppUri.isAction(XmppUri.ACTION_REGISTER)) {
|
if (xmppUri.isAction(XmppUri.ACTION_REGISTER)) {
|
||||||
intent = SignupUtils.getTokenRegistrationIntent(this, jid, preAuth);
|
intent = SignupUtils.getTokenRegistrationIntent(this, jid, preAuth);
|
||||||
} else if (xmppUri.isAction(XmppUri.ACTION_ROSTER) && "y".equals(xmppUri.getParameter(XmppUri.PARAMETER_IBR))) {
|
} else if (xmppUri.isAction(XmppUri.ACTION_ROSTER)
|
||||||
|
&& "y".equals(xmppUri.getParameter(XmppUri.PARAMETER_IBR))) {
|
||||||
intent = SignupUtils.getTokenRegistrationIntent(this, jid.getDomain(), preAuth);
|
intent = SignupUtils.getTokenRegistrationIntent(this, jid.getDomain(), preAuth);
|
||||||
intent.putExtra(StartConversationActivity.EXTRA_INVITE_URI, xmppUri.toString());
|
intent.putExtra(StartConversationActivity.EXTRA_INVITE_URI, xmppUri.toString());
|
||||||
} else {
|
} else {
|
||||||
|
@ -81,22 +85,14 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void refreshUiReal() {
|
protected void refreshUiReal() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onBackendConnected() {
|
void onBackendConnected() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
final int theme = findTheme();
|
|
||||||
if (this.mTheme != theme) {
|
|
||||||
recreate();
|
|
||||||
}
|
|
||||||
new InstallReferrerUtils(this);
|
new InstallReferrerUtils(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,42 +115,44 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
|
||||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||||
}
|
}
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
ActivityWelcomeBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_welcome);
|
ActivityWelcomeBinding binding =
|
||||||
|
DataBindingUtil.setContentView(this, R.layout.activity_welcome);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar(), false);
|
configureActionBar(getSupportActionBar(), false);
|
||||||
binding.registerNewAccount.setOnClickListener(v -> {
|
setTitle(null);
|
||||||
final Intent intent = new Intent(this, PickServerActivity.class);
|
binding.registerNewAccount.setOnClickListener(
|
||||||
addInviteUri(intent);
|
v -> {
|
||||||
startActivity(intent);
|
final Intent intent = new Intent(this, PickServerActivity.class);
|
||||||
});
|
addInviteUri(intent);
|
||||||
binding.useExisting.setOnClickListener(v -> {
|
startActivity(intent);
|
||||||
final List<Account> accounts = xmppConnectionService.getAccounts();
|
});
|
||||||
Intent intent = new Intent(WelcomeActivity.this, EditAccountActivity.class);
|
binding.useExisting.setOnClickListener(
|
||||||
intent.putExtra(EditAccountActivity.EXTRA_FORCE_REGISTER, false);
|
v -> {
|
||||||
if (accounts.size() == 1) {
|
final List<Account> accounts = xmppConnectionService.getAccounts();
|
||||||
intent.putExtra("jid", accounts.get(0).getJid().asBareJid().toString());
|
Intent intent = new Intent(this, EditAccountActivity.class);
|
||||||
intent.putExtra("init", true);
|
intent.putExtra(EditAccountActivity.EXTRA_FORCE_REGISTER, false);
|
||||||
} else if (accounts.size() >= 1) {
|
if (accounts.size() == 1) {
|
||||||
intent = new Intent(WelcomeActivity.this, ManageAccountActivity.class);
|
intent.putExtra("jid", accounts.get(0).getJid().asBareJid().toString());
|
||||||
}
|
intent.putExtra("init", true);
|
||||||
addInviteUri(intent);
|
} else if (!accounts.isEmpty()) {
|
||||||
startActivity(intent);
|
intent = new Intent(this, ManageAccountActivity.class);
|
||||||
});
|
}
|
||||||
|
addInviteUri(intent);
|
||||||
|
startActivity(intent);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.welcome_menu, menu);
|
getMenuInflater().inflate(R.menu.welcome_menu, menu);
|
||||||
final MenuItem scan = menu.findItem(R.id.action_scan_qr_code);
|
final MenuItem scan = menu.findItem(R.id.action_scan_qr_code);
|
||||||
scan.setVisible(Compatibility.hasFeatureCamera(this));
|
scan.setVisible(Compatibility.hasFeatureCamera(this));
|
||||||
return super.onCreateOptionsMenu(menu);
|
return super.onCreateOptionsMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_import_backup:
|
case R.id.action_import_backup:
|
||||||
if (hasStoragePermission(REQUEST_IMPORT_BACKUP)) {
|
if (hasStoragePermission(REQUEST_IMPORT_BACKUP)) {
|
||||||
|
@ -174,16 +172,25 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
|
||||||
private void addAccountFromKey() {
|
private void addAccountFromKey() {
|
||||||
try {
|
try {
|
||||||
KeyChain.choosePrivateKeyAlias(this, this, null, null, null, -1, null);
|
KeyChain.choosePrivateKeyAlias(this, this, null, null, null, -1, null);
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (final ActivityNotFoundException e) {
|
||||||
Toast.makeText(this, R.string.device_does_not_support_certificates, Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.device_does_not_support_certificates, Toast.LENGTH_LONG)
|
||||||
|
.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void alias(final String alias) {
|
public void alias(final String alias) {
|
||||||
if (alias != null) {
|
if (Strings.isNullOrEmpty(alias)) {
|
||||||
xmppConnectionService.createAccountFromKey(alias, this);
|
runOnUiThread(
|
||||||
|
() ->
|
||||||
|
Toast.makeText(
|
||||||
|
this,
|
||||||
|
R.string.no_certificate_selected,
|
||||||
|
Toast.LENGTH_LONG)
|
||||||
|
.show());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
xmppConnectionService.createAccountFromKey(alias, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -201,7 +208,8 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
public void onRequestPermissionsResult(
|
||||||
|
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
UriHandlerActivity.onRequestPermissionResult(this, requestCode, grantResults);
|
UriHandlerActivity.onRequestPermissionResult(this, requestCode, grantResults);
|
||||||
if (grantResults.length > 0) {
|
if (grantResults.length > 0) {
|
||||||
|
@ -211,7 +219,8 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
|
||||||
startActivity(new Intent(this, ImportBackupActivity.class));
|
startActivity(new Intent(this, ImportBackupActivity.class));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (Arrays.asList(permissions).contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
} else if (Arrays.asList(permissions)
|
||||||
|
.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||||
Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,5 +241,4 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
|
||||||
to.putExtra(StartConversationActivity.EXTRA_INVITE_URI, this.inviteUri.toString());
|
to.putExtra(StartConversationActivity.EXTRA_INVITE_URI, this.inviteUri.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.List;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.AccountRowBinding;
|
import eu.siacs.conversations.databinding.ItemAccountBinding;
|
||||||
import eu.siacs.conversations.services.AvatarService;
|
import eu.siacs.conversations.services.AvatarService;
|
||||||
import eu.siacs.conversations.services.ImportBackupService;
|
import eu.siacs.conversations.services.ImportBackupService;
|
||||||
import eu.siacs.conversations.utils.BackupFileHeader;
|
import eu.siacs.conversations.utils.BackupFileHeader;
|
||||||
|
@ -39,7 +39,7 @@ public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.Ba
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public BackupFileViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
|
public BackupFileViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
|
||||||
return new BackupFileViewHolder(DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), R.layout.account_row, viewGroup, false));
|
return new BackupFileViewHolder(DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), R.layout.item_account, viewGroup, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,9 +73,9 @@ public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.Ba
|
||||||
}
|
}
|
||||||
|
|
||||||
static class BackupFileViewHolder extends RecyclerView.ViewHolder {
|
static class BackupFileViewHolder extends RecyclerView.ViewHolder {
|
||||||
private final AccountRowBinding binding;
|
private final ItemAccountBinding binding;
|
||||||
|
|
||||||
BackupFileViewHolder(AccountRowBinding binding) {
|
BackupFileViewHolder(ItemAccountBinding binding) {
|
||||||
super(binding.getRoot());
|
super(binding.getRoot());
|
||||||
this.binding = binding;
|
this.binding = binding;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.Ba
|
||||||
private Jid jid = null;
|
private Jid jid = null;
|
||||||
private final int size;
|
private final int size;
|
||||||
|
|
||||||
BitmapWorkerTask(ImageView imageView) {
|
BitmapWorkerTask(final ImageView imageView) {
|
||||||
imageViewReference = new WeakReference<>(imageView);
|
imageViewReference = new WeakReference<>(imageView);
|
||||||
DisplayMetrics metrics = imageView.getContext().getResources().getDisplayMetrics();
|
DisplayMetrics metrics = imageView.getContext().getResources().getDisplayMetrics();
|
||||||
this.size = ((int) (48 * metrics.density));
|
this.size = ((int) (48 * metrics.density));
|
||||||
|
@ -146,8 +146,7 @@ public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.Ba
|
||||||
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
|
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
|
||||||
if (imageView != null) {
|
if (imageView != null) {
|
||||||
final Drawable drawable = imageView.getDrawable();
|
final Drawable drawable = imageView.getDrawable();
|
||||||
if (drawable instanceof AsyncDrawable) {
|
if (drawable instanceof AsyncDrawable asyncDrawable) {
|
||||||
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
|
|
||||||
return asyncDrawable.getBitmapWorkerTask();
|
return asyncDrawable.getBitmapWorkerTask();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 258 B |
Binary file not shown.
Before Width: | Height: | Size: 181 B |
Binary file not shown.
Before Width: | Height: | Size: 273 B |
Binary file not shown.
Before Width: | Height: | Size: 391 B |
Binary file not shown.
Before Width: | Height: | Size: 503 B |
|
@ -1,17 +1,23 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:background="?attr/color_background_primary"
|
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/toolbar"
|
android:layout_width="match_parent"
|
||||||
layout="@layout/toolbar" />
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?attr/actionBarSize" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/in_progress"
|
android:id="@+id/in_progress"
|
||||||
|
@ -41,7 +47,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/tap_share_button_send_invite"
|
android:text="@string/tap_share_button_send_invite"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Body1" />
|
android:textAppearance="?textAppearanceBodyMedium" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/scan_the_code"
|
android:id="@+id/scan_the_code"
|
||||||
|
@ -50,7 +56,7 @@
|
||||||
android:layout_below="@+id/tap_to_share"
|
android:layout_below="@+id/tap_to_share"
|
||||||
android:layout_marginTop="24sp"
|
android:layout_marginTop="24sp"
|
||||||
android:text="@string/if_contact_is_nearby_use_qr"
|
android:text="@string/if_contact_is_nearby_use_qr"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Body1" />
|
android:textAppearance="?textAppearanceBodyMedium" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/qr_code"
|
android:id="@+id/qr_code"
|
||||||
|
@ -59,23 +65,19 @@
|
||||||
android:layout_above="@+id/share_button"
|
android:layout_above="@+id/share_button"
|
||||||
android:layout_below="@id/scan_the_code"
|
android:layout_below="@id/scan_the_code"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_margin="24sp"
|
android:layout_margin="24sp"
|
||||||
android:scaleType="fitCenter" />
|
android:scaleType="fitCenter" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/share_button"
|
android:id="@+id/share_button"
|
||||||
style="@style/Widget.Conversations.Button.Borderless"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:minWidth="0dp"
|
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingRight="16dp"
|
|
||||||
android:text="@string/share"
|
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:textColor="?attr/colorAccent" />
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:text="@string/share" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
|
@ -2,22 +2,30 @@
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<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
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:background="?attr/color_background_primary"
|
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/toolbar"
|
android:layout_width="match_parent"
|
||||||
layout="@layout/toolbar" />
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?attr/actionBarSize" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:visibility="gone"
|
|
||||||
android:id="@+id/in_progress"
|
android:id="@+id/in_progress"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center">
|
android:gravity="center"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -25,18 +33,15 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
android:id="@+id/coordinator"
|
android:id="@+id/coordinator"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:background="?attr/color_background_primary">
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/list"
|
android:id="@+id/list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="?attr/color_background_primary"
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
|
@ -7,7 +7,18 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include layout="@layout/toolbar" android:id="@+id/toolbar"/>
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/app_bar_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?attr/actionBarSize" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -16,15 +27,13 @@
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content">
|
||||||
android:background="?attr/color_background_primary">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/linearLayout"
|
android:id="@+id/linearLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:minHeight="256dp"
|
android:minHeight="256dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
@ -42,50 +51,53 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/pick_your_username"
|
android:text="@string/pick_your_username"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Title" />
|
android:textAppearance="?textAppearanceTitleLarge" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/instructions"
|
android:id="@+id/instructions"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginVertical="8dp"
|
||||||
android:text="@string/magic_create_text"
|
android:text="@string/magic_create_text"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Body1" />
|
android:textAppearance="?textAppearanceBodyMedium" />
|
||||||
|
|
||||||
<EditText
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/username"
|
android:id="@+id/username_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:hint="@string/username_hint">
|
||||||
android:hint="@string/username_hint"
|
|
||||||
android:textColor="?attr/edit_text_color"
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:inputType="textNoSuggestions" />
|
android:id="@+id/username"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:inputType="textNoSuggestions" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/full_jid"
|
android:id="@+id/full_jid"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginVertical="8dp"
|
||||||
android:text="@string/your_full_jid_will_be"
|
android:text="@string/your_full_jid_will_be"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Caption"
|
android:textAppearance="?textAppearanceLabelSmall"
|
||||||
android:visibility="invisible" />
|
android:visibility="invisible" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/create_account"
|
android:id="@+id/create_account"
|
||||||
style="@style/Widget.Conversations.Button.Borderless"
|
style="@style/Widget.Material3.Button.TonalButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="end"
|
||||||
android:text="@string/next"
|
android:text="@string/next" />
|
||||||
android:textColor="?colorAccent" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_above="@+id/linearLayout"
|
android:layout_above="@+id/linearLayout"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true">
|
||||||
android:layout_alignParentLeft="true">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
|
@ -7,7 +7,17 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include android:id="@+id/toolbar" layout="@layout/toolbar" />
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?attr/actionBarSize" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -16,15 +26,13 @@
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content">
|
||||||
android:background="?attr/color_background_primary">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/linearLayout"
|
android:id="@+id/linearLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:minHeight="256dp"
|
android:minHeight="256dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
@ -41,40 +49,38 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/pick_a_server"
|
android:text="@string/pick_a_server"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Title" />
|
android:textAppearance="?textAppearanceTitleLarge" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
android:text="@string/server_select_text"
|
android:text="@string/server_select_text"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Body1" />
|
android:textAppearance="?textAppearanceBodyMedium" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/use_cim"
|
android:id="@+id/use_cim"
|
||||||
style="@style/Widget.Conversations.Button.Borderless"
|
style="@style/Widget.Material3.Button.TonalButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="end"
|
||||||
android:text="@string/use_conversations.im"
|
android:text="@string/use_conversations.im" />
|
||||||
android:textColor="?colorAccent" />
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/use_own_provider"
|
android:id="@+id/use_own_provider"
|
||||||
style="@style/Widget.Conversations.Button.Borderless"
|
style="@style/Widget.Material3.Button.TextButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="end"
|
||||||
android:text="@string/use_own_provider"
|
android:text="@string/use_own_provider" />
|
||||||
android:textColor="?android:textColorSecondary" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_above="@+id/linearLayout"
|
android:layout_above="@+id/linearLayout"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true">
|
||||||
android:layout_alignParentLeft="true">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
@ -6,9 +6,18 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/app_bar_layout"
|
||||||
layout="@layout/toolbar" />
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?attr/actionBarSize" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -17,15 +26,13 @@
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content">
|
||||||
android:background="?attr/color_background_primary">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/linearLayout"
|
android:id="@+id/linearLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:minHeight="256dp"
|
android:minHeight="256dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
@ -42,40 +49,38 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/welcome_header"
|
android:text="@string/welcome_header"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Title" />
|
android:textAppearance="?textAppearanceTitleLarge" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
android:text="@string/do_you_have_an_account"
|
android:text="@string/do_you_have_an_account"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Body1" />
|
android:textAppearance="?textAppearanceBodyMedium" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/register_new_account"
|
android:id="@+id/register_new_account"
|
||||||
style="@style/Widget.Conversations.Button.Borderless"
|
style="@style/Widget.Material3.Button.TonalButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="end"
|
||||||
android:text="@string/create_new_account"
|
android:text="@string/create_new_account" />
|
||||||
android:textColor="?colorAccent" />
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/use_existing"
|
android:id="@+id/use_existing"
|
||||||
style="@style/Widget.Conversations.Button.Borderless"
|
style="@style/Widget.Material3.Button.TextButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="end"
|
||||||
android:text="@string/i_already_have_an_account"
|
android:text="@string/i_already_have_an_account" />
|
||||||
android:textColor="?android:textColorSecondary" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_above="@+id/linearLayout"
|
android:layout_above="@+id/linearLayout"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true">
|
||||||
android:layout_alignParentLeft="true">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<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
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -13,41 +13,35 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/enter_password_to_restore"
|
android:text="@string/enter_password_to_restore"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Body2"/>
|
android:textAppearance="?textAppearanceBodyMedium" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_marginTop="?TextSizeBody1"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="18sp"
|
||||||
android:text="@string/restore_warning"
|
android:text="@string/restore_warning"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Body1"/>
|
android:textAppearance="?textAppearanceBodyMedium" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_marginTop="?TextSizeBody1"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="18sp"
|
||||||
android:text="@string/restore_warning_continued"
|
android:text="@string/restore_warning_continued"
|
||||||
android:textAppearance="@style/TextAppearance.Conversations.Subhead.Bold"/>
|
android:textAppearance="?textAppearanceBodyMedium" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/account_password_layout"
|
android:id="@+id/account_password_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
app:passwordToggleDrawable="@drawable/visibility_toggle_drawable"
|
app:endIconMode="password_toggle">
|
||||||
app:passwordToggleEnabled="true"
|
|
||||||
app:passwordToggleTint="?android:textColorSecondary"
|
|
||||||
app:hintTextAppearance="@style/TextAppearance.Conversations.Design.Hint"
|
|
||||||
app:errorTextAppearance="@style/TextAppearance.Conversations.Design.Error">
|
|
||||||
|
|
||||||
<eu.siacs.conversations.ui.widget.TextInputEditText
|
<eu.siacs.conversations.ui.widget.TextInputEditText
|
||||||
android:id="@+id/account_password"
|
android:id="@+id/account_password"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/password"
|
android:hint="@string/password"
|
||||||
android:inputType="textPassword"
|
android:inputType="textPassword" />
|
||||||
android:textColor="?attr/edit_text_color"
|
|
||||||
style="@style/Widget.Conversations.EditText"/>
|
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_share"
|
android:id="@+id/action_share"
|
||||||
android:icon="?attr/icon_share"
|
android:icon="@drawable/ic_share_24dp"
|
||||||
android:title="@string/invite"
|
android:title="@string/invite"
|
||||||
app:showAsAction="always" />
|
app:showAsAction="always" />
|
||||||
</menu>
|
</menu>
|
|
@ -1,32 +1,31 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu 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">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_add_account"
|
android:id="@+id/action_add_account"
|
||||||
android:icon="?attr/icon_add_person"
|
android:icon="@drawable/ic_person_add_24dp"
|
||||||
app:showAsAction="always"
|
android:title="@string/action_add_account"
|
||||||
android:title="@string/action_add_account"/>
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_import_backup"
|
android:id="@+id/action_import_backup"
|
||||||
app:showAsAction="never"
|
android:title="@string/restore_backup"
|
||||||
android:title="@string/restore_backup"/>
|
app:showAsAction="never" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_add_account_with_cert"
|
android:id="@+id/action_add_account_with_cert"
|
||||||
app:showAsAction="never"
|
android:title="@string/action_add_account_with_certificate"
|
||||||
android:icon="?attr/icon_add_person"
|
android:visible="true"
|
||||||
android:title="@string/action_add_account_with_certificate"
|
app:showAsAction="never" />
|
||||||
android:visible="true"/>
|
<item
|
||||||
<item
|
android:id="@+id/action_enable_all"
|
||||||
android:id="@+id/action_enable_all"
|
android:title="@string/enable_all_accounts" />
|
||||||
android:title="@string/enable_all_accounts"/>
|
<item
|
||||||
<item
|
android:id="@+id/action_disable_all"
|
||||||
android:id="@+id/action_disable_all"
|
android:title="@string/disable_all_accounts" />
|
||||||
android:title="@string/disable_all_accounts"/>
|
<item
|
||||||
<item
|
android:id="@+id/action_settings"
|
||||||
android:id="@+id/action_settings"
|
android:orderInCategory="100"
|
||||||
android:orderInCategory="100"
|
android:title="@string/action_settings"
|
||||||
app:showAsAction="never"
|
app:showAsAction="never" />
|
||||||
android:title="@string/action_settings"/>
|
|
||||||
|
|
||||||
</menu>
|
</menu>
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_scan_qr_code"
|
android:id="@+id/action_scan_qr_code"
|
||||||
android:icon="?attr/icon_scan_qr_code"
|
android:icon="@drawable/ic_qr_code_scanner_24dp"
|
||||||
android:orderInCategory="10"
|
android:orderInCategory="10"
|
||||||
android:title="@string/scan_qr_code"
|
android:title="@string/scan_qr_code"
|
||||||
android:visible="@bool/show_qr_code_scan"
|
android:visible="@bool/show_qr_code_scan"
|
||||||
|
|
63
src/conversations/res/values/colors-themed.xml
Normal file
63
src/conversations/res/values/colors-themed.xml
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="md_theme_light_primary">#006E1C</color>
|
||||||
|
<color name="md_theme_light_onPrimary">#FFFFFF</color>
|
||||||
|
<color name="md_theme_light_primaryContainer">#98F994</color>
|
||||||
|
<color name="md_theme_light_onPrimaryContainer">#002204</color>
|
||||||
|
<color name="md_theme_light_secondary">#52634F</color>
|
||||||
|
<color name="md_theme_light_onSecondary">#FFFFFF</color>
|
||||||
|
<color name="md_theme_light_secondaryContainer">#D5E8CF</color>
|
||||||
|
<color name="md_theme_light_onSecondaryContainer">#111F0F</color>
|
||||||
|
<color name="md_theme_light_tertiary">#38656A</color>
|
||||||
|
<color name="md_theme_light_onTertiary">#FFFFFF</color>
|
||||||
|
<color name="md_theme_light_tertiaryContainer">#BCEBF0</color>
|
||||||
|
<color name="md_theme_light_onTertiaryContainer">#002023</color>
|
||||||
|
<color name="md_theme_light_error">#BA1A1A</color>
|
||||||
|
<color name="md_theme_light_errorContainer">#FFDAD6</color>
|
||||||
|
<color name="md_theme_light_onError">#FFFFFF</color>
|
||||||
|
<color name="md_theme_light_onErrorContainer">#410002</color>
|
||||||
|
<color name="md_theme_light_background">#FCFDF6</color>
|
||||||
|
<color name="md_theme_light_onBackground">#1A1C19</color>
|
||||||
|
<color name="md_theme_light_surface">#FCFDF6</color>
|
||||||
|
<color name="md_theme_light_onSurface">#1A1C19</color>
|
||||||
|
<color name="md_theme_light_surfaceVariant">#DEE5D8</color>
|
||||||
|
<color name="md_theme_light_onSurfaceVariant">#424940</color>
|
||||||
|
<color name="md_theme_light_outline">#72796F</color>
|
||||||
|
<color name="md_theme_light_inverseOnSurface">#F0F1EB</color>
|
||||||
|
<color name="md_theme_light_inverseSurface">#2F312D</color>
|
||||||
|
<color name="md_theme_light_inversePrimary">#7DDC7A</color>
|
||||||
|
<color name="md_theme_light_shadow">#000000</color>
|
||||||
|
<color name="md_theme_light_surfaceTint">#006E1C</color>
|
||||||
|
<color name="md_theme_light_outlineVariant">#C2C9BD</color>
|
||||||
|
<color name="md_theme_light_scrim">#000000</color>
|
||||||
|
<color name="md_theme_dark_primary">#7DDC7A</color>
|
||||||
|
<color name="md_theme_dark_onPrimary">#00390A</color>
|
||||||
|
<color name="md_theme_dark_primaryContainer">#005313</color>
|
||||||
|
<color name="md_theme_dark_onPrimaryContainer">#98F994</color>
|
||||||
|
<color name="md_theme_dark_secondary">#BACCB3</color>
|
||||||
|
<color name="md_theme_dark_onSecondary">#253423</color>
|
||||||
|
<color name="md_theme_dark_secondaryContainer">#3B4B38</color>
|
||||||
|
<color name="md_theme_dark_onSecondaryContainer">#D5E8CF</color>
|
||||||
|
<color name="md_theme_dark_tertiary">#A0CFD4</color>
|
||||||
|
<color name="md_theme_dark_onTertiary">#00363B</color>
|
||||||
|
<color name="md_theme_dark_tertiaryContainer">#1F4D52</color>
|
||||||
|
<color name="md_theme_dark_onTertiaryContainer">#BCEBF0</color>
|
||||||
|
<color name="md_theme_dark_error">#FFB4AB</color>
|
||||||
|
<color name="md_theme_dark_errorContainer">#93000A</color>
|
||||||
|
<color name="md_theme_dark_onError">#690005</color>
|
||||||
|
<color name="md_theme_dark_onErrorContainer">#FFDAD6</color>
|
||||||
|
<color name="md_theme_dark_background">#1A1C19</color>
|
||||||
|
<color name="md_theme_dark_onBackground">#E2E3DD</color>
|
||||||
|
<color name="md_theme_dark_surface">#1A1C19</color>
|
||||||
|
<color name="md_theme_dark_onSurface">#E2E3DD</color>
|
||||||
|
<color name="md_theme_dark_surfaceVariant">#424940</color>
|
||||||
|
<color name="md_theme_dark_onSurfaceVariant">#C2C9BD</color>
|
||||||
|
<color name="md_theme_dark_outline">#8C9388</color>
|
||||||
|
<color name="md_theme_dark_inverseOnSurface">#1A1C19</color>
|
||||||
|
<color name="md_theme_dark_inverseSurface">#E2E3DD</color>
|
||||||
|
<color name="md_theme_dark_inversePrimary">#006E1C</color>
|
||||||
|
<color name="md_theme_dark_shadow">#000000</color>
|
||||||
|
<color name="md_theme_dark_surfaceTint">#7DDC7A</color>
|
||||||
|
<color name="md_theme_dark_outlineVariant">#424940</color>
|
||||||
|
<color name="md_theme_dark_scrim">#000000</color>
|
||||||
|
</resources>
|
|
@ -47,7 +47,7 @@
|
||||||
<!-- this foreground service type permission is exclusively used for import and export backup -->
|
<!-- this foreground service type permission is exclusively used for import and export backup -->
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS"/>
|
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
|
||||||
|
|
||||||
<uses-feature
|
<uses-feature
|
||||||
android:name="android.hardware.camera"
|
android:name="android.hardware.camera"
|
||||||
|
@ -84,6 +84,7 @@
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:name=".Conversations"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:appCategory="social"
|
android:appCategory="social"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
android:networkSecurityConfig="@xml/network_security_configuration"
|
android:networkSecurityConfig="@xml/network_security_configuration"
|
||||||
android:preserveLegacyExternalStorage="true"
|
android:preserveLegacyExternalStorage="true"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:theme="@style/ConversationsTheme"
|
android:theme="@style/Theme.Conversations3"
|
||||||
tools:targetApi="tiramisu">
|
tools:targetApi="tiramisu">
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
|
@ -132,9 +133,10 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service android:name=".services.CallIntegrationConnectionService"
|
<service
|
||||||
android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
|
android:name=".services.CallIntegrationConnectionService"
|
||||||
android:exported="true">
|
android:exported="true"
|
||||||
|
android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.telecom.ConnectionService" />
|
<action android:name="android.telecom.ConnectionService" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
@ -180,14 +182,14 @@
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.RecordingActivity"
|
android:name=".ui.RecordingActivity"
|
||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
android:theme="@style/ConversationsTheme.Dialog" />
|
android:theme="@style/Theme.Conversations3.Dialog" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ShowLocationActivity"
|
android:name=".ui.ShowLocationActivity"
|
||||||
android:label="@string/title_activity_show_location" />
|
android:label="@string/title_activity_show_location" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ConversationActivity"
|
android:name=".ui.ConversationActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:theme="@style/SplashTheme">
|
android:theme="@style/Theme.Conversations3.SplashScreen">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
@ -202,7 +204,7 @@
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ScanActivity"
|
android:name=".ui.ScanActivity"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/ConversationsTheme.FullScreen"
|
android:theme="@style/Theme.Conversations3.FullScreen"
|
||||||
android:windowSoftInputMode="stateAlwaysHidden" />
|
android:windowSoftInputMode="stateAlwaysHidden" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.UriHandlerActivity"
|
android:name=".ui.UriHandlerActivity"
|
||||||
|
@ -263,10 +265,10 @@
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ChooseContactActivity"
|
android:name=".ui.ChooseContactActivity"
|
||||||
android:label="@string/title_activity_choose_contact" />
|
android:label="@string/title_activity_choose_contact"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.BlocklistActivity"
|
android:name=".ui.BlocklistActivity"
|
||||||
android:label="@string/title_activity_block_list" />
|
android:label="@string/title_activity_block_list"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ChangePasswordActivity"
|
android:name=".ui.ChangePasswordActivity"
|
||||||
android:label="@string/change_password_on_server" />
|
android:label="@string/change_password_on_server" />
|
||||||
|
@ -351,7 +353,7 @@
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.MediaBrowserActivity"
|
android:name=".ui.MediaBrowserActivity"
|
||||||
android:label="@string/media_browser" />
|
android:label="@string/media_browser"/>
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
@ -378,10 +380,10 @@
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.MucUsersActivity"
|
android:name=".ui.MucUsersActivity"
|
||||||
android:label="@string/group_chat_members" />
|
android:label="@string/group_chat_members"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ChannelDiscoveryActivity"
|
android:name=".ui.ChannelDiscoveryActivity"
|
||||||
android:label="@string/discover_channels" />
|
android:label="@string/discover_channels"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.RtpSessionActivity"
|
android:name=".ui.RtpSessionActivity"
|
||||||
android:autoRemoveFromRecents="true"
|
android:autoRemoveFromRecents="true"
|
||||||
|
|
|
@ -45,8 +45,6 @@ public final class Config {
|
||||||
|
|
||||||
public static final Jid BUG_REPORTS = Jid.of("bugs@conversations.im");
|
public static final Jid BUG_REPORTS = Jid.of("bugs@conversations.im");
|
||||||
public static final Uri HELP = Uri.parse("https://help.conversations.im");
|
public static final Uri HELP = Uri.parse("https://help.conversations.im");
|
||||||
|
|
||||||
public static final String DOMAIN_LOCK = null; // only allow account creation for this domain
|
|
||||||
public static final String MAGIC_CREATE_DOMAIN = "conversations.im";
|
public static final String MAGIC_CREATE_DOMAIN = "conversations.im";
|
||||||
public static final Jid QUICKSY_DOMAIN = Jid.of("quicksy.im");
|
public static final Jid QUICKSY_DOMAIN = Jid.of("quicksy.im");
|
||||||
|
|
||||||
|
|
67
src/main/java/eu/siacs/conversations/Conversations.java
Normal file
67
src/main/java/eu/siacs/conversations/Conversations.java
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package eu.siacs.conversations;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate;
|
||||||
|
|
||||||
|
import com.google.android.material.color.DynamicColors;
|
||||||
|
import com.google.android.material.color.DynamicColorsOptions;
|
||||||
|
|
||||||
|
public class Conversations extends Application {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
applyThemeSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyThemeSettings() {
|
||||||
|
final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
if (sharedPreferences == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
applyThemeSettings(sharedPreferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyThemeSettings(final SharedPreferences sharedPreferences) {
|
||||||
|
AppCompatDelegate.setDefaultNightMode(getDesiredNightMode(this, sharedPreferences));
|
||||||
|
var dynamicColorsOptions =
|
||||||
|
new DynamicColorsOptions.Builder()
|
||||||
|
.setPrecondition((activity, t) -> isDynamicColorsDesired(activity))
|
||||||
|
.build();
|
||||||
|
DynamicColors.applyToActivitiesIfAvailable(this, dynamicColorsOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getDesiredNightMode(final Context context) {
|
||||||
|
final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
if (sharedPreferences == null) {
|
||||||
|
return AppCompatDelegate.getDefaultNightMode();
|
||||||
|
}
|
||||||
|
return getDesiredNightMode(context, sharedPreferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDynamicColorsDesired(final Context context) {
|
||||||
|
final var preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
return preferences.getBoolean("dynamic_colors", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getDesiredNightMode(
|
||||||
|
final Context context, final SharedPreferences sharedPreferences) {
|
||||||
|
final String theme =
|
||||||
|
sharedPreferences.getString("theme", context.getString(R.string.theme));
|
||||||
|
return getDesiredNightMode(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getDesiredNightMode(final String theme) {
|
||||||
|
if ("automatic".equals(theme)) {
|
||||||
|
return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
||||||
|
} else if ("light".equals(theme)) {
|
||||||
|
return AppCompatDelegate.MODE_NIGHT_NO;
|
||||||
|
} else {
|
||||||
|
return AppCompatDelegate.MODE_NIGHT_YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,18 +41,18 @@ public class RtpSessionStatus {
|
||||||
return new RtpSessionStatus(made, duration);
|
return new RtpSessionStatus(made, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @DrawableRes int getDrawable(final boolean received, final boolean successful, final boolean darkTheme) {
|
public static @DrawableRes int getDrawable(final boolean received, final boolean successful) {
|
||||||
if (received) {
|
if (received) {
|
||||||
if (successful) {
|
if (successful) {
|
||||||
return darkTheme ? R.drawable.ic_call_received_white_18dp : R.drawable.ic_call_received_black_18dp;
|
return R.drawable.ic_call_received_24dp;
|
||||||
} else {
|
} else {
|
||||||
return darkTheme ? R.drawable.ic_call_missed_white_18dp : R.drawable.ic_call_missed_black_18dp;
|
return R.drawable.ic_call_missed_24db;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (successful) {
|
if (successful) {
|
||||||
return darkTheme ? R.drawable.ic_call_made_white_18dp : R.drawable.ic_call_made_black_18dp;
|
return R.drawable.ic_call_made_24dp;
|
||||||
} else {
|
} else {
|
||||||
return darkTheme ? R.drawable.ic_call_missed_outgoing_white_18dp : R.drawable.ic_call_missed_outgoing_black_18dp;
|
return R.drawable.ic_call_missed_outgoing_24dp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,11 @@ public class BarcodeProvider extends ContentProvider implements ServiceConnectio
|
||||||
return Uri.parse("content://" + packageId + AUTHORITY + "/" + account.getJid().asBareJid() + ".png");
|
return Uri.parse("content://" + packageId + AUTHORITY + "/" + account.getJid().asBareJid() + ".png");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bitmap create2dBarcodeBitmap(String input, int size) {
|
public static Bitmap create2dBarcodeBitmap(final String input, final int size) {
|
||||||
|
return create2dBarcodeBitmap(input, size, Color.BLACK, Color.WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap create2dBarcodeBitmap(final String input, final int size, final int black, final int white) {
|
||||||
try {
|
try {
|
||||||
final QRCodeWriter barcodeWriter = new QRCodeWriter();
|
final QRCodeWriter barcodeWriter = new QRCodeWriter();
|
||||||
final Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
|
final Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
|
||||||
|
@ -61,14 +65,14 @@ public class BarcodeProvider extends ContentProvider implements ServiceConnectio
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
final int offset = y * width;
|
final int offset = y * width;
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.WHITE;
|
pixels[offset + x] = result.get(x, y) ? black : white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||||
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
|
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
|
||||||
return bitmap;
|
return bitmap;
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
e.printStackTrace();
|
Log.e(Config.LOGTAG,"could not generate QR code image",e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,7 +266,7 @@ public class ExportBackupService extends Service {
|
||||||
NotificationCompat.Builder mBuilder =
|
NotificationCompat.Builder mBuilder =
|
||||||
new NotificationCompat.Builder(getBaseContext(), "backup");
|
new NotificationCompat.Builder(getBaseContext(), "backup");
|
||||||
mBuilder.setContentTitle(getString(R.string.notification_create_backup_title))
|
mBuilder.setContentTitle(getString(R.string.notification_create_backup_title))
|
||||||
.setSmallIcon(R.drawable.ic_archive_white_24dp)
|
.setSmallIcon(R.drawable.ic_archive_24dp)
|
||||||
.setProgress(1, 0, false);
|
.setProgress(1, 0, false);
|
||||||
startForeground(NOTIFICATION_ID, mBuilder.build());
|
startForeground(NOTIFICATION_ID, mBuilder.build());
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -420,11 +420,11 @@ public class ExportBackupService extends Service {
|
||||||
.getAbsolutePath())))
|
.getAbsolutePath())))
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setContentIntent(openFolderIntent)
|
.setContentIntent(openFolderIntent)
|
||||||
.setSmallIcon(R.drawable.ic_archive_white_24dp);
|
.setSmallIcon(R.drawable.ic_archive_24dp);
|
||||||
|
|
||||||
if (shareFilesIntent != null) {
|
if (shareFilesIntent != null) {
|
||||||
mBuilder.addAction(
|
mBuilder.addAction(
|
||||||
R.drawable.ic_share_white_24dp,
|
R.drawable.ic_share_24dp,
|
||||||
getString(R.string.share_backup_files),
|
getString(R.string.share_backup_files),
|
||||||
shareFilesIntent);
|
shareFilesIntent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -475,7 +475,7 @@ public class NotificationService {
|
||||||
new Builder(mXmppConnectionService, "delivery_failed")
|
new Builder(mXmppConnectionService, "delivery_failed")
|
||||||
.setContentTitle(conversation.getName())
|
.setContentTitle(conversation.getName())
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setSmallIcon(R.drawable.ic_error_white_24dp)
|
.setSmallIcon(R.drawable.ic_error_24dp)
|
||||||
.setContentText(
|
.setContentText(
|
||||||
mXmppConnectionService
|
mXmppConnectionService
|
||||||
.getResources()
|
.getResources()
|
||||||
|
@ -495,7 +495,7 @@ public class NotificationService {
|
||||||
.getQuantityText(
|
.getQuantityText(
|
||||||
R.plurals.some_messages_could_not_be_delivered,
|
R.plurals.some_messages_could_not_be_delivered,
|
||||||
1024))
|
1024))
|
||||||
.setSmallIcon(R.drawable.ic_error_white_24dp)
|
.setSmallIcon(R.drawable.ic_error_24dp)
|
||||||
.setGroup("delivery_failed")
|
.setGroup("delivery_failed")
|
||||||
.setGroupSummary(true)
|
.setGroupSummary(true)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
|
@ -569,11 +569,11 @@ public class NotificationService {
|
||||||
new NotificationCompat.Builder(
|
new NotificationCompat.Builder(
|
||||||
mXmppConnectionService, INCOMING_CALLS_NOTIFICATION_CHANNEL);
|
mXmppConnectionService, INCOMING_CALLS_NOTIFICATION_CHANNEL);
|
||||||
if (media.contains(Media.VIDEO)) {
|
if (media.contains(Media.VIDEO)) {
|
||||||
builder.setSmallIcon(R.drawable.ic_videocam_white_24dp);
|
builder.setSmallIcon(R.drawable.ic_videocam_24dp);
|
||||||
builder.setContentTitle(
|
builder.setContentTitle(
|
||||||
mXmppConnectionService.getString(R.string.rtp_state_incoming_video_call));
|
mXmppConnectionService.getString(R.string.rtp_state_incoming_video_call));
|
||||||
} else {
|
} else {
|
||||||
builder.setSmallIcon(R.drawable.ic_call_white_24dp);
|
builder.setSmallIcon(R.drawable.ic_call_24dp);
|
||||||
builder.setContentTitle(
|
builder.setContentTitle(
|
||||||
mXmppConnectionService.getString(R.string.rtp_state_incoming_call));
|
mXmppConnectionService.getString(R.string.rtp_state_incoming_call));
|
||||||
}
|
}
|
||||||
|
@ -596,7 +596,7 @@ public class NotificationService {
|
||||||
builder.setOngoing(true);
|
builder.setOngoing(true);
|
||||||
builder.addAction(
|
builder.addAction(
|
||||||
new NotificationCompat.Action.Builder(
|
new NotificationCompat.Action.Builder(
|
||||||
R.drawable.ic_call_end_white_48dp,
|
R.drawable.ic_call_end_24dp,
|
||||||
mXmppConnectionService.getString(R.string.dismiss_call),
|
mXmppConnectionService.getString(R.string.dismiss_call),
|
||||||
createCallAction(
|
createCallAction(
|
||||||
id.sessionId,
|
id.sessionId,
|
||||||
|
@ -605,7 +605,7 @@ public class NotificationService {
|
||||||
.build());
|
.build());
|
||||||
builder.addAction(
|
builder.addAction(
|
||||||
new NotificationCompat.Action.Builder(
|
new NotificationCompat.Action.Builder(
|
||||||
R.drawable.ic_call_white_24dp,
|
R.drawable.ic_call_24dp,
|
||||||
mXmppConnectionService.getString(R.string.answer_call),
|
mXmppConnectionService.getString(R.string.answer_call),
|
||||||
createPendingRtpSession(
|
createPendingRtpSession(
|
||||||
id, RtpSessionActivity.ACTION_ACCEPT_CALL, 103))
|
id, RtpSessionActivity.ACTION_ACCEPT_CALL, 103))
|
||||||
|
@ -622,7 +622,7 @@ public class NotificationService {
|
||||||
final NotificationCompat.Builder builder =
|
final NotificationCompat.Builder builder =
|
||||||
new NotificationCompat.Builder(mXmppConnectionService, "ongoing_calls");
|
new NotificationCompat.Builder(mXmppConnectionService, "ongoing_calls");
|
||||||
if (ongoingCall.media.contains(Media.VIDEO)) {
|
if (ongoingCall.media.contains(Media.VIDEO)) {
|
||||||
builder.setSmallIcon(R.drawable.ic_videocam_white_24dp);
|
builder.setSmallIcon(R.drawable.ic_videocam_24dp);
|
||||||
if (ongoingCall.reconnecting) {
|
if (ongoingCall.reconnecting) {
|
||||||
builder.setContentTitle(
|
builder.setContentTitle(
|
||||||
mXmppConnectionService.getString(R.string.reconnecting_video_call));
|
mXmppConnectionService.getString(R.string.reconnecting_video_call));
|
||||||
|
@ -631,7 +631,7 @@ public class NotificationService {
|
||||||
mXmppConnectionService.getString(R.string.ongoing_video_call));
|
mXmppConnectionService.getString(R.string.ongoing_video_call));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
builder.setSmallIcon(R.drawable.ic_call_white_24dp);
|
builder.setSmallIcon(R.drawable.ic_call_24dp);
|
||||||
if (ongoingCall.reconnecting) {
|
if (ongoingCall.reconnecting) {
|
||||||
builder.setContentTitle(
|
builder.setContentTitle(
|
||||||
mXmppConnectionService.getString(R.string.reconnecting_call));
|
mXmppConnectionService.getString(R.string.reconnecting_call));
|
||||||
|
@ -647,7 +647,7 @@ public class NotificationService {
|
||||||
builder.setOngoing(true);
|
builder.setOngoing(true);
|
||||||
builder.addAction(
|
builder.addAction(
|
||||||
new NotificationCompat.Action.Builder(
|
new NotificationCompat.Action.Builder(
|
||||||
R.drawable.ic_call_end_white_48dp,
|
R.drawable.ic_call_end_24dp,
|
||||||
mXmppConnectionService.getString(R.string.hang_up),
|
mXmppConnectionService.getString(R.string.hang_up),
|
||||||
createCallAction(
|
createCallAction(
|
||||||
id.sessionId, XmppConnectionService.ACTION_END_CALL, 104))
|
id.sessionId, XmppConnectionService.ACTION_END_CALL, 104))
|
||||||
|
@ -826,7 +826,7 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markAsReadIfHasDirectReply(final ArrayList<Message> messages) {
|
private void markAsReadIfHasDirectReply(final ArrayList<Message> messages) {
|
||||||
if (messages != null && messages.size() > 0) {
|
if (messages != null && !messages.isEmpty()) {
|
||||||
Message last = messages.get(messages.size() - 1);
|
Message last = messages.get(messages.size() - 1);
|
||||||
if (last.getStatus() != Message.STATUS_RECEIVED) {
|
if (last.getStatus() != Message.STATUS_RECEIVED) {
|
||||||
if (mXmppConnectionService.markRead((Conversation) last.getConversation(), false)) {
|
if (mXmppConnectionService.markRead((Conversation) last.getConversation(), false)) {
|
||||||
|
@ -837,7 +837,8 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setNotificationColor(final Builder mBuilder) {
|
private void setNotificationColor(final Builder mBuilder) {
|
||||||
mBuilder.setColor(ContextCompat.getColor(mXmppConnectionService, R.color.green600));
|
// TODO can we use themed colors?
|
||||||
|
mBuilder.setColor(ContextCompat.getColor(mXmppConnectionService, R.color.md_theme_light_primary));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateNotification() {
|
public void updateNotification() {
|
||||||
|
@ -1035,7 +1036,7 @@ public class NotificationService {
|
||||||
if (!publicVersion) {
|
if (!publicVersion) {
|
||||||
builder.setContentText(Joiner.on(", ").join(names));
|
builder.setContentText(Joiner.on(", ").join(names));
|
||||||
}
|
}
|
||||||
builder.setSmallIcon(R.drawable.ic_call_missed_white_24db);
|
builder.setSmallIcon(R.drawable.ic_call_missed_24db);
|
||||||
builder.setGroupSummary(true);
|
builder.setGroupSummary(true);
|
||||||
builder.setGroup(MISSED_CALLS_GROUP);
|
builder.setGroup(MISSED_CALLS_GROUP);
|
||||||
builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN);
|
builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN);
|
||||||
|
@ -1085,7 +1086,7 @@ public class NotificationService {
|
||||||
name));
|
name));
|
||||||
builder.setContentText(name);
|
builder.setContentText(name);
|
||||||
}
|
}
|
||||||
builder.setSmallIcon(R.drawable.ic_call_missed_white_24db);
|
builder.setSmallIcon(R.drawable.ic_call_missed_24db);
|
||||||
builder.setGroup(MISSED_CALLS_GROUP);
|
builder.setGroup(MISSED_CALLS_GROUP);
|
||||||
builder.setCategory(NotificationCompat.CATEGORY_CALL);
|
builder.setCategory(NotificationCompat.CATEGORY_CALL);
|
||||||
builder.setWhen(info.getLastTime());
|
builder.setWhen(info.getLastTime());
|
||||||
|
@ -1221,7 +1222,7 @@ public class NotificationService {
|
||||||
PendingIntent markAsReadPendingIntent = createReadPendingIntent(conversation);
|
PendingIntent markAsReadPendingIntent = createReadPendingIntent(conversation);
|
||||||
NotificationCompat.Action markReadAction =
|
NotificationCompat.Action markReadAction =
|
||||||
new NotificationCompat.Action.Builder(
|
new NotificationCompat.Action.Builder(
|
||||||
R.drawable.ic_drafts_white_24dp,
|
R.drawable.ic_mark_chat_read_24dp,
|
||||||
mXmppConnectionService.getString(R.string.mark_as_read),
|
mXmppConnectionService.getString(R.string.mark_as_read),
|
||||||
markAsReadPendingIntent)
|
markAsReadPendingIntent)
|
||||||
.setSemanticAction(
|
.setSemanticAction(
|
||||||
|
@ -1232,7 +1233,7 @@ public class NotificationService {
|
||||||
final String lastMessageUuid = Iterables.getLast(messages).getUuid();
|
final String lastMessageUuid = Iterables.getLast(messages).getUuid();
|
||||||
final NotificationCompat.Action replyAction =
|
final NotificationCompat.Action replyAction =
|
||||||
new NotificationCompat.Action.Builder(
|
new NotificationCompat.Action.Builder(
|
||||||
R.drawable.ic_send_text_offline,
|
R.drawable.ic_send_24dp,
|
||||||
replyLabel,
|
replyLabel,
|
||||||
createReplyIntent(conversation, lastMessageUuid, false))
|
createReplyIntent(conversation, lastMessageUuid, false))
|
||||||
.setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY)
|
.setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY)
|
||||||
|
@ -1241,7 +1242,7 @@ public class NotificationService {
|
||||||
.build();
|
.build();
|
||||||
final NotificationCompat.Action wearReplyAction =
|
final NotificationCompat.Action wearReplyAction =
|
||||||
new NotificationCompat.Action.Builder(
|
new NotificationCompat.Action.Builder(
|
||||||
R.drawable.ic_wear_reply,
|
R.drawable.ic_reply_24dp,
|
||||||
replyLabel,
|
replyLabel,
|
||||||
createReplyIntent(conversation, lastMessageUuid, true))
|
createReplyIntent(conversation, lastMessageUuid, true))
|
||||||
.addRemoteInput(remoteInput)
|
.addRemoteInput(remoteInput)
|
||||||
|
@ -1260,7 +1261,7 @@ public class NotificationService {
|
||||||
PendingIntent pendingSnoozeIntent = createSnoozeIntent(conversation);
|
PendingIntent pendingSnoozeIntent = createSnoozeIntent(conversation);
|
||||||
NotificationCompat.Action snoozeAction =
|
NotificationCompat.Action snoozeAction =
|
||||||
new NotificationCompat.Action.Builder(
|
new NotificationCompat.Action.Builder(
|
||||||
R.drawable.ic_notifications_paused_white_24dp,
|
R.drawable.ic_notifications_paused_24dp,
|
||||||
label,
|
label,
|
||||||
pendingSnoozeIntent)
|
pendingSnoozeIntent)
|
||||||
.build();
|
.build();
|
||||||
|
@ -1279,7 +1280,7 @@ public class NotificationService {
|
||||||
.getString(R.string.show_location);
|
.getString(R.string.show_location);
|
||||||
NotificationCompat.Action locationAction =
|
NotificationCompat.Action locationAction =
|
||||||
new NotificationCompat.Action.Builder(
|
new NotificationCompat.Action.Builder(
|
||||||
R.drawable.ic_room_white_24dp,
|
R.drawable.ic_location_pin_24dp,
|
||||||
label,
|
label,
|
||||||
pendingShowLocationIntent)
|
pendingShowLocationIntent)
|
||||||
.build();
|
.build();
|
||||||
|
@ -1303,7 +1304,7 @@ public class NotificationService {
|
||||||
createDownloadIntent(firstDownloadableMessage);
|
createDownloadIntent(firstDownloadableMessage);
|
||||||
NotificationCompat.Action downloadAction =
|
NotificationCompat.Action downloadAction =
|
||||||
new NotificationCompat.Action.Builder(
|
new NotificationCompat.Action.Builder(
|
||||||
R.drawable.ic_file_download_white_24dp,
|
R.drawable.ic_download_24dp,
|
||||||
label,
|
label,
|
||||||
pendingDownloadIntent)
|
pendingDownloadIntent)
|
||||||
.build();
|
.build();
|
||||||
|
@ -1761,21 +1762,21 @@ public class NotificationService {
|
||||||
.setPriority(Notification.PRIORITY_MIN)
|
.setPriority(Notification.PRIORITY_MIN)
|
||||||
.setSmallIcon(
|
.setSmallIcon(
|
||||||
connected > 0
|
connected > 0
|
||||||
? R.drawable.ic_link_white_24dp
|
? R.drawable.ic_link_24dp
|
||||||
: R.drawable.ic_link_off_white_24dp)
|
: R.drawable.ic_link_off_24dp)
|
||||||
.setLocalOnly(true);
|
.setLocalOnly(true);
|
||||||
|
|
||||||
if (Compatibility.runsTwentySix()) {
|
if (Compatibility.runsTwentySix()) {
|
||||||
mBuilder.setChannelId("foreground");
|
mBuilder.setChannelId("foreground");
|
||||||
mBuilder.addAction(
|
mBuilder.addAction(
|
||||||
R.drawable.ic_logout_white_24dp,
|
R.drawable.ic_logout_24dp,
|
||||||
mXmppConnectionService.getString(R.string.log_out),
|
mXmppConnectionService.getString(R.string.log_out),
|
||||||
pendingServiceIntent(
|
pendingServiceIntent(
|
||||||
mXmppConnectionService,
|
mXmppConnectionService,
|
||||||
XmppConnectionService.ACTION_TEMPORARILY_DISABLE,
|
XmppConnectionService.ACTION_TEMPORARILY_DISABLE,
|
||||||
87));
|
87));
|
||||||
mBuilder.addAction(
|
mBuilder.addAction(
|
||||||
R.drawable.ic_notifications_off_white_24dp,
|
R.drawable.ic_notifications_off_24dp,
|
||||||
mXmppConnectionService.getString(R.string.hide_notification),
|
mXmppConnectionService.getString(R.string.hide_notification),
|
||||||
pendingNotificationSettingsIntent(mXmppConnectionService));
|
pendingNotificationSettingsIntent(mXmppConnectionService));
|
||||||
}
|
}
|
||||||
|
@ -1853,7 +1854,7 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mBuilder.addAction(
|
mBuilder.addAction(
|
||||||
R.drawable.ic_autorenew_white_24dp,
|
R.drawable.ic_autorenew_24dp,
|
||||||
mXmppConnectionService.getString(R.string.try_again),
|
mXmppConnectionService.getString(R.string.try_again),
|
||||||
pendingServiceIntent(
|
pendingServiceIntent(
|
||||||
mXmppConnectionService, XmppConnectionService.ACTION_TRY_AGAIN, 45));
|
mXmppConnectionService, XmppConnectionService.ACTION_TRY_AGAIN, 45));
|
||||||
|
@ -1871,7 +1872,7 @@ public class NotificationService {
|
||||||
if (torNotAvailable) {
|
if (torNotAvailable) {
|
||||||
if (TorServiceUtils.isOrbotInstalled(mXmppConnectionService)) {
|
if (TorServiceUtils.isOrbotInstalled(mXmppConnectionService)) {
|
||||||
mBuilder.addAction(
|
mBuilder.addAction(
|
||||||
R.drawable.ic_play_circle_filled_white_48dp,
|
R.drawable.ic_play_circle_24dp,
|
||||||
mXmppConnectionService.getString(R.string.start_orbot),
|
mXmppConnectionService.getString(R.string.start_orbot),
|
||||||
PendingIntent.getActivity(
|
PendingIntent.getActivity(
|
||||||
mXmppConnectionService,
|
mXmppConnectionService,
|
||||||
|
@ -1883,7 +1884,7 @@ public class NotificationService {
|
||||||
: PendingIntent.FLAG_UPDATE_CURRENT));
|
: PendingIntent.FLAG_UPDATE_CURRENT));
|
||||||
} else {
|
} else {
|
||||||
mBuilder.addAction(
|
mBuilder.addAction(
|
||||||
R.drawable.ic_file_download_white_24dp,
|
R.drawable.ic_download_24dp,
|
||||||
mXmppConnectionService.getString(R.string.install_orbot),
|
mXmppConnectionService.getString(R.string.install_orbot),
|
||||||
PendingIntent.getActivity(
|
PendingIntent.getActivity(
|
||||||
mXmppConnectionService,
|
mXmppConnectionService,
|
||||||
|
@ -1896,7 +1897,7 @@ public class NotificationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE);
|
mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE);
|
||||||
mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp);
|
mBuilder.setSmallIcon(R.drawable.ic_warning_24dp);
|
||||||
mBuilder.setLocalOnly(true);
|
mBuilder.setLocalOnly(true);
|
||||||
mBuilder.setPriority(Notification.PRIORITY_LOW);
|
mBuilder.setPriority(Notification.PRIORITY_LOW);
|
||||||
final Intent intent;
|
final Intent intent;
|
||||||
|
@ -1935,7 +1936,7 @@ public class NotificationService {
|
||||||
} else {
|
} else {
|
||||||
builder.setProgress(100, 0, true);
|
builder.setProgress(100, 0, true);
|
||||||
}
|
}
|
||||||
builder.setSmallIcon(R.drawable.ic_hourglass_empty_white_24dp);
|
builder.setSmallIcon(R.drawable.ic_hourglass_top_24dp);
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
builder.setContentIntent(createContentIntent(message.getConversation()));
|
builder.setContentIntent(createContentIntent(message.getConversation()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4760,9 +4760,6 @@ public class XmppConnectionService extends Service {
|
||||||
if (Config.QUICKSY_DOMAIN != null) {
|
if (Config.QUICKSY_DOMAIN != null) {
|
||||||
hosts.remove(Config.QUICKSY_DOMAIN.toEscapedString()); //we only want to show this when we type a e164 number
|
hosts.remove(Config.QUICKSY_DOMAIN.toEscapedString()); //we only want to show this when we type a e164 number
|
||||||
}
|
}
|
||||||
if (Config.DOMAIN_LOCK != null) {
|
|
||||||
hosts.add(Config.DOMAIN_LOCK);
|
|
||||||
}
|
|
||||||
if (Config.MAGIC_CREATE_DOMAIN != null) {
|
if (Config.MAGIC_CREATE_DOMAIN != null) {
|
||||||
hosts.add(Config.MAGIC_CREATE_DOMAIN);
|
hosts.add(Config.MAGIC_CREATE_DOMAIN);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,25 @@
|
||||||
package eu.siacs.conversations.ui;
|
package eu.siacs.conversations.ui;
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
|
||||||
import eu.siacs.conversations.ui.util.SettingsUtils;
|
|
||||||
import eu.siacs.conversations.utils.ThemeHelper;
|
|
||||||
|
|
||||||
import static eu.siacs.conversations.ui.XmppActivity.configureActionBar;
|
import static eu.siacs.conversations.ui.XmppActivity.configureActionBar;
|
||||||
|
|
||||||
public class AboutActivity extends AppCompatActivity {
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.databinding.ActivityAboutBinding;
|
||||||
|
|
||||||
|
public class AboutActivity extends BaseActivity {
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume(){
|
|
||||||
super.onResume();
|
|
||||||
SettingsUtils.applyScreenshotPreventionSetting(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setTheme(ThemeHelper.find(this));
|
final ActivityAboutBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_about);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
|
|
||||||
setContentView(R.layout.activity_about);
|
setSupportActionBar(binding.toolbar);
|
||||||
setSupportActionBar(findViewById(R.id.toolbar));
|
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
setTitle(getString(R.string.title_activity_about_x, getString(R.string.app_name)));
|
setTitle(getString(R.string.title_activity_about_x, getString(R.string.app_name)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import android.widget.EditText;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -34,7 +35,7 @@ public abstract class AbstractSearchableListItemActivity extends XmppActivity im
|
||||||
private final MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() {
|
private final MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemActionExpand(final MenuItem item) {
|
public boolean onMenuItemActionExpand(@NonNull final MenuItem item) {
|
||||||
mSearchEditText.post(() -> {
|
mSearchEditText.post(() -> {
|
||||||
mSearchEditText.requestFocus();
|
mSearchEditText.requestFocus();
|
||||||
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
@ -45,7 +46,7 @@ public abstract class AbstractSearchableListItemActivity extends XmppActivity im
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemActionCollapse(final MenuItem item) {
|
public boolean onMenuItemActionCollapse(@NonNull final MenuItem item) {
|
||||||
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
|
imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
|
||||||
mSearchEditText.setText("");
|
mSearchEditText.setText("");
|
||||||
|
@ -92,6 +93,7 @@ public abstract class AbstractSearchableListItemActivity extends XmppActivity im
|
||||||
public void onCreate(final Bundle savedInstanceState) {
|
public void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
this.binding = DataBindingUtil.setContentView(this,R.layout.activity_choose_contact);
|
this.binding = DataBindingUtil.setContentView(this,R.layout.activity_choose_contact);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
this.binding.chooseContactList.setFastScrollEnabled(true);
|
this.binding.chooseContactList.setFastScrollEnabled(true);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
|
|
||||||
public abstract class ActionBarActivity extends AppCompatActivity {
|
public abstract class ActionBarActivity extends BaseActivity {
|
||||||
public static void configureActionBar(ActionBar actionBar) {
|
public static void configureActionBar(ActionBar actionBar) {
|
||||||
configureActionBar(actionBar, true);
|
configureActionBar(actionBar, true);
|
||||||
}
|
}
|
||||||
|
|
47
src/main/java/eu/siacs/conversations/ui/Activities.java
Normal file
47
src/main/java/eu/siacs/conversations/ui/Activities.java
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package eu.siacs.conversations.ui;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.view.View;
|
||||||
|
import com.google.android.material.elevation.SurfaceColors;
|
||||||
|
|
||||||
|
public final class Activities {
|
||||||
|
|
||||||
|
private Activities() {}
|
||||||
|
|
||||||
|
public static void setStatusAndNavigationBarColors(final Activity activity, final View view) {
|
||||||
|
setStatusAndNavigationBarColors(activity, view, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setStatusAndNavigationBarColors(
|
||||||
|
final Activity activity, final View view, final boolean raisedStatusBar) {
|
||||||
|
final var isLightMode = isLightMode(activity);
|
||||||
|
final var window = activity.getWindow();
|
||||||
|
final var flags = view.getSystemUiVisibility();
|
||||||
|
// an elevation of 4 matches the MaterialToolbar elevation
|
||||||
|
if (raisedStatusBar) {
|
||||||
|
window.setStatusBarColor(SurfaceColors.SURFACE_5.getColor(activity));
|
||||||
|
} else {
|
||||||
|
window.setStatusBarColor(SurfaceColors.SURFACE_0.getColor(activity));
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
window.setNavigationBarColor(SurfaceColors.SURFACE_1.getColor(activity));
|
||||||
|
if (isLightMode) {
|
||||||
|
view.setSystemUiVisibility(
|
||||||
|
flags
|
||||||
|
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||||
|
| View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
|
||||||
|
}
|
||||||
|
} else if (isLightMode) {
|
||||||
|
view.setSystemUiVisibility(flags | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isLightMode(final Context context) {
|
||||||
|
final int nightModeFlags =
|
||||||
|
context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||||
|
return nightModeFlags != Configuration.UI_MODE_NIGHT_YES;
|
||||||
|
}
|
||||||
|
}
|
53
src/main/java/eu/siacs/conversations/ui/BaseActivity.java
Normal file
53
src/main/java/eu/siacs/conversations/ui/BaseActivity.java
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package eu.siacs.conversations.ui;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.Conversations;
|
||||||
|
import eu.siacs.conversations.ui.util.SettingsUtils;
|
||||||
|
|
||||||
|
public abstract class BaseActivity extends AppCompatActivity {
|
||||||
|
private Boolean isDynamicColors;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
final int desiredNightMode = Conversations.getDesiredNightMode(this);
|
||||||
|
if (setDesiredNightMode(desiredNightMode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final boolean isDynamicColors = Conversations.isDynamicColorsDesired(this);
|
||||||
|
setDynamicColors(isDynamicColors);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume(){
|
||||||
|
super.onResume();
|
||||||
|
SettingsUtils.applyScreenshotPreventionSetting(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDynamicColors(final boolean isDynamicColors) {
|
||||||
|
if (this.isDynamicColors == null) {
|
||||||
|
this.isDynamicColors = isDynamicColors;
|
||||||
|
} else {
|
||||||
|
if (this.isDynamicColors != isDynamicColors) {
|
||||||
|
Log.i(
|
||||||
|
"Recreating {} because dynamic color setting has changed",
|
||||||
|
getClass().getSimpleName());
|
||||||
|
recreate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setDesiredNightMode(final int desiredNightMode) {
|
||||||
|
if (desiredNightMode == AppCompatDelegate.getDefaultNightMode()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
AppCompatDelegate.setDefaultNightMode(desiredNightMode);
|
||||||
|
Log.i("Recreating {} because desired night mode has changed", getClass().getSimpleName());
|
||||||
|
recreate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ import androidx.annotation.StringRes;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.DialogBlockContactBinding;
|
import eu.siacs.conversations.databinding.DialogBlockContactBinding;
|
||||||
import eu.siacs.conversations.entities.Blockable;
|
import eu.siacs.conversations.entities.Blockable;
|
||||||
|
@ -19,7 +21,7 @@ public final class BlockContactDialog {
|
||||||
show(xmppActivity, blockable, null);
|
show(xmppActivity, blockable, null);
|
||||||
}
|
}
|
||||||
public static void show(final XmppActivity xmppActivity, final Blockable blockable, final String serverMsgId) {
|
public static void show(final XmppActivity xmppActivity, final Blockable blockable, final String serverMsgId) {
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(xmppActivity);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(xmppActivity);
|
||||||
final boolean isBlocked = blockable.isBlocked();
|
final boolean isBlocked = blockable.isBlocked();
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
DialogBlockContactBinding binding = DataBindingUtil.inflate(xmppActivity.getLayoutInflater(), R.layout.dialog_block_contact, null, false);
|
DialogBlockContactBinding binding = DataBindingUtil.inflate(xmppActivity.getLayoutInflater(), R.layout.dialog_block_contact, null, false);
|
||||||
|
|
|
@ -3,86 +3,84 @@ package eu.siacs.conversations.ui;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.databinding.ActivityChangePasswordBinding;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.ui.widget.DisabledActionModeCallback;
|
import eu.siacs.conversations.ui.widget.DisabledActionModeCallback;
|
||||||
|
|
||||||
public class ChangePasswordActivity extends XmppActivity implements XmppConnectionService.OnAccountPasswordChanged {
|
public class ChangePasswordActivity extends XmppActivity implements XmppConnectionService.OnAccountPasswordChanged {
|
||||||
|
|
||||||
private Button mChangePasswordButton;
|
private ActivityChangePasswordBinding binding;
|
||||||
|
|
||||||
private final View.OnClickListener mOnChangePasswordButtonClicked = new View.OnClickListener() {
|
private final View.OnClickListener mOnChangePasswordButtonClicked = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(final View view) {
|
||||||
if (mAccount != null) {
|
final var account = mAccount;
|
||||||
final String currentPassword = mCurrentPassword.getText().toString();
|
if (account == null) {
|
||||||
final String newPassword = mNewPassword.getText().toString();
|
return;
|
||||||
if (!mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE) && !currentPassword.equals(mAccount.getPassword())) {
|
|
||||||
mCurrentPassword.requestFocus();
|
|
||||||
mCurrentPasswordLayout.setError(getString(R.string.account_status_unauthorized));
|
|
||||||
removeErrorsOnAllBut(mCurrentPasswordLayout);
|
|
||||||
} else if (newPassword.trim().isEmpty()) {
|
|
||||||
mNewPassword.requestFocus();
|
|
||||||
mNewPasswordLayout.setError(getString(R.string.password_should_not_be_empty));
|
|
||||||
removeErrorsOnAllBut(mNewPasswordLayout);
|
|
||||||
} else {
|
|
||||||
mCurrentPasswordLayout.setError(null);
|
|
||||||
mNewPasswordLayout.setError(null);
|
|
||||||
xmppConnectionService.updateAccountPasswordOnServer(mAccount, newPassword, ChangePasswordActivity.this);
|
|
||||||
mChangePasswordButton.setEnabled(false);
|
|
||||||
mChangePasswordButton.setText(R.string.updating);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
final String currentPassword = binding.currentPassword.getText().toString();
|
||||||
|
final String newPassword = binding.newPassword.getText().toString();
|
||||||
|
if (!account.isOptionSet(Account.OPTION_MAGIC_CREATE) && !currentPassword.equals(account.getPassword())) {
|
||||||
|
binding.currentPassword.requestFocus();
|
||||||
|
binding.currentPasswordLayout.setError(getString(R.string.account_status_unauthorized));
|
||||||
|
removeErrorsOnAllBut(binding.currentPasswordLayout);
|
||||||
|
} else if (newPassword.trim().isEmpty()) {
|
||||||
|
binding.newPassword.requestFocus();
|
||||||
|
binding.newPasswordLayout.setError(getString(R.string.password_should_not_be_empty));
|
||||||
|
removeErrorsOnAllBut(binding.newPasswordLayout);
|
||||||
|
} else {
|
||||||
|
binding.currentPasswordLayout.setError(null);
|
||||||
|
binding.newPasswordLayout.setError(null);
|
||||||
|
xmppConnectionService.updateAccountPasswordOnServer(account, newPassword, ChangePasswordActivity.this);
|
||||||
|
binding.changePasswordButton.setEnabled(false);
|
||||||
|
binding.changePasswordButton.setText(R.string.updating);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private EditText mCurrentPassword;
|
|
||||||
private EditText mNewPassword;
|
|
||||||
private TextInputLayout mNewPasswordLayout;
|
|
||||||
private TextInputLayout mCurrentPasswordLayout;
|
|
||||||
private Account mAccount;
|
private Account mAccount;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onBackendConnected() {
|
void onBackendConnected() {
|
||||||
this.mAccount = extractAccount(getIntent());
|
this.mAccount = extractAccount(getIntent());
|
||||||
if (this.mAccount != null && this.mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE)) {
|
if (this.mAccount != null && this.mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE)) {
|
||||||
this.mCurrentPasswordLayout.setVisibility(View.GONE);
|
this.binding.currentPasswordLayout.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
this.mCurrentPassword.setVisibility(View.VISIBLE);
|
this.binding.currentPasswordLayout.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(final Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_change_password);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_change_password);
|
||||||
setSupportActionBar(findViewById(R.id.toolbar));
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
Button mCancelButton = findViewById(R.id.left_button);
|
binding.cancelButton.setOnClickListener(view -> finish());
|
||||||
mCancelButton.setOnClickListener(view -> finish());
|
binding.changePasswordButton.setOnClickListener(this.mOnChangePasswordButtonClicked);
|
||||||
this.mChangePasswordButton = findViewById(R.id.right_button);
|
binding.currentPassword.setCustomSelectionActionModeCallback(new DisabledActionModeCallback());
|
||||||
this.mChangePasswordButton.setOnClickListener(this.mOnChangePasswordButtonClicked);
|
binding.newPassword.setCustomSelectionActionModeCallback(new DisabledActionModeCallback());
|
||||||
this.mCurrentPassword = findViewById(R.id.current_password);
|
|
||||||
this.mCurrentPassword.setCustomSelectionActionModeCallback(new DisabledActionModeCallback());
|
|
||||||
this.mNewPassword = findViewById(R.id.new_password);
|
|
||||||
this.mNewPassword.setCustomSelectionActionModeCallback(new DisabledActionModeCallback());
|
|
||||||
this.mCurrentPasswordLayout = findViewById(R.id.current_password_layout);
|
|
||||||
this.mNewPasswordLayout = findViewById(R.id.new_password_layout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
String password = intent != null ? intent.getStringExtra("password") : null;
|
String password = intent != null ? intent.getStringExtra("password") : null;
|
||||||
if (password != null) {
|
if (password != null) {
|
||||||
this.mNewPassword.getEditableText().clear();
|
binding.newPassword.getEditableText().clear();
|
||||||
this.mNewPassword.getEditableText().append(password);
|
binding.newPassword.getEditableText().append(password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,21 +95,21 @@ public class ChangePasswordActivity extends XmppActivity implements XmppConnecti
|
||||||
@Override
|
@Override
|
||||||
public void onPasswordChangeFailed() {
|
public void onPasswordChangeFailed() {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
mNewPasswordLayout.setError(getString(R.string.could_not_change_password));
|
binding.newPasswordLayout.setError(getString(R.string.could_not_change_password));
|
||||||
mChangePasswordButton.setEnabled(true);
|
binding.changePasswordButton.setEnabled(true);
|
||||||
mChangePasswordButton.setText(R.string.change_password);
|
binding.changePasswordButton.setText(R.string.change_password);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeErrorsOnAllBut(TextInputLayout exception) {
|
private void removeErrorsOnAllBut(TextInputLayout exception) {
|
||||||
if (this.mCurrentPasswordLayout != exception) {
|
if (this.binding.currentPasswordLayout != exception) {
|
||||||
this.mCurrentPasswordLayout.setErrorEnabled(false);
|
this.binding.currentPasswordLayout.setErrorEnabled(false);
|
||||||
this.mCurrentPasswordLayout.setError(null);
|
this.binding.currentPasswordLayout.setError(null);
|
||||||
}
|
}
|
||||||
if (this.mNewPasswordLayout != exception) {
|
if (this.binding.newPasswordLayout != exception) {
|
||||||
this.mNewPasswordLayout.setErrorEnabled(false);
|
this.binding.newPasswordLayout.setErrorEnabled(false);
|
||||||
this.mNewPasswordLayout.setError(null);
|
this.binding.newPasswordLayout.setError(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,11 @@ import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -39,7 +42,6 @@ import eu.siacs.conversations.services.QuickConversationsService;
|
||||||
import eu.siacs.conversations.ui.adapter.ChannelSearchResultAdapter;
|
import eu.siacs.conversations.ui.adapter.ChannelSearchResultAdapter;
|
||||||
import eu.siacs.conversations.ui.util.PendingItem;
|
import eu.siacs.conversations.ui.util.PendingItem;
|
||||||
import eu.siacs.conversations.ui.util.SoftKeyboardUtils;
|
import eu.siacs.conversations.ui.util.SoftKeyboardUtils;
|
||||||
import eu.siacs.conversations.ui.util.StyledAttributes;
|
|
||||||
import eu.siacs.conversations.utils.AccountUtils;
|
import eu.siacs.conversations.utils.AccountUtils;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
|
||||||
|
@ -81,6 +83,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
binding = DataBindingUtil.setContentView(this, R.layout.activity_channel_discovery);
|
binding = DataBindingUtil.setContentView(this, R.layout.activity_channel_discovery);
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
configureActionBar(getSupportActionBar(), true);
|
configureActionBar(getSupportActionBar(), true);
|
||||||
binding.list.setAdapter(this.adapter);
|
binding.list.setAdapter(this.adapter);
|
||||||
this.adapter.setOnChannelSearchResultSelectedListener(this);
|
this.adapter.setOnChannelSearchResultSelectedListener(this);
|
||||||
|
@ -155,7 +158,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
private void toggleLoadingScreen() {
|
private void toggleLoadingScreen() {
|
||||||
adapter.submitList(Collections.emptyList());
|
adapter.submitList(Collections.emptyList());
|
||||||
binding.progressBar.setVisibility(View.VISIBLE);
|
binding.progressBar.setVisibility(View.VISIBLE);
|
||||||
binding.list.setBackgroundColor(StyledAttributes.getColor(this, R.attr.color_background_primary));
|
binding.list.setBackgroundColor(MaterialColors.getColor(binding.list, com.google.android.material.R.attr.colorSurface));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -163,13 +166,13 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
super.onStart();
|
super.onStart();
|
||||||
this.method = getMethod(this);
|
this.method = getMethod(this);
|
||||||
if (!optedIn && method == ChannelDiscoveryService.Method.JABBER_NETWORK) {
|
if (!optedIn && method == ChannelDiscoveryService.Method.JABBER_NETWORK) {
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(R.string.channel_discovery_opt_in_title);
|
builder.setTitle(R.string.channel_discovery_opt_in_title);
|
||||||
builder.setMessage(Html.fromHtml(getString(R.string.channel_discover_opt_in_message)));
|
builder.setMessage(Html.fromHtml(getString(R.string.channel_discover_opt_in_message)));
|
||||||
builder.setNegativeButton(R.string.cancel, (dialog, which) -> finish());
|
builder.setNegativeButton(R.string.cancel, (dialog, which) -> finish());
|
||||||
builder.setPositiveButton(R.string.confirm, (dialog, which) -> optIn());
|
builder.setPositiveButton(R.string.confirm, (dialog, which) -> optIn());
|
||||||
builder.setOnCancelListener(dialog -> finish());
|
builder.setOnCancelListener(dialog -> finish());
|
||||||
final AlertDialog dialog = builder.create();
|
final androidx.appcompat.app.AlertDialog dialog = builder.create();
|
||||||
dialog.setOnShowListener(d -> {
|
dialog.setOnShowListener(d -> {
|
||||||
final TextView textView = dialog.findViewById(android.R.id.message);
|
final TextView textView = dialog.findViewById(android.R.id.message);
|
||||||
if (textView == null) {
|
if (textView == null) {
|
||||||
|
@ -186,7 +189,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
private void holdLoading() {
|
private void holdLoading() {
|
||||||
adapter.submitList(Collections.emptyList());
|
adapter.submitList(Collections.emptyList());
|
||||||
binding.progressBar.setVisibility(View.GONE);
|
binding.progressBar.setVisibility(View.GONE);
|
||||||
binding.list.setBackgroundColor(StyledAttributes.getColor(this, R.attr.color_background_primary));
|
binding.list.setBackgroundColor(MaterialColors.getColor(binding.list, com.google.android.material.R.attr.colorSurface));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -220,10 +223,10 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
adapter.submitList(results);
|
adapter.submitList(results);
|
||||||
binding.progressBar.setVisibility(View.GONE);
|
binding.progressBar.setVisibility(View.GONE);
|
||||||
if (results.size() == 0) {
|
if (results.isEmpty()) {
|
||||||
binding.list.setBackground(StyledAttributes.getDrawable(this, R.attr.activity_primary_background_no_results));
|
binding.list.setBackground(ContextCompat.getDrawable(this,R.drawable.background_no_results));
|
||||||
} else {
|
} else {
|
||||||
binding.list.setBackgroundColor(StyledAttributes.getColor(this, R.attr.color_background_primary));
|
binding.list.setBackgroundColor(MaterialColors.getColor(binding.list, com.google.android.material.R.attr.colorSurface));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -234,11 +237,11 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
final List<String> accounts = AccountUtils.getEnabledAccounts(xmppConnectionService);
|
final List<String> accounts = AccountUtils.getEnabledAccounts(xmppConnectionService);
|
||||||
if (accounts.size() == 1) {
|
if (accounts.size() == 1) {
|
||||||
joinChannelSearchResult(accounts.get(0), result);
|
joinChannelSearchResult(accounts.get(0), result);
|
||||||
} else if (accounts.size() == 0) {
|
} else if (accounts.isEmpty()) {
|
||||||
Toast.makeText(this, R.string.please_enable_an_account, Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.please_enable_an_account, Toast.LENGTH_LONG).show();
|
||||||
} else {
|
} else {
|
||||||
final AtomicReference<String> account = new AtomicReference<>(accounts.get(0));
|
final AtomicReference<String> account = new AtomicReference<>(accounts.get(0));
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(R.string.choose_account);
|
builder.setTitle(R.string.choose_account);
|
||||||
builder.setSingleChoiceItems(accounts.toArray(new CharSequence[0]), 0, (dialog, which) -> account.set(accounts.get(which)));
|
builder.setSingleChoiceItems(accounts.toArray(new CharSequence[0]), 0, (dialog, which) -> account.set(accounts.get(which)));
|
||||||
builder.setPositiveButton(R.string.join, (dialog, which) -> joinChannelSearchResult(account.get(), result));
|
builder.setPositiveButton(R.string.join, (dialog, which) -> joinChannelSearchResult(account.get(), result));
|
||||||
|
@ -271,10 +274,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
}
|
}
|
||||||
|
|
||||||
public void joinChannelSearchResult(final String selectedAccount, final Room result) {
|
public void joinChannelSearchResult(final String selectedAccount, final Room result) {
|
||||||
final Jid jid =
|
final Jid jid = Jid.ofEscaped(selectedAccount);
|
||||||
Config.DOMAIN_LOCK == null
|
|
||||||
? Jid.ofEscaped(selectedAccount)
|
|
||||||
: Jid.ofLocalAndDomainEscaped(selectedAccount, Config.DOMAIN_LOCK);
|
|
||||||
final boolean syncAutoJoin = getBooleanPreference("autojoin", R.bool.autojoin);
|
final boolean syncAutoJoin = getBooleanPreference("autojoin", R.bool.autojoin);
|
||||||
final Account account = xmppConnectionService.findAccountByJid(jid);
|
final Account account = xmppConnectionService.findAccountByJid(jid);
|
||||||
final Conversation conversation =
|
final Conversation conversation =
|
||||||
|
|
|
@ -3,20 +3,21 @@ package eu.siacs.conversations.ui;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.databinding.ActivityManageAccountsBinding;
|
||||||
|
import eu.siacs.conversations.entities.Account;
|
||||||
|
import eu.siacs.conversations.ui.adapter.AccountAdapter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
|
||||||
import eu.siacs.conversations.entities.Account;
|
|
||||||
import eu.siacs.conversations.ui.adapter.AccountAdapter;
|
|
||||||
|
|
||||||
public class ChooseAccountForProfilePictureActivity extends XmppActivity {
|
public class ChooseAccountForProfilePictureActivity extends XmppActivity {
|
||||||
|
|
||||||
protected final List<Account> accountList = new ArrayList<>();
|
protected final List<Account> accountList = new ArrayList<>();
|
||||||
protected ListView accountListView;
|
|
||||||
protected AccountAdapter mAccountAdapter;
|
protected AccountAdapter mAccountAdapter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -28,25 +29,21 @@ public class ChooseAccountForProfilePictureActivity extends XmppActivity {
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_manage_accounts);
|
final ActivityManageAccountsBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_manage_accounts);
|
||||||
setSupportActionBar(findViewById(R.id.toolbar));
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar(), false);
|
configureActionBar(getSupportActionBar(), false);
|
||||||
accountListView = findViewById(R.id.account_list);
|
|
||||||
this.mAccountAdapter = new AccountAdapter(this, accountList, false);
|
this.mAccountAdapter = new AccountAdapter(this, accountList, false);
|
||||||
accountListView.setAdapter(this.mAccountAdapter);
|
binding.accountList.setAdapter(this.mAccountAdapter);
|
||||||
accountListView.setOnItemClickListener((arg0, view, position, arg3) -> {
|
binding.accountList.setOnItemClickListener((arg0, view, position, arg3) -> {
|
||||||
final Account account = accountList.get(position);
|
final Account account = accountList.get(position);
|
||||||
goToProfilePictureActivity(account);
|
goToProfilePictureActivity(account);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
final int theme = findTheme();
|
|
||||||
if (this.mTheme != theme) {
|
|
||||||
recreate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.view.ActionMode;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.SoundEffectConstants;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.AbsListView.MultiChoiceModeListener;
|
import android.widget.AbsListView.MultiChoiceModeListener;
|
||||||
|
@ -51,7 +52,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
|
||||||
public static final String EXTRA_SHOW_ENTER_JID = "extra_show_enter_jid";
|
public static final String EXTRA_SHOW_ENTER_JID = "extra_show_enter_jid";
|
||||||
public static final String EXTRA_CONVERSATION = "extra_conversation";
|
public static final String EXTRA_CONVERSATION = "extra_conversation";
|
||||||
private static final String EXTRA_FILTERED_CONTACTS = "extra_filtered_contacts";
|
private static final String EXTRA_FILTERED_CONTACTS = "extra_filtered_contacts";
|
||||||
private final List<String> mActivatedAccounts = new ArrayList<>();
|
private final ArrayList<String> mActivatedAccounts = new ArrayList<>();
|
||||||
private final Set<String> selected = new HashSet<>();
|
private final Set<String> selected = new HashSet<>();
|
||||||
private Set<String> filterContacts;
|
private Set<String> filterContacts;
|
||||||
|
|
||||||
|
@ -130,7 +131,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
|
||||||
if (this.showEnterJid) {
|
if (this.showEnterJid) {
|
||||||
this.binding.fab.show();
|
this.binding.fab.show();
|
||||||
} else {
|
} else {
|
||||||
binding.fab.setImageResource(R.drawable.ic_forward_white_24dp);
|
binding.fab.setImageResource(R.drawable.ic_navigate_next_24dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
final SharedPreferences preferences = getPreferences();
|
final SharedPreferences preferences = getPreferences();
|
||||||
|
@ -139,7 +140,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onFabClicked(View v) {
|
private void onFabClicked(View v) {
|
||||||
if (selected.size() == 0) {
|
if (selected.isEmpty()) {
|
||||||
showEnterJidDialog(null);
|
showEnterJidDialog(null);
|
||||||
} else {
|
} else {
|
||||||
submitSelection();
|
submitSelection();
|
||||||
|
@ -154,7 +155,8 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||||
mode.setTitle(getTitleFromIntent());
|
mode.setTitle(getTitleFromIntent());
|
||||||
binding.fab.setImageResource(R.drawable.ic_forward_white_24dp);
|
binding.chooseContactList.setFastScrollEnabled(false);
|
||||||
|
binding.fab.setImageResource(R.drawable.ic_navigate_next_24dp);
|
||||||
binding.fab.show();
|
binding.fab.show();
|
||||||
final View view = getSearchEditText();
|
final View view = getSearchEditText();
|
||||||
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
@ -166,12 +168,13 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyActionMode(ActionMode mode) {
|
public void onDestroyActionMode(ActionMode mode) {
|
||||||
this.binding.fab.setImageResource(R.drawable.ic_person_add_white_24dp);
|
this.binding.fab.setImageResource(R.drawable.ic_person_add_24dp);
|
||||||
if (this.showEnterJid) {
|
if (this.showEnterJid) {
|
||||||
this.binding.fab.show();
|
this.binding.fab.show();
|
||||||
} else {
|
} else {
|
||||||
this.binding.fab.hide();
|
this.binding.fab.hide();
|
||||||
}
|
}
|
||||||
|
binding.chooseContactList.setFastScrollEnabled(true);
|
||||||
selected.clear();
|
selected.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,8 +202,9 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
|
||||||
@Override
|
@Override
|
||||||
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
|
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
|
||||||
if (selected.size() != 0) {
|
if (selected.size() != 0) {
|
||||||
getListView().playSoundEffect(0);
|
getListView().playSoundEffect(SoundEffectConstants.CLICK);
|
||||||
}
|
}
|
||||||
|
getListItemAdapter().notifyDataSetChanged();
|
||||||
Contact item = (Contact) getListItems().get(position);
|
Contact item = (Contact) getListItems().get(position);
|
||||||
if (checked) {
|
if (checked) {
|
||||||
selected.add(item.getJid().toString());
|
selected.add(item.getJid().toString());
|
||||||
|
@ -361,13 +365,9 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
|
||||||
void onBackendConnected() {
|
void onBackendConnected() {
|
||||||
filterContacts();
|
filterContacts();
|
||||||
this.mActivatedAccounts.clear();
|
this.mActivatedAccounts.clear();
|
||||||
for (Account account : xmppConnectionService.getAccounts()) {
|
for (final Account account : xmppConnectionService.getAccounts()) {
|
||||||
if (account.isEnabled()) {
|
if (account.isEnabled()) {
|
||||||
if (Config.DOMAIN_LOCK != null) {
|
this.mActivatedAccounts.add(account.getJid().asBareJid().toEscapedString());
|
||||||
this.mActivatedAccounts.add(account.getJid().getEscapedLocal());
|
|
||||||
} else {
|
|
||||||
this.mActivatedAccounts.add(account.getJid().asBareJid().toEscapedString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActivityResult activityResult = this.postponedActivityResult.pop();
|
ActivityResult activityResult = this.postponedActivityResult.pop();
|
||||||
|
|
|
@ -55,6 +55,8 @@ import me.drakeet.support.toast.ToastCompat;
|
||||||
import static eu.siacs.conversations.entities.Bookmark.printableValue;
|
import static eu.siacs.conversations.entities.Bookmark.printableValue;
|
||||||
import static eu.siacs.conversations.utils.StringUtils.changed;
|
import static eu.siacs.conversations.utils.StringUtils.changed;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnConfigurationPushed, XmppConnectionService.OnRoomDestroy, TextWatcher, OnMediaLoaded {
|
public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnConfigurationPushed, XmppConnectionService.OnRoomDestroy, TextWatcher, OnMediaLoaded {
|
||||||
public static final String ACTION_VIEW_MUC = "view_muc";
|
public static final String ACTION_VIEW_MUC = "view_muc";
|
||||||
|
|
||||||
|
@ -97,7 +99,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
private final OnClickListener mNotifyStatusClickListener = new OnClickListener() {
|
private final OnClickListener mNotifyStatusClickListener = new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(ConferenceDetailsActivity.this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ConferenceDetailsActivity.this);
|
||||||
builder.setTitle(R.string.pref_notification_settings);
|
builder.setTitle(R.string.pref_notification_settings);
|
||||||
String[] choices = {
|
String[] choices = {
|
||||||
getString(R.string.notify_on_all_messages),
|
getString(R.string.notify_on_all_messages),
|
||||||
|
@ -130,7 +132,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
final MucOptions mucOptions = mConversation.getMucOptions();
|
final MucOptions mucOptions = mConversation.getMucOptions();
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(ConferenceDetailsActivity.this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ConferenceDetailsActivity.this);
|
||||||
MucConfiguration configuration = MucConfiguration.get(ConferenceDetailsActivity.this, mAdvancedMode, mucOptions);
|
MucConfiguration configuration = MucConfiguration.get(ConferenceDetailsActivity.this, mAdvancedMode, mucOptions);
|
||||||
builder.setTitle(configuration.title);
|
builder.setTitle(configuration.title);
|
||||||
final boolean[] values = configuration.values;
|
final boolean[] values = configuration.values;
|
||||||
|
@ -168,6 +170,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_muc_details);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_muc_details);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
this.binding.changeConferenceButton.setOnClickListener(this.mChangeConferenceSettings);
|
this.binding.changeConferenceButton.setOnClickListener(this.mChangeConferenceSettings);
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
|
@ -216,12 +219,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
final int theme = findTheme();
|
|
||||||
if (this.mTheme != theme) {
|
|
||||||
recreate();
|
|
||||||
}
|
|
||||||
binding.mediaWrapper.setVisibility(Compatibility.hasStoragePermission(this) ? View.VISIBLE : View.GONE);
|
binding.mediaWrapper.setVisibility(Compatibility.hasStoragePermission(this) ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +276,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
final MucOptions mucOptions = mConversation.getMucOptions();
|
final MucOptions mucOptions = mConversation.getMucOptions();
|
||||||
this.binding.mucEditor.setVisibility(View.VISIBLE);
|
this.binding.mucEditor.setVisibility(View.VISIBLE);
|
||||||
this.binding.mucDisplay.setVisibility(View.GONE);
|
this.binding.mucDisplay.setVisibility(View.GONE);
|
||||||
this.binding.editMucNameButton.setImageResource(getThemeResource(R.attr.icon_cancel, R.drawable.ic_cancel_black_24dp));
|
this.binding.editMucNameButton.setImageResource(R.drawable.ic_cancel_24dp);
|
||||||
final String name = mucOptions.getName();
|
final String name = mucOptions.getName();
|
||||||
this.binding.mucEditTitle.setText("");
|
this.binding.mucEditTitle.setText("");
|
||||||
final boolean owner = mucOptions.getSelf().getAffiliation().ranks(MucOptions.Affiliation.OWNER);
|
final boolean owner = mucOptions.getSelf().getAffiliation().ranks(MucOptions.Affiliation.OWNER);
|
||||||
|
@ -311,7 +310,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
private void hideEditor() {
|
private void hideEditor() {
|
||||||
this.binding.mucEditor.setVisibility(View.GONE);
|
this.binding.mucEditor.setVisibility(View.GONE);
|
||||||
this.binding.mucDisplay.setVisibility(View.VISIBLE);
|
this.binding.mucDisplay.setVisibility(View.VISIBLE);
|
||||||
this.binding.editMucNameButton.setImageResource(getThemeResource(R.attr.icon_edit_body, R.drawable.ic_edit_black_24dp));
|
this.binding.editMucNameButton.setImageResource(R.drawable.ic_edit_24dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onMucInfoUpdated(String subject, String name) {
|
private void onMucInfoUpdated(String subject, String name) {
|
||||||
|
@ -384,7 +383,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
|
|
||||||
protected void destroyRoom() {
|
protected void destroyRoom() {
|
||||||
final boolean groupChat = mConversation != null && mConversation.isPrivateAndNonAnonymous();
|
final boolean groupChat = mConversation != null && mConversation.isPrivateAndNonAnonymous();
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(groupChat ? R.string.destroy_room : R.string.destroy_channel);
|
builder.setTitle(groupChat ? R.string.destroy_room : R.string.destroy_channel);
|
||||||
builder.setMessage(groupChat ? R.string.destroy_room_dialog : R.string.destroy_channel_dialog);
|
builder.setMessage(groupChat ? R.string.destroy_room_dialog : R.string.destroy_channel_dialog);
|
||||||
builder.setPositiveButton(R.string.ok, (dialog, which) -> {
|
builder.setPositiveButton(R.string.ok, (dialog, which) -> {
|
||||||
|
@ -434,12 +433,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
}
|
}
|
||||||
final MucOptions mucOptions = mConversation.getMucOptions();
|
final MucOptions mucOptions = mConversation.getMucOptions();
|
||||||
final User self = mucOptions.getSelf();
|
final User self = mucOptions.getSelf();
|
||||||
String account;
|
final String account = mConversation.getAccount().getJid().asBareJid().toEscapedString();
|
||||||
if (Config.DOMAIN_LOCK != null) {
|
|
||||||
account = mConversation.getAccount().getJid().getEscapedLocal();
|
|
||||||
} else {
|
|
||||||
account = mConversation.getAccount().getJid().asBareJid().toEscapedString();
|
|
||||||
}
|
|
||||||
setTitle(mucOptions.isPrivateAndNonAnonymous() ? R.string.action_muc_details : R.string.channel_details);
|
setTitle(mucOptions.isPrivateAndNonAnonymous() ? R.string.action_muc_details : R.string.channel_details);
|
||||||
this.binding.editMucNameButton.setVisibility((self.getAffiliation().ranks(MucOptions.Affiliation.OWNER) || mucOptions.canChangeSubject()) ? View.VISIBLE : View.GONE);
|
this.binding.editMucNameButton.setVisibility((self.getAffiliation().ranks(MucOptions.Affiliation.OWNER) || mucOptions.canChangeSubject()) ? View.VISIBLE : View.GONE);
|
||||||
this.binding.detailsAccount.setText(getString(R.string.using_account, account));
|
this.binding.detailsAccount.setText(getString(R.string.using_account, account));
|
||||||
|
@ -469,7 +463,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
StylingHelper.format(spannable, this.binding.mucSubject.getCurrentTextColor());
|
StylingHelper.format(spannable, this.binding.mucSubject.getCurrentTextColor());
|
||||||
MyLinkify.addLinks(spannable, false);
|
MyLinkify.addLinks(spannable, false);
|
||||||
this.binding.mucSubject.setText(spannable);
|
this.binding.mucSubject.setText(spannable);
|
||||||
this.binding.mucSubject.setTextAppearance(this, subject.length() > (hasTitle ? 128 : 196) ? R.style.TextAppearance_Conversations_Body1_Linkified : R.style.TextAppearance_Conversations_Subhead);
|
this.binding.mucSubject.setTextAppearance( subject.length() > (hasTitle ? 128 : 196) ? com.google.android.material.R.style.TextAppearance_Material3_BodyMedium : com.google.android.material.R.style.TextAppearance_Material3_BodyLarge);
|
||||||
this.binding.mucSubject.setAutoLinkMask(0);
|
this.binding.mucSubject.setAutoLinkMask(0);
|
||||||
this.binding.mucSubject.setVisibility(View.VISIBLE);
|
this.binding.mucSubject.setVisibility(View.VISIBLE);
|
||||||
this.binding.mucSubject.setMovementMethod(LinkMovementMethod.getInstance());
|
this.binding.mucSubject.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
@ -507,24 +501,19 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
this.binding.mucSettings.setVisibility(View.GONE);
|
this.binding.mucSettings.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ic_notifications = getThemeResource(R.attr.icon_notifications, R.drawable.ic_notifications_black_24dp);
|
final long mutedTill = mConversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
|
||||||
int ic_notifications_off = getThemeResource(R.attr.icon_notifications_off, R.drawable.ic_notifications_off_black_24dp);
|
|
||||||
int ic_notifications_paused = getThemeResource(R.attr.icon_notifications_paused, R.drawable.ic_notifications_paused_black_24dp);
|
|
||||||
int ic_notifications_none = getThemeResource(R.attr.icon_notifications_none, R.drawable.ic_notifications_none_black_24dp);
|
|
||||||
|
|
||||||
long mutedTill = mConversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
|
|
||||||
if (mutedTill == Long.MAX_VALUE) {
|
if (mutedTill == Long.MAX_VALUE) {
|
||||||
this.binding.notificationStatusText.setText(R.string.notify_never);
|
this.binding.notificationStatusText.setText(R.string.notify_never);
|
||||||
this.binding.notificationStatusButton.setImageResource(ic_notifications_off);
|
this.binding.notificationStatusButton.setImageResource(R.drawable.ic_notifications_off_24dp);
|
||||||
} else if (System.currentTimeMillis() < mutedTill) {
|
} else if (System.currentTimeMillis() < mutedTill) {
|
||||||
this.binding.notificationStatusText.setText(R.string.notify_paused);
|
this.binding.notificationStatusText.setText(R.string.notify_paused);
|
||||||
this.binding.notificationStatusButton.setImageResource(ic_notifications_paused);
|
this.binding.notificationStatusButton.setImageResource(R.drawable.ic_notifications_paused_24dp);
|
||||||
} else if (mConversation.alwaysNotify()) {
|
} else if (mConversation.alwaysNotify()) {
|
||||||
this.binding.notificationStatusText.setText(R.string.notify_on_all_messages);
|
this.binding.notificationStatusText.setText(R.string.notify_on_all_messages);
|
||||||
this.binding.notificationStatusButton.setImageResource(ic_notifications);
|
this.binding.notificationStatusButton.setImageResource(R.drawable.ic_notifications_24dp);
|
||||||
} else {
|
} else {
|
||||||
this.binding.notificationStatusText.setText(R.string.notify_only_when_highlighted);
|
this.binding.notificationStatusText.setText(R.string.notify_only_when_highlighted);
|
||||||
this.binding.notificationStatusButton.setImageResource(ic_notifications_none);
|
this.binding.notificationStatusButton.setImageResource(R.drawable.ic_notifications_none_24dp);
|
||||||
}
|
}
|
||||||
final List<User> users = mucOptions.getUsers();
|
final List<User> users = mucOptions.getUsers();
|
||||||
Collections.sort(users, (a, b) -> {
|
Collections.sort(users, (a, b) -> {
|
||||||
|
@ -629,9 +618,9 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
boolean subjectChanged = changed(binding.mucEditSubject.getEditableText().toString(), mucOptions.getSubject());
|
boolean subjectChanged = changed(binding.mucEditSubject.getEditableText().toString(), mucOptions.getSubject());
|
||||||
boolean nameChanged = changed(binding.mucEditTitle.getEditableText().toString(), mucOptions.getName());
|
boolean nameChanged = changed(binding.mucEditTitle.getEditableText().toString(), mucOptions.getName());
|
||||||
if (subjectChanged || nameChanged) {
|
if (subjectChanged || nameChanged) {
|
||||||
this.binding.editMucNameButton.setImageResource(getThemeResource(R.attr.icon_save, R.drawable.ic_save_black_24dp));
|
this.binding.editMucNameButton.setImageResource(R.drawable.ic_save_24dp);
|
||||||
} else {
|
} else {
|
||||||
this.binding.editMucNameButton.setImageResource(getThemeResource(R.attr.icon_cancel, R.drawable.ic_cancel_black_24dp));
|
this.binding.editMucNameButton.setImageResource(R.drawable.ic_cancel_24dp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,9 @@ import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import org.openintents.openpgp.util.OpenPgpUtils;
|
import org.openintents.openpgp.util.OpenPgpUtils;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -144,7 +147,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
|
||||||
} else {
|
} else {
|
||||||
value = jid.toEscapedString();
|
value = jid.toEscapedString();
|
||||||
}
|
}
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(getString(R.string.action_add_phone_book));
|
builder.setTitle(getString(R.string.action_add_phone_book));
|
||||||
builder.setMessage(getString(R.string.add_phone_book_text, value));
|
builder.setMessage(getString(R.string.add_phone_book_text, value));
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
builder.setNegativeButton(getString(R.string.cancel), null);
|
||||||
|
@ -215,6 +218,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
|
||||||
}
|
}
|
||||||
this.messageFingerprint = getIntent().getStringExtra("fingerprint");
|
this.messageFingerprint = getIntent().getStringExtra("fingerprint");
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_contact_details);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_contact_details);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
|
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
|
@ -238,14 +242,9 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
final int theme = findTheme();
|
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
if (this.mTheme != theme) {
|
this.showDynamicTags = preferences.getBoolean(SettingsActivity.SHOW_DYNAMIC_TAGS, false);
|
||||||
recreate();
|
this.showLastSeen = preferences.getBoolean("last_activity", false);
|
||||||
} else {
|
|
||||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
this.showDynamicTags = preferences.getBoolean(SettingsActivity.SHOW_DYNAMIC_TAGS, false);
|
|
||||||
this.showLastSeen = preferences.getBoolean("last_activity", false);
|
|
||||||
}
|
|
||||||
binding.mediaWrapper.setVisibility(Compatibility.hasStoragePermission(this) ? View.VISIBLE : View.GONE);
|
binding.mediaWrapper.setVisibility(Compatibility.hasStoragePermission(this) ? View.VISIBLE : View.GONE);
|
||||||
mMediaAdapter.setAttachments(Collections.emptyList());
|
mMediaAdapter.setAttachments(Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
@ -268,8 +267,6 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
|
||||||
if (MenuDoubleTabUtil.shouldIgnoreTap()) {
|
if (MenuDoubleTabUtil.shouldIgnoreTap()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
|
||||||
switch (menuItem.getItemId()) {
|
switch (menuItem.getItemId()) {
|
||||||
case android.R.id.home:
|
case android.R.id.home:
|
||||||
finish();
|
finish();
|
||||||
|
@ -281,6 +278,8 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
|
||||||
shareLink(false);
|
shareLink(false);
|
||||||
break;
|
break;
|
||||||
case R.id.action_delete_contact:
|
case R.id.action_delete_contact:
|
||||||
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
|
builder.setNegativeButton(getString(R.string.cancel), null);
|
||||||
builder.setTitle(getString(R.string.action_delete_contact))
|
builder.setTitle(getString(R.string.action_delete_contact))
|
||||||
.setMessage(JidDialog.style(this, R.string.remove_contact_text, contact.getJid().toEscapedString()))
|
.setMessage(JidDialog.style(this, R.string.remove_contact_text, contact.getJid().toEscapedString()))
|
||||||
.setPositiveButton(getString(R.string.delete),
|
.setPositiveButton(getString(R.string.delete),
|
||||||
|
@ -431,12 +430,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.detailsContactjid.setText(IrregularUnicodeDetector.style(this, contact.getJid()));
|
binding.detailsContactjid.setText(IrregularUnicodeDetector.style(this, contact.getJid()));
|
||||||
String account;
|
final String account = contact.getAccount().getJid().asBareJid().toEscapedString();
|
||||||
if (Config.DOMAIN_LOCK != null) {
|
|
||||||
account = contact.getAccount().getJid().getEscapedLocal();
|
|
||||||
} else {
|
|
||||||
account = contact.getAccount().getJid().asBareJid().toEscapedString();
|
|
||||||
}
|
|
||||||
binding.detailsAccount.setText(getString(R.string.using_account, account));
|
binding.detailsAccount.setText(getString(R.string.using_account, account));
|
||||||
AvatarWorkerTask.loadAvatar(contact, binding.detailsContactBadge, R.dimen.avatar_on_details_screen_size);
|
AvatarWorkerTask.loadAvatar(contact, binding.detailsContactBadge, R.dimen.avatar_on_details_screen_size);
|
||||||
binding.detailsContactBadge.setOnClickListener(this::onBadgeClick);
|
binding.detailsContactBadge.setOnClickListener(this::onBadgeClick);
|
||||||
|
@ -498,7 +492,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
|
||||||
TextView keyType = view.findViewById(R.id.key_type);
|
TextView keyType = view.findViewById(R.id.key_type);
|
||||||
keyType.setText(R.string.openpgp_key_id);
|
keyType.setText(R.string.openpgp_key_id);
|
||||||
if ("pgp".equals(messageFingerprint)) {
|
if ("pgp".equals(messageFingerprint)) {
|
||||||
keyType.setTextAppearance(this, R.style.TextAppearance_Conversations_Caption_Highlight);
|
keyType.setTextColor(MaterialColors.getColor(keyType, com.google.android.material.R.attr.colorPrimaryVariant));
|
||||||
}
|
}
|
||||||
key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId()));
|
key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId()));
|
||||||
final OnClickListener openKey = v -> launchOpenKeyChain(contact.getPgpKeyId());
|
final OnClickListener openKey = v -> launchOpenKeyChain(contact.getPgpKeyId());
|
||||||
|
@ -510,7 +504,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
|
||||||
binding.keysWrapper.setVisibility(hasKeys ? View.VISIBLE : View.GONE);
|
binding.keysWrapper.setVisibility(hasKeys ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
List<ListItem.Tag> tagList = contact.getTags(this);
|
List<ListItem.Tag> tagList = contact.getTags(this);
|
||||||
if (tagList.size() == 0 || !this.showDynamicTags) {
|
if (tagList.isEmpty() || !this.showDynamicTags) {
|
||||||
binding.tags.setVisibility(View.GONE);
|
binding.tags.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
binding.tags.setVisibility(View.VISIBLE);
|
binding.tags.setVisibility(View.VISIBLE);
|
||||||
|
|
|
@ -16,10 +16,4 @@ public class ConversationActivity extends AppCompatActivity {
|
||||||
startActivity(new Intent(this, ConversationsActivity.class));
|
startActivity(new Intent(this, ConversationsActivity.class));
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume(){
|
|
||||||
super.onResume();
|
|
||||||
SettingsUtils.applyScreenshotPreventionSetting(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import android.content.Intent;
|
||||||
import android.content.IntentSender.SendIntentException;
|
import android.content.IntentSender.SendIntentException;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -63,6 +64,7 @@ import androidx.core.view.inputmethod.InputConnectionCompat;
|
||||||
import androidx.core.view.inputmethod.InputContentInfoCompat;
|
import androidx.core.view.inputmethod.InputContentInfoCompat;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
@ -1062,7 +1064,7 @@ public class ConversationFragment extends XmppFragment
|
||||||
};
|
};
|
||||||
if (conversation == null
|
if (conversation == null
|
||||||
|| conversation.getMode() == Conversation.MODE_MULTI
|
|| conversation.getMode() == Conversation.MODE_MULTI
|
||||||
|| Attachment.canBeSendInband(attachments)
|
|| Attachment.canBeSendInBand(attachments)
|
||||||
|| (conversation.getAccount().httpUploadAvailable()
|
|| (conversation.getAccount().httpUploadAvailable()
|
||||||
&& FileBackend.allFilesUnderSize(
|
&& FileBackend.allFilesUnderSize(
|
||||||
getActivity(), attachments, getMaxHttpUploadSize(conversation)))) {
|
getActivity(), attachments, getMaxHttpUploadSize(conversation)))) {
|
||||||
|
@ -1934,8 +1936,8 @@ public class ConversationFragment extends XmppFragment
|
||||||
|
|
||||||
@SuppressLint("InflateParams")
|
@SuppressLint("InflateParams")
|
||||||
protected void clearHistoryDialog(final Conversation conversation) {
|
protected void clearHistoryDialog(final Conversation conversation) {
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
|
||||||
builder.setTitle(getString(R.string.clear_conversation_history));
|
builder.setTitle(R.string.clear_conversation_history);
|
||||||
final View dialogView =
|
final View dialogView =
|
||||||
requireActivity().getLayoutInflater().inflate(R.layout.dialog_clear_history, null);
|
requireActivity().getLayoutInflater().inflate(R.layout.dialog_clear_history, null);
|
||||||
final CheckBox endConversationCheckBox =
|
final CheckBox endConversationCheckBox =
|
||||||
|
@ -1958,7 +1960,7 @@ public class ConversationFragment extends XmppFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void muteConversationDialog(final Conversation conversation) {
|
protected void muteConversationDialog(final Conversation conversation) {
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
|
||||||
builder.setTitle(R.string.disable_notifications);
|
builder.setTitle(R.string.disable_notifications);
|
||||||
final int[] durations = getResources().getIntArray(R.array.mute_options_durations);
|
final int[] durations = getResources().getIntArray(R.array.mute_options_durations);
|
||||||
final CharSequence[] labels = new CharSequence[durations.length];
|
final CharSequence[] labels = new CharSequence[durations.length];
|
||||||
|
@ -2132,7 +2134,7 @@ public class ConversationFragment extends XmppFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showErrorMessage(final Message message) {
|
private void showErrorMessage(final Message message) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
|
||||||
builder.setTitle(R.string.error_message);
|
builder.setTitle(R.string.error_message);
|
||||||
final String errorMessage = message.getErrorMessage();
|
final String errorMessage = message.getErrorMessage();
|
||||||
final String[] errorMessageParts =
|
final String[] errorMessageParts =
|
||||||
|
@ -2159,7 +2161,7 @@ public class ConversationFragment extends XmppFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteFile(final Message message) {
|
private void deleteFile(final Message message) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
builder.setTitle(R.string.delete_file_dialog);
|
builder.setTitle(R.string.delete_file_dialog);
|
||||||
builder.setMessage(R.string.delete_file_dialog_msg);
|
builder.setMessage(R.string.delete_file_dialog_msg);
|
||||||
|
@ -2921,10 +2923,11 @@ public class ConversationFragment extends XmppFragment
|
||||||
status = Presence.Status.OFFLINE;
|
status = Presence.Status.OFFLINE;
|
||||||
}
|
}
|
||||||
this.binding.textSendButton.setTag(action);
|
this.binding.textSendButton.setTag(action);
|
||||||
|
this.binding.textSendButton.setIconResource(SendButtonTool.getSendButtonImageResource(action));
|
||||||
|
this.binding.textSendButton.setIconTint(ColorStateList.valueOf(SendButtonTool.getSendButtonColor(this.binding.textSendButton, status)));
|
||||||
|
// TODO send button color
|
||||||
final Activity activity = getActivity();
|
final Activity activity = getActivity();
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
this.binding.textSendButton.setImageResource(
|
|
||||||
SendButtonTool.getSendButtonImageResource(activity, action, status));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3247,9 +3250,8 @@ public class ConversationFragment extends XmppFragment
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showNoPGPKeyDialog(boolean plural, DialogInterface.OnClickListener listener) {
|
public void showNoPGPKeyDialog(final boolean plural, final DialogInterface.OnClickListener listener) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
|
||||||
builder.setIconAttribute(android.R.attr.alertDialogIcon);
|
|
||||||
if (plural) {
|
if (plural) {
|
||||||
builder.setTitle(getString(R.string.no_pgp_keys));
|
builder.setTitle(getString(R.string.no_pgp_keys));
|
||||||
builder.setMessage(getText(R.string.contacts_have_no_pgp_keys));
|
builder.setMessage(getText(R.string.contacts_have_no_pgp_keys));
|
||||||
|
|
|
@ -59,18 +59,18 @@ import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import org.openintents.openpgp.util.OpenPgpApi;
|
import org.openintents.openpgp.util.OpenPgpApi;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.crypto.OmemoSetting;
|
import eu.siacs.conversations.crypto.OmemoSetting;
|
||||||
import eu.siacs.conversations.databinding.ActivityConversationsBinding;
|
import eu.siacs.conversations.databinding.ActivityConversationsBinding;
|
||||||
import eu.siacs.conversations.entities.Account;
|
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.Conversational;
|
import eu.siacs.conversations.entities.Conversational;
|
||||||
|
@ -80,11 +80,11 @@ import eu.siacs.conversations.ui.interfaces.OnConversationArchived;
|
||||||
import eu.siacs.conversations.ui.interfaces.OnConversationRead;
|
import eu.siacs.conversations.ui.interfaces.OnConversationRead;
|
||||||
import eu.siacs.conversations.ui.interfaces.OnConversationSelected;
|
import eu.siacs.conversations.ui.interfaces.OnConversationSelected;
|
||||||
import eu.siacs.conversations.ui.interfaces.OnConversationsListItemUpdated;
|
import eu.siacs.conversations.ui.interfaces.OnConversationsListItemUpdated;
|
||||||
import eu.siacs.conversations.ui.util.ActionBarUtil;
|
|
||||||
import eu.siacs.conversations.ui.util.ActivityResult;
|
import eu.siacs.conversations.ui.util.ActivityResult;
|
||||||
import eu.siacs.conversations.ui.util.ConversationMenuConfigurator;
|
import eu.siacs.conversations.ui.util.ConversationMenuConfigurator;
|
||||||
import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
|
import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
|
||||||
import eu.siacs.conversations.ui.util.PendingItem;
|
import eu.siacs.conversations.ui.util.PendingItem;
|
||||||
|
import eu.siacs.conversations.ui.util.ToolbarUtils;
|
||||||
import eu.siacs.conversations.utils.ExceptionHelper;
|
import eu.siacs.conversations.utils.ExceptionHelper;
|
||||||
import eu.siacs.conversations.utils.SignupUtils;
|
import eu.siacs.conversations.utils.SignupUtils;
|
||||||
import eu.siacs.conversations.utils.XmppUri;
|
import eu.siacs.conversations.utils.XmppUri;
|
||||||
|
@ -227,10 +227,8 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean openBatteryOptimizationDialogIfNeeded() {
|
private boolean openBatteryOptimizationDialogIfNeeded() {
|
||||||
if (isOptimizingBattery()
|
if (isOptimizingBattery() && getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true)) {
|
||||||
&& android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
&& getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true)) {
|
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setTitle(R.string.battery_optimizations_enabled);
|
builder.setTitle(R.string.battery_optimizations_enabled);
|
||||||
builder.setMessage(getString(R.string.battery_optimizations_enabled_dialog, getString(R.string.app_name)));
|
builder.setMessage(getString(R.string.battery_optimizations_enabled_dialog, getString(R.string.app_name)));
|
||||||
builder.setPositiveButton(R.string.next, (dialog, which) -> {
|
builder.setPositiveButton(R.string.next, (dialog, which) -> {
|
||||||
|
@ -372,6 +370,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
||||||
ConversationMenuConfigurator.reloadFeatures(this);
|
ConversationMenuConfigurator.reloadFeatures(this);
|
||||||
OmemoSetting.load(this);
|
OmemoSetting.load(this);
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_conversations);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_conversations);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
this.getFragmentManager().addOnBackStackChangedListener(this::invalidateActionBarTitle);
|
this.getFragmentManager().addOnBackStackChangedListener(this::invalidateActionBarTitle);
|
||||||
|
@ -466,9 +465,8 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
||||||
conversationFragment.reInit(conversation, extras == null ? new Bundle() : extras);
|
conversationFragment.reInit(conversation, extras == null ? new Bundle() : extras);
|
||||||
if (mainNeedsRefresh) {
|
if (mainNeedsRefresh) {
|
||||||
refreshFragment(R.id.main_fragment);
|
refreshFragment(R.id.main_fragment);
|
||||||
} else {
|
|
||||||
invalidateActionBarTitle();
|
|
||||||
}
|
}
|
||||||
|
invalidateActionBarTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void executePendingTransactions(final FragmentManager fragmentManager) {
|
private static void executePendingTransactions(final FragmentManager fragmentManager) {
|
||||||
|
@ -546,15 +544,8 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
final int theme = findTheme();
|
|
||||||
if (this.mTheme != theme) {
|
|
||||||
this.mSkipBackgroundBinding = true;
|
|
||||||
recreate();
|
|
||||||
} else {
|
|
||||||
this.mSkipBackgroundBinding = false;
|
|
||||||
}
|
|
||||||
mRedirectInProcess.set(false);
|
mRedirectInProcess.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,21 +621,31 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
||||||
}
|
}
|
||||||
final FragmentManager fragmentManager = getFragmentManager();
|
final FragmentManager fragmentManager = getFragmentManager();
|
||||||
final Fragment mainFragment = fragmentManager.findFragmentById(R.id.main_fragment);
|
final Fragment mainFragment = fragmentManager.findFragmentById(R.id.main_fragment);
|
||||||
if (mainFragment instanceof ConversationFragment) {
|
if (mainFragment instanceof ConversationFragment conversationFragment) {
|
||||||
final Conversation conversation = ((ConversationFragment) mainFragment).getConversation();
|
final Conversation conversation = conversationFragment.getConversation();
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
actionBar.setTitle(conversation.getName());
|
actionBar.setTitle(conversation.getName());
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
ActionBarUtil.setActionBarOnClickListener(
|
ToolbarUtils.setActionBarOnClickListener(
|
||||||
binding.toolbar,
|
binding.toolbar,
|
||||||
(v) -> openConversationDetails(conversation)
|
(v) -> openConversationDetails(conversation)
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
actionBar.setTitle(R.string.app_name);
|
final Fragment secondaryFragment = fragmentManager.findFragmentById(R.id.secondary_fragment);
|
||||||
|
if (secondaryFragment instanceof ConversationFragment conversationFragment) {
|
||||||
|
final Conversation conversation = conversationFragment.getConversation();
|
||||||
|
if (conversation != null) {
|
||||||
|
actionBar.setTitle(conversation.getName());
|
||||||
|
} else {
|
||||||
|
actionBar.setTitle(R.string.app_name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
actionBar.setTitle(R.string.app_name);
|
||||||
|
}
|
||||||
actionBar.setDisplayHomeAsUpEnabled(false);
|
actionBar.setDisplayHomeAsUpEnabled(false);
|
||||||
ActionBarUtil.resetActionBarOnClickListeners(binding.toolbar);
|
ToolbarUtils.resetActionBarOnClickListeners(binding.toolbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openConversationDetails(final Conversation conversation) {
|
private void openConversationDetails(final Conversation conversation) {
|
||||||
|
|
|
@ -50,6 +50,8 @@ import androidx.recyclerview.widget.ItemTouchHelper;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
|
|
||||||
|
@ -72,10 +74,8 @@ import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
|
||||||
import eu.siacs.conversations.ui.util.PendingActionHelper;
|
import eu.siacs.conversations.ui.util.PendingActionHelper;
|
||||||
import eu.siacs.conversations.ui.util.PendingItem;
|
import eu.siacs.conversations.ui.util.PendingItem;
|
||||||
import eu.siacs.conversations.ui.util.ScrollState;
|
import eu.siacs.conversations.ui.util.ScrollState;
|
||||||
import eu.siacs.conversations.ui.util.StyledAttributes;
|
|
||||||
import eu.siacs.conversations.utils.AccountUtils;
|
import eu.siacs.conversations.utils.AccountUtils;
|
||||||
import eu.siacs.conversations.utils.EasyOnboardingInvite;
|
import eu.siacs.conversations.utils.EasyOnboardingInvite;
|
||||||
import eu.siacs.conversations.utils.ThemeHelper;
|
|
||||||
|
|
||||||
import static androidx.recyclerview.widget.ItemTouchHelper.LEFT;
|
import static androidx.recyclerview.widget.ItemTouchHelper.LEFT;
|
||||||
import static androidx.recyclerview.widget.ItemTouchHelper.RIGHT;
|
import static androidx.recyclerview.widget.ItemTouchHelper.RIGHT;
|
||||||
|
@ -111,7 +111,7 @@ public class ConversationsOverviewFragment extends XmppFragment {
|
||||||
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
|
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
|
||||||
if(actionState != ItemTouchHelper.ACTION_STATE_IDLE){
|
if(actionState != ItemTouchHelper.ACTION_STATE_IDLE){
|
||||||
Paint paint = new Paint();
|
Paint paint = new Paint();
|
||||||
paint.setColor(StyledAttributes.getColor(activity,R.attr.conversations_overview_background));
|
paint.setColor(MaterialColors.getColor(viewHolder.itemView, com.google.android.material.R.attr.colorSecondaryFixedDim));
|
||||||
paint.setStyle(Paint.Style.FILL);
|
paint.setStyle(Paint.Style.FILL);
|
||||||
c.drawRect(viewHolder.itemView.getLeft(),viewHolder.itemView.getTop()
|
c.drawRect(viewHolder.itemView.getLeft(),viewHolder.itemView.getTop()
|
||||||
,viewHolder.itemView.getRight(),viewHolder.itemView.getBottom(), paint);
|
,viewHolder.itemView.getRight(),viewHolder.itemView.getBottom(), paint);
|
||||||
|
@ -196,8 +196,6 @@ public class ConversationsOverviewFragment extends XmppFragment {
|
||||||
activity.xmppConnectionService.archiveConversation(c);
|
activity.xmppConnectionService.archiveConversation(c);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ThemeHelper.fix(snackbar);
|
|
||||||
snackbar.show();
|
snackbar.show();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -381,14 +379,14 @@ public class ConversationsOverviewFragment extends XmppFragment {
|
||||||
|
|
||||||
private void selectAccountToStartEasyInvite() {
|
private void selectAccountToStartEasyInvite() {
|
||||||
final List<Account> accounts = EasyOnboardingInvite.getSupportingAccounts(activity.xmppConnectionService);
|
final List<Account> accounts = EasyOnboardingInvite.getSupportingAccounts(activity.xmppConnectionService);
|
||||||
if (accounts.size() == 0) {
|
if (accounts.isEmpty()) {
|
||||||
//This can technically happen if opening the menu item races with accounts reconnecting or something
|
//This can technically happen if opening the menu item races with accounts reconnecting or something
|
||||||
Toast.makeText(getActivity(),R.string.no_active_accounts_support_this, Toast.LENGTH_LONG).show();
|
Toast.makeText(getActivity(),R.string.no_active_accounts_support_this, Toast.LENGTH_LONG).show();
|
||||||
} else if (accounts.size() == 1) {
|
} else if (accounts.size() == 1) {
|
||||||
openEasyInviteScreen(accounts.get(0));
|
openEasyInviteScreen(accounts.get(0));
|
||||||
} else {
|
} else {
|
||||||
final AtomicReference<Account> selectedAccount = new AtomicReference<>(accounts.get(0));
|
final AtomicReference<Account> selectedAccount = new AtomicReference<>(accounts.get(0));
|
||||||
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
|
final MaterialAlertDialogBuilder alertDialogBuilder = new MaterialAlertDialogBuilder(activity);
|
||||||
alertDialogBuilder.setTitle(R.string.choose_account);
|
alertDialogBuilder.setTitle(R.string.choose_account);
|
||||||
final String[] asStrings = Collections2.transform(accounts, a -> a.getJid().asBareJid().toEscapedString()).toArray(new String[0]);
|
final String[] asStrings = Collections2.transform(accounts, a -> a.getJid().asBareJid().toEscapedString()).toArray(new String[0]);
|
||||||
alertDialogBuilder.setSingleChoiceItems(asStrings, 0, (dialog, which) -> selectedAccount.set(accounts.get(which)));
|
alertDialogBuilder.setSingleChoiceItems(asStrings, 0, (dialog, which) -> selectedAccount.set(accounts.get(which)));
|
||||||
|
|
|
@ -3,18 +3,20 @@ package eu.siacs.conversations.ui;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.widget.Spinner;
|
import android.widget.AutoCompleteTextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.CreateConferenceDialogBinding;
|
import eu.siacs.conversations.databinding.DialogCreateConferenceBinding;
|
||||||
import eu.siacs.conversations.ui.util.DelayedHintHelper;
|
import eu.siacs.conversations.ui.util.DelayedHintHelper;
|
||||||
|
|
||||||
public class CreatePrivateGroupChatDialog extends DialogFragment {
|
public class CreatePrivateGroupChatDialog extends DialogFragment {
|
||||||
|
@ -39,9 +41,9 @@ public class CreatePrivateGroupChatDialog extends DialogFragment {
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
|
||||||
builder.setTitle(R.string.create_private_group_chat);
|
builder.setTitle(R.string.create_private_group_chat);
|
||||||
CreateConferenceDialogBinding binding = DataBindingUtil.inflate(getActivity().getLayoutInflater(), R.layout.create_conference_dialog, null, false);
|
final DialogCreateConferenceBinding binding = DataBindingUtil.inflate(getActivity().getLayoutInflater(), R.layout.dialog_create_conference, null, false);
|
||||||
ArrayList<String> mActivatedAccounts = getArguments().getStringArrayList(ACCOUNTS_LIST_KEY);
|
ArrayList<String> mActivatedAccounts = getArguments().getStringArrayList(ACCOUNTS_LIST_KEY);
|
||||||
StartConversationActivity.populateAccountSpinner(getActivity(), mActivatedAccounts, binding.account);
|
StartConversationActivity.populateAccountSpinner(getActivity(), mActivatedAccounts, binding.account);
|
||||||
builder.setView(binding.getRoot());
|
builder.setView(binding.getRoot());
|
||||||
|
@ -57,7 +59,7 @@ public class CreatePrivateGroupChatDialog extends DialogFragment {
|
||||||
|
|
||||||
|
|
||||||
public interface CreateConferenceDialogListener {
|
public interface CreateConferenceDialogListener {
|
||||||
void onCreateDialogPositiveClick(Spinner spinner, String subject);
|
void onCreateDialogPositiveClick(AutoCompleteTextView spinner, String subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -17,13 +17,14 @@ import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.CreatePublicChannelDialogBinding;
|
import eu.siacs.conversations.databinding.DialogCreatePublicChannelBinding;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
|
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
|
||||||
|
@ -44,7 +45,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
|
||||||
private boolean nameEntered = false;
|
private boolean nameEntered = false;
|
||||||
private boolean skipTetxWatcher = false;
|
private boolean skipTetxWatcher = false;
|
||||||
|
|
||||||
public static CreatePublicChannelDialog newInstance(List<String> accounts) {
|
public static CreatePublicChannelDialog newInstance(final List<String> accounts) {
|
||||||
CreatePublicChannelDialog dialog = new CreatePublicChannelDialog();
|
CreatePublicChannelDialog dialog = new CreatePublicChannelDialog();
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putStringArrayList(ACCOUNTS_LIST_KEY, (ArrayList<String>) accounts);
|
bundle.putStringArrayList(ACCOUNTS_LIST_KEY, (ArrayList<String>) accounts);
|
||||||
|
@ -63,9 +64,9 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
jidWasModified = savedInstanceState != null && savedInstanceState.getBoolean("jid_was_modified_false", false);
|
jidWasModified = savedInstanceState != null && savedInstanceState.getBoolean("jid_was_modified_false", false);
|
||||||
nameEntered = savedInstanceState != null && savedInstanceState.getBoolean("name_entered", false);
|
nameEntered = savedInstanceState != null && savedInstanceState.getBoolean("name_entered", false);
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
|
||||||
builder.setTitle(R.string.create_public_channel);
|
builder.setTitle(R.string.create_public_channel);
|
||||||
final CreatePublicChannelDialogBinding binding = DataBindingUtil.inflate(getActivity().getLayoutInflater(), R.layout.create_public_channel_dialog, null, false);
|
final DialogCreatePublicChannelBinding binding = DataBindingUtil.inflate(getActivity().getLayoutInflater(), R.layout.dialog_create_public_channel, null, false);
|
||||||
binding.account.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
binding.account.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
@ -107,7 +108,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
|
||||||
builder.setPositiveButton(nameEntered ? R.string.create : R.string.next, null);
|
builder.setPositiveButton(nameEntered ? R.string.create : R.string.next, null);
|
||||||
builder.setNegativeButton(nameEntered ? R.string.back : R.string.cancel, null);
|
builder.setNegativeButton(nameEntered ? R.string.back : R.string.cancel, null);
|
||||||
DelayedHintHelper.setHint(R.string.channel_bare_jid_example, binding.jid);
|
DelayedHintHelper.setHint(R.string.channel_bare_jid_example, binding.jid);
|
||||||
this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.simple_list_item);
|
this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.item_autocomplete);
|
||||||
binding.jid.setAdapter(knownHostsAdapter);
|
binding.jid.setAdapter(knownHostsAdapter);
|
||||||
final AlertDialog dialog = builder.create();
|
final AlertDialog dialog = builder.create();
|
||||||
binding.groupChatName.setOnEditorActionListener((v, actionId, event) -> {
|
binding.groupChatName.setOnEditorActionListener((v, actionId, event) -> {
|
||||||
|
@ -121,7 +122,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateJidSuggestion(CreatePublicChannelDialogBinding binding) {
|
private void updateJidSuggestion(final DialogCreatePublicChannelBinding binding) {
|
||||||
if (jidWasModified) {
|
if (jidWasModified) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -138,7 +139,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getJidSuggestion(CreatePublicChannelDialogBinding binding) {
|
private static String getJidSuggestion(final DialogCreatePublicChannelBinding binding) {
|
||||||
final Account account = StartConversationActivity.getSelectedAccount(binding.getRoot().getContext(), binding.account);
|
final Account account = StartConversationActivity.getSelectedAccount(binding.getRoot().getContext(), binding.account);
|
||||||
final XmppConnection connection = account == null ? null : account.getXmppConnection();
|
final XmppConnection connection = account == null ? null : account.getXmppConnection();
|
||||||
if (connection == null) {
|
if (connection == null) {
|
||||||
|
@ -169,7 +170,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
|
||||||
return name.replaceAll("\\s+","-");
|
return name.replaceAll("\\s+","-");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void goBack(AlertDialog dialog, CreatePublicChannelDialogBinding binding) {
|
private void goBack(AlertDialog dialog, DialogCreatePublicChannelBinding binding) {
|
||||||
if (nameEntered) {
|
if (nameEntered) {
|
||||||
nameEntered = false;
|
nameEntered = false;
|
||||||
updateInputs(binding, true);
|
updateInputs(binding, true);
|
||||||
|
@ -179,7 +180,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void submit(AlertDialog dialog, CreatePublicChannelDialogBinding binding) {
|
private void submit(AlertDialog dialog, DialogCreatePublicChannelBinding binding) {
|
||||||
final Context context = binding.getRoot().getContext();
|
final Context context = binding.getRoot().getContext();
|
||||||
final Editable nameText = binding.groupChatName.getText();
|
final Editable nameText = binding.groupChatName.getText();
|
||||||
final String name = nameText == null ? "" : nameText.toString().trim();
|
final String name = nameText == null ? "" : nameText.toString().trim();
|
||||||
|
@ -227,7 +228,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void updateInputs(CreatePublicChannelDialogBinding binding, boolean requestFocus) {
|
private void updateInputs(final DialogCreatePublicChannelBinding binding, final boolean requestFocus) {
|
||||||
binding.xmppAddressLayout.setVisibility(nameEntered ? View.VISIBLE : View.GONE);
|
binding.xmppAddressLayout.setVisibility(nameEntered ? View.VISIBLE : View.GONE);
|
||||||
binding.nameLayout.setVisibility(nameEntered ? View.GONE : View.VISIBLE);
|
binding.nameLayout.setVisibility(nameEntered ? View.GONE : View.VISIBLE);
|
||||||
if (!requestFocus) {
|
if (!requestFocus) {
|
||||||
|
@ -265,7 +266,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(@NonNull Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
try {
|
try {
|
||||||
mListener = (CreatePublicChannelDialogListener) context;
|
mListener = (CreatePublicChannelDialogListener) context;
|
||||||
|
|
|
@ -33,9 +33,10 @@ import android.widget.Toast;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.ActionBar;
|
import androidx.appcompat.app.ActionBar;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AlertDialog.Builder;
|
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
import com.google.common.base.CharMatcher;
|
import com.google.common.base.CharMatcher;
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
private Jid jidToEdit;
|
private Jid jidToEdit;
|
||||||
private boolean mInitMode = false;
|
private boolean mInitMode = false;
|
||||||
private Boolean mForceRegister = null;
|
private Boolean mForceRegister = null;
|
||||||
private boolean mUsernameMode = Config.DOMAIN_LOCK != null;
|
private boolean mUsernameMode = false;
|
||||||
private boolean mShowOptions = false;
|
private boolean mShowOptions = false;
|
||||||
private Account mAccount;
|
private Account mAccount;
|
||||||
private final OnClickListener mCancelButtonClickListener = v -> {
|
private final OnClickListener mCancelButtonClickListener = v -> {
|
||||||
|
@ -609,6 +610,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
this.mSavedInstanceInit = savedInstanceState.getBoolean("initMode", false);
|
this.mSavedInstanceInit = savedInstanceState.getBoolean("initMode", false);
|
||||||
}
|
}
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_edit_account);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_edit_account);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
binding.accountJid.addTextChangedListener(this.mTextWatcher);
|
binding.accountJid.addTextChangedListener(this.mTextWatcher);
|
||||||
binding.accountJid.setOnFocusChangeListener(this.mEditTextFocusListener);
|
binding.accountJid.setOnFocusChangeListener(this.mEditTextFocusListener);
|
||||||
|
@ -697,13 +699,10 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
final int theme = findTheme();
|
if (intent != null) {
|
||||||
if (this.mTheme != theme) {
|
|
||||||
recreate();
|
|
||||||
} else if (intent != null) {
|
|
||||||
try {
|
try {
|
||||||
this.jidToEdit = Jid.ofEscaped(intent.getStringExtra("jid"));
|
this.jidToEdit = Jid.ofEscaped(intent.getStringExtra("jid"));
|
||||||
} catch (final IllegalArgumentException | NullPointerException ignored) {
|
} catch (final IllegalArgumentException | NullPointerException ignored) {
|
||||||
|
@ -758,7 +757,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayVerificationWarningDialog(final XmppUri xmppUri) {
|
private void displayVerificationWarningDialog(final XmppUri xmppUri) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(R.string.verify_omemo_keys);
|
builder.setTitle(R.string.verify_omemo_keys);
|
||||||
View view = getLayoutInflater().inflate(R.layout.dialog_verify_fingerprints, null);
|
View view = getLayoutInflater().inflate(R.layout.dialog_verify_fingerprints, null);
|
||||||
final CheckBox isTrustedSource = view.findViewById(R.id.trusted_source);
|
final CheckBox isTrustedSource = view.findViewById(R.id.trusted_source);
|
||||||
|
@ -773,7 +772,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(R.string.cancel, (dialog, which) -> finish());
|
builder.setNegativeButton(R.string.cancel, (dialog, which) -> finish());
|
||||||
AlertDialog dialog = builder.create();
|
final var dialog = builder.create();
|
||||||
dialog.setCanceledOnTouchOutside(false);
|
dialog.setCanceledOnTouchOutside(false);
|
||||||
dialog.setOnCancelListener(d -> finish());
|
dialog.setOnCancelListener(d -> finish());
|
||||||
dialog.show();
|
dialog.show();
|
||||||
|
@ -835,7 +834,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
this.binding.accountJidLayout.setHint(getString(R.string.username_hint));
|
this.binding.accountJidLayout.setHint(getString(R.string.username_hint));
|
||||||
} else {
|
} else {
|
||||||
final KnownHostsAdapter mKnownHostsAdapter = new KnownHostsAdapter(this,
|
final KnownHostsAdapter mKnownHostsAdapter = new KnownHostsAdapter(this,
|
||||||
R.layout.simple_list_item,
|
R.layout.item_autocomplete,
|
||||||
xmppConnectionService.getKnownHosts());
|
xmppConnectionService.getKnownHosts());
|
||||||
this.binding.accountJid.setAdapter(mKnownHostsAdapter);
|
this.binding.accountJid.setAdapter(mKnownHostsAdapter);
|
||||||
}
|
}
|
||||||
|
@ -853,7 +852,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
if (mAccount != null && mAccount.getJid().getDomain() != null) {
|
if (mAccount != null && mAccount.getJid().getDomain() != null) {
|
||||||
return mAccount.getServer();
|
return mAccount.getServer();
|
||||||
} else {
|
} else {
|
||||||
return Config.DOMAIN_LOCK;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,7 +939,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
private void changePresence() {
|
private void changePresence() {
|
||||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
boolean manualStatus = sharedPreferences.getBoolean(SettingsActivity.MANUALLY_CHANGE_PRESENCE, getResources().getBoolean(R.bool.manually_change_presence));
|
boolean manualStatus = sharedPreferences.getBoolean(SettingsActivity.MANUALLY_CHANGE_PRESENCE, getResources().getBoolean(R.bool.manually_change_presence));
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
final DialogPresenceBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.dialog_presence, null, false);
|
final DialogPresenceBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.dialog_presence, null, false);
|
||||||
String current = mAccount.getPresenceStatusMessage();
|
String current = mAccount.getPresenceStatusMessage();
|
||||||
if (current != null && !current.trim().isEmpty()) {
|
if (current != null && !current.trim().isEmpty()) {
|
||||||
|
@ -949,7 +948,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
setAvailabilityRadioButton(mAccount.getPresenceStatus(), binding);
|
setAvailabilityRadioButton(mAccount.getPresenceStatus(), binding);
|
||||||
binding.show.setVisibility(manualStatus ? View.VISIBLE : View.GONE);
|
binding.show.setVisibility(manualStatus ? View.VISIBLE : View.GONE);
|
||||||
List<PresenceTemplate> templates = xmppConnectionService.getPresenceTemplates(mAccount);
|
List<PresenceTemplate> templates = xmppConnectionService.getPresenceTemplates(mAccount);
|
||||||
PresenceTemplateAdapter presenceTemplateAdapter = new PresenceTemplateAdapter(this, R.layout.simple_list_item, templates);
|
PresenceTemplateAdapter presenceTemplateAdapter = new PresenceTemplateAdapter(this, R.layout.item_autocomplete, templates);
|
||||||
binding.statusMessage.setAdapter(presenceTemplateAdapter);
|
binding.statusMessage.setAdapter(presenceTemplateAdapter);
|
||||||
binding.statusMessage.setOnItemClickListener((parent, view, position, id) -> {
|
binding.statusMessage.setOnItemClickListener((parent, view, position, id) -> {
|
||||||
PresenceTemplate template = (PresenceTemplate) parent.getItemAtPosition(position);
|
PresenceTemplate template = (PresenceTemplate) parent.getItemAtPosition(position);
|
||||||
|
@ -1144,7 +1143,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
this.binding.pgpFingerprint.setText(OpenPgpUtils.convertKeyIdToHex(pgpKeyId));
|
this.binding.pgpFingerprint.setText(OpenPgpUtils.convertKeyIdToHex(pgpKeyId));
|
||||||
this.binding.pgpFingerprint.setOnClickListener(openPgp);
|
this.binding.pgpFingerprint.setOnClickListener(openPgp);
|
||||||
if ("pgp".equals(messageFingerprint)) {
|
if ("pgp".equals(messageFingerprint)) {
|
||||||
this.binding.pgpFingerprintDesc.setTextAppearance(this, R.style.TextAppearance_Conversations_Caption_Highlight);
|
this.binding.pgpFingerprintDesc.setTextColor(MaterialColors.getColor(binding.pgpFingerprintDesc, com.google.android.material.R.attr.colorPrimaryVariant));
|
||||||
}
|
}
|
||||||
this.binding.pgpFingerprintDesc.setOnClickListener(openPgp);
|
this.binding.pgpFingerprintDesc.setOnClickListener(openPgp);
|
||||||
this.binding.actionDeletePgp.setOnClickListener(delete);
|
this.binding.actionDeletePgp.setOnClickListener(delete);
|
||||||
|
@ -1155,10 +1154,10 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
if (ownAxolotlFingerprint != null && Config.supportOmemo()) {
|
if (ownAxolotlFingerprint != null && Config.supportOmemo()) {
|
||||||
this.binding.axolotlFingerprintBox.setVisibility(View.VISIBLE);
|
this.binding.axolotlFingerprintBox.setVisibility(View.VISIBLE);
|
||||||
if (ownAxolotlFingerprint.equals(messageFingerprint)) {
|
if (ownAxolotlFingerprint.equals(messageFingerprint)) {
|
||||||
this.binding.ownFingerprintDesc.setTextAppearance(this, R.style.TextAppearance_Conversations_Caption_Highlight);
|
this.binding.ownFingerprintDesc.setTextColor(MaterialColors.getColor(binding.ownFingerprintDesc, com.google.android.material.R.attr.colorPrimaryVariant));
|
||||||
this.binding.ownFingerprintDesc.setText(R.string.omemo_fingerprint_selected_message);
|
this.binding.ownFingerprintDesc.setText(R.string.omemo_fingerprint_selected_message);
|
||||||
} else {
|
} else {
|
||||||
this.binding.ownFingerprintDesc.setTextAppearance(this, R.style.TextAppearance_Conversations_Caption);
|
this.binding.ownFingerprintDesc.setTextColor(MaterialColors.getColor(binding.ownFingerprintDesc, com.google.android.material.R.attr.colorOnSurface));
|
||||||
this.binding.ownFingerprintDesc.setText(R.string.omemo_fingerprint);
|
this.binding.ownFingerprintDesc.setText(R.string.omemo_fingerprint);
|
||||||
}
|
}
|
||||||
this.binding.axolotlFingerprint.setText(CryptoHelper.prettifyFingerprint(ownAxolotlFingerprint.substring(2)));
|
this.binding.axolotlFingerprint.setText(CryptoHelper.prettifyFingerprint(ownAxolotlFingerprint.substring(2)));
|
||||||
|
@ -1222,10 +1221,10 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
private void updateDisplayName(String displayName) {
|
private void updateDisplayName(String displayName) {
|
||||||
if (TextUtils.isEmpty(displayName)) {
|
if (TextUtils.isEmpty(displayName)) {
|
||||||
this.binding.yourName.setText(R.string.no_name_set_instructions);
|
this.binding.yourName.setText(R.string.no_name_set_instructions);
|
||||||
this.binding.yourName.setTextAppearance(this, R.style.TextAppearance_Conversations_Body1_Tertiary);
|
this.binding.yourName.setTextColor(MaterialColors.getColor(binding.yourName, com.google.android.material.R.attr.colorOnSurfaceVariant));
|
||||||
} else {
|
} else {
|
||||||
this.binding.yourName.setText(displayName);
|
this.binding.yourName.setText(displayName);
|
||||||
this.binding.yourName.setTextAppearance(this, R.style.TextAppearance_Conversations_Body1);
|
this.binding.yourName.setTextColor(MaterialColors.getColor(binding.yourName, com.google.android.material.R.attr.colorOnSurfaceVariant));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1249,7 +1248,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showDeletePgpDialog() {
|
private void showDeletePgpDialog() {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(R.string.unpublish_pgp);
|
builder.setTitle(R.string.unpublish_pgp);
|
||||||
builder.setMessage(R.string.unpublish_pgp_message);
|
builder.setMessage(R.string.unpublish_pgp_message);
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
|
@ -1279,7 +1278,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
Toast.makeText(EditAccountActivity.this, getString(R.string.device_does_not_support_data_saver, getString(R.string.app_name)), Toast.LENGTH_SHORT).show();
|
Toast.makeText(EditAccountActivity.this, getString(R.string.device_does_not_support_data_saver, getString(R.string.app_name)), Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (showBatteryWarning && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
} else if (showBatteryWarning) {
|
||||||
this.binding.osOptimizationDisable.setText(R.string.disable);
|
this.binding.osOptimizationDisable.setText(R.string.disable);
|
||||||
this.binding.osOptimizationHeadline.setText(R.string.battery_optimizations_enabled);
|
this.binding.osOptimizationHeadline.setText(R.string.battery_optimizations_enabled);
|
||||||
this.binding.osOptimizationBody.setText(getString(R.string.battery_optimizations_enabled_explained, getString(R.string.app_name)));
|
this.binding.osOptimizationBody.setText(getString(R.string.battery_optimizations_enabled_explained, getString(R.string.app_name)));
|
||||||
|
@ -1297,7 +1296,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showWipePepDialog() {
|
public void showWipePepDialog() {
|
||||||
Builder builder = new Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(getString(R.string.clear_other_devices));
|
builder.setTitle(getString(R.string.clear_other_devices));
|
||||||
builder.setIconAttribute(android.R.attr.alertDialogIcon);
|
builder.setIconAttribute(android.R.attr.alertDialogIcon);
|
||||||
builder.setMessage(getString(R.string.clear_other_devices_desc));
|
builder.setMessage(getString(R.string.clear_other_devices_desc));
|
||||||
|
@ -1324,7 +1323,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
if (mCaptchaDialog != null && mCaptchaDialog.isShowing()) {
|
if (mCaptchaDialog != null && mCaptchaDialog.isShowing()) {
|
||||||
mCaptchaDialog.dismiss();
|
mCaptchaDialog.dismiss();
|
||||||
}
|
}
|
||||||
final Builder builder = new Builder(EditAccountActivity.this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(EditAccountActivity.this);
|
||||||
final View view = getLayoutInflater().inflate(R.layout.captcha, null);
|
final View view = getLayoutInflater().inflate(R.layout.captcha, null);
|
||||||
final ImageView imageView = view.findViewById(R.id.captcha);
|
final ImageView imageView = view.findViewById(R.id.captcha);
|
||||||
final EditText input = view.findViewById(R.id.input);
|
final EditText input = view.findViewById(R.id.input);
|
||||||
|
@ -1372,7 +1371,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
|
||||||
if (mFetchingMamPrefsToast != null) {
|
if (mFetchingMamPrefsToast != null) {
|
||||||
mFetchingMamPrefsToast.cancel();
|
mFetchingMamPrefsToast.cancel();
|
||||||
}
|
}
|
||||||
Builder builder = new Builder(EditAccountActivity.this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(EditAccountActivity.this);
|
||||||
builder.setTitle(R.string.server_side_mam_prefs);
|
builder.setTitle(R.string.server_side_mam_prefs);
|
||||||
String defaultAttr = prefs.getAttribute("default");
|
String defaultAttr = prefs.getAttribute("default");
|
||||||
final List<String> defaults = Arrays.asList("never", "roster", "always");
|
final List<String> defaults = Arrays.asList("never", "roster", "always");
|
||||||
|
|
|
@ -13,15 +13,17 @@ import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.EnterJidDialogBinding;
|
import eu.siacs.conversations.databinding.DialogEnterJidBinding;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
|
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
|
||||||
import eu.siacs.conversations.ui.interfaces.OnBackendConnected;
|
import eu.siacs.conversations.ui.interfaces.OnBackendConnected;
|
||||||
|
@ -46,28 +48,28 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
|
||||||
private KnownHostsAdapter knownHostsAdapter;
|
private KnownHostsAdapter knownHostsAdapter;
|
||||||
private Collection<String> whitelistedDomains = Collections.emptyList();
|
private Collection<String> whitelistedDomains = Collections.emptyList();
|
||||||
|
|
||||||
private EnterJidDialogBinding binding;
|
private DialogEnterJidBinding binding;
|
||||||
private AlertDialog dialog;
|
private AlertDialog dialog;
|
||||||
private boolean sanityCheckJid = false;
|
private boolean sanityCheckJid = false;
|
||||||
|
|
||||||
private boolean issuedWarning = false;
|
private boolean issuedWarning = false;
|
||||||
|
|
||||||
public static EnterJidDialog newInstance(
|
public static EnterJidDialog newInstance(
|
||||||
final List<String> activatedAccounts,
|
final ArrayList<String> activatedAccounts,
|
||||||
final String title,
|
final String title,
|
||||||
final String positiveButton,
|
final String positiveButton,
|
||||||
final String prefilledJid,
|
final String prefilledJid,
|
||||||
final String account,
|
final String account,
|
||||||
boolean allowEditJid,
|
boolean allowEditJid,
|
||||||
final boolean sanity_check_jid) {
|
final boolean sanity_check_jid) {
|
||||||
EnterJidDialog dialog = new EnterJidDialog();
|
final EnterJidDialog dialog = new EnterJidDialog();
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putString(TITLE_KEY, title);
|
bundle.putString(TITLE_KEY, title);
|
||||||
bundle.putString(POSITIVE_BUTTON_KEY, positiveButton);
|
bundle.putString(POSITIVE_BUTTON_KEY, positiveButton);
|
||||||
bundle.putString(PREFILLED_JID_KEY, prefilledJid);
|
bundle.putString(PREFILLED_JID_KEY, prefilledJid);
|
||||||
bundle.putString(ACCOUNT_KEY, account);
|
bundle.putString(ACCOUNT_KEY, account);
|
||||||
bundle.putBoolean(ALLOW_EDIT_JID_KEY, allowEditJid);
|
bundle.putBoolean(ALLOW_EDIT_JID_KEY, allowEditJid);
|
||||||
bundle.putStringArrayList(ACCOUNTS_LIST_KEY, (ArrayList<String>) activatedAccounts);
|
bundle.putStringArrayList(ACCOUNTS_LIST_KEY, activatedAccounts);
|
||||||
bundle.putBoolean(SANITY_CHECK_JID, sanity_check_jid);
|
bundle.putBoolean(SANITY_CHECK_JID, sanity_check_jid);
|
||||||
dialog.setArguments(bundle);
|
dialog.setArguments(bundle);
|
||||||
return dialog;
|
return dialog;
|
||||||
|
@ -91,16 +93,16 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
final var arguments = getArguments();
|
||||||
builder.setTitle(getArguments().getString(TITLE_KEY));
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
|
||||||
|
builder.setTitle(arguments.getString(TITLE_KEY));
|
||||||
binding =
|
binding =
|
||||||
DataBindingUtil.inflate(
|
DataBindingUtil.inflate(requireActivity().getLayoutInflater(), R.layout.dialog_enter_jid, null, false);
|
||||||
getActivity().getLayoutInflater(), R.layout.enter_jid_dialog, null, false);
|
this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.item_autocomplete);
|
||||||
this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.simple_list_item);
|
|
||||||
binding.jid.setAdapter(this.knownHostsAdapter);
|
binding.jid.setAdapter(this.knownHostsAdapter);
|
||||||
binding.jid.addTextChangedListener(this);
|
binding.jid.addTextChangedListener(this);
|
||||||
String prefilledJid = getArguments().getString(PREFILLED_JID_KEY);
|
final String prefilledJid = arguments.getString(PREFILLED_JID_KEY);
|
||||||
if (prefilledJid != null) {
|
if (prefilledJid != null) {
|
||||||
binding.jid.append(prefilledJid);
|
binding.jid.append(prefilledJid);
|
||||||
if (!getArguments().getBoolean(ALLOW_EDIT_JID_KEY)) {
|
if (!getArguments().getBoolean(ALLOW_EDIT_JID_KEY)) {
|
||||||
|
@ -114,18 +116,18 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
|
||||||
|
|
||||||
DelayedHintHelper.setHint(R.string.account_settings_example_jabber_id, binding.jid);
|
DelayedHintHelper.setHint(R.string.account_settings_example_jabber_id, binding.jid);
|
||||||
|
|
||||||
String account = getArguments().getString(ACCOUNT_KEY);
|
final String account = getArguments().getString(ACCOUNT_KEY);
|
||||||
if (account == null) {
|
if (Strings.isNullOrEmpty(account)) {
|
||||||
StartConversationActivity.populateAccountSpinner(
|
StartConversationActivity.populateAccountSpinner(
|
||||||
getActivity(),
|
getActivity(),
|
||||||
getArguments().getStringArrayList(ACCOUNTS_LIST_KEY),
|
arguments.getStringArrayList(ACCOUNTS_LIST_KEY),
|
||||||
binding.account);
|
binding.account);
|
||||||
} else {
|
} else {
|
||||||
ArrayAdapter<String> adapter =
|
final ArrayAdapter<String> adapter =
|
||||||
new ArrayAdapter<>(
|
new ArrayAdapter<>(requireActivity(), R.layout.item_autocomplete, new String[] {account});
|
||||||
getActivity(), R.layout.simple_list_item, new String[] {account});
|
binding.account.setText(account);
|
||||||
binding.account.setEnabled(false);
|
binding.account.setEnabled(false);
|
||||||
adapter.setDropDownViewResource(R.layout.simple_list_item);
|
adapter.setDropDownViewResource(R.layout.item_autocomplete);
|
||||||
binding.account.setAdapter(adapter);
|
binding.account.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,9 +137,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
|
||||||
this.dialog = builder.create();
|
this.dialog = builder.create();
|
||||||
|
|
||||||
View.OnClickListener dialogOnClick =
|
View.OnClickListener dialogOnClick =
|
||||||
v -> {
|
v -> handleEnter(binding, account);
|
||||||
handleEnter(binding, account);
|
|
||||||
};
|
|
||||||
|
|
||||||
binding.jid.setOnEditorActionListener(
|
binding.jid.setOnEditorActionListener(
|
||||||
(v, actionId, event) -> {
|
(v, actionId, event) -> {
|
||||||
|
@ -150,21 +150,13 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleEnter(EnterJidDialogBinding binding, String account) {
|
private void handleEnter(DialogEnterJidBinding binding, String account) {
|
||||||
final Jid accountJid;
|
final Jid accountJid;
|
||||||
if (!binding.account.isEnabled() && account == null) {
|
if (!binding.account.isEnabled() && account == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (Config.DOMAIN_LOCK != null) {
|
accountJid = Jid.ofEscaped((String) binding.account.getEditableText().toString());
|
||||||
accountJid =
|
|
||||||
Jid.ofEscaped(
|
|
||||||
(String) binding.account.getSelectedItem(),
|
|
||||||
Config.DOMAIN_LOCK,
|
|
||||||
null);
|
|
||||||
} else {
|
|
||||||
accountJid = Jid.ofEscaped((String) binding.account.getSelectedItem());
|
|
||||||
}
|
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -50,11 +51,11 @@ public class JoinConferenceDialog extends DialogFragment implements OnBackendCon
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
|
||||||
builder.setTitle(R.string.join_public_channel);
|
builder.setTitle(R.string.join_public_channel);
|
||||||
DialogJoinConferenceBinding binding = DataBindingUtil.inflate(getActivity().getLayoutInflater(), R.layout.dialog_join_conference, null, false);
|
final DialogJoinConferenceBinding binding = DataBindingUtil.inflate(getActivity().getLayoutInflater(), R.layout.dialog_join_conference, null, false);
|
||||||
DelayedHintHelper.setHint(R.string.channel_full_jid_example, binding.jid);
|
DelayedHintHelper.setHint(R.string.channel_full_jid_example, binding.jid);
|
||||||
this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.simple_list_item);
|
this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.item_autocomplete);
|
||||||
binding.jid.setAdapter(knownHostsAdapter);
|
binding.jid.setAdapter(knownHostsAdapter);
|
||||||
String prefilledJid = getArguments().getString(PREFILLED_JID_KEY);
|
String prefilledJid = getArguments().getString(PREFILLED_JID_KEY);
|
||||||
if (prefilledJid != null) {
|
if (prefilledJid != null) {
|
||||||
|
@ -117,6 +118,6 @@ public class JoinConferenceDialog extends DialogFragment implements OnBackendCon
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface JoinConferenceDialogListener {
|
public interface JoinConferenceDialogListener {
|
||||||
void onJoinDialogPositiveClick(Dialog dialog, Spinner spinner, TextInputLayout jidLayout, AutoCompleteTextView jid, boolean isBookmarkChecked);
|
void onJoinDialogPositiveClick(Dialog dialog, AutoCompleteTextView spinner, TextInputLayout jidLayout, AutoCompleteTextView jid, boolean isBookmarkChecked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ import eu.siacs.conversations.ui.util.LocationHelper;
|
||||||
import eu.siacs.conversations.ui.widget.Marker;
|
import eu.siacs.conversations.ui.widget.Marker;
|
||||||
import eu.siacs.conversations.ui.widget.MyLocation;
|
import eu.siacs.conversations.ui.widget.MyLocation;
|
||||||
import eu.siacs.conversations.ui.util.SettingsUtils;
|
import eu.siacs.conversations.ui.util.SettingsUtils;
|
||||||
import eu.siacs.conversations.utils.ThemeHelper;
|
|
||||||
|
|
||||||
public abstract class LocationActivity extends ActionBarActivity implements LocationListener {
|
public abstract class LocationActivity extends ActionBarActivity implements LocationListener {
|
||||||
protected LocationManager locationManager;
|
protected LocationManager locationManager;
|
||||||
|
@ -78,7 +77,6 @@ public abstract class LocationActivity extends ActionBarActivity implements Loca
|
||||||
protected void onCreate(final Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
final Context ctx = getApplicationContext();
|
final Context ctx = getApplicationContext();
|
||||||
setTheme(ThemeHelper.find(this));
|
|
||||||
|
|
||||||
final PackageManager packageManager = ctx.getPackageManager();
|
final PackageManager packageManager = ctx.getPackageManager();
|
||||||
hasLocationFeature = packageManager.hasSystemFeature(PackageManager.FEATURE_LOCATION) ||
|
hasLocationFeature = packageManager.hasSystemFeature(PackageManager.FEATURE_LOCATION) ||
|
||||||
|
@ -90,7 +88,7 @@ public abstract class LocationActivity extends ActionBarActivity implements Loca
|
||||||
// Ask for location permissions if location services are enabled and we're
|
// Ask for location permissions if location services are enabled and we're
|
||||||
// just starting the activity (we don't want to keep pestering them on every
|
// just starting the activity (we don't want to keep pestering them on every
|
||||||
// screen rotation or if there's no point because it's disabled anyways).
|
// screen rotation or if there's no point because it's disabled anyways).
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
requestPermissions(REQUEST_CODE_CREATE);
|
requestPermissions(REQUEST_CODE_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +222,6 @@ public abstract class LocationActivity extends ActionBarActivity implements Loca
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
SettingsUtils.applyScreenshotPreventionSetting(this);
|
|
||||||
Configuration.getInstance().load(this, getPreferences());
|
Configuration.getInstance().load(this, getPreferences());
|
||||||
map.onResume();
|
map.onResume();
|
||||||
this.setMyLoc(null);
|
this.setMyLoc(null);
|
||||||
|
|
|
@ -29,6 +29,7 @@ public class MediaBrowserActivity extends XmppActivity implements OnMediaLoaded
|
||||||
protected void onCreate(final Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
this.binding = DataBindingUtil.setContentView(this,R.layout.activity_media_browser);
|
this.binding = DataBindingUtil.setContentView(this,R.layout.activity_media_browser);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
mMediaAdapter = new MediaAdapter(this, R.dimen.media_size);
|
mMediaAdapter = new MediaAdapter(this, R.dimen.media_size);
|
||||||
|
|
|
@ -33,6 +33,8 @@ import android.os.Bundle;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -40,7 +42,6 @@ import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.entities.MTMDecision;
|
import eu.siacs.conversations.entities.MTMDecision;
|
||||||
import eu.siacs.conversations.services.MemorizingTrustManager;
|
import eu.siacs.conversations.services.MemorizingTrustManager;
|
||||||
import eu.siacs.conversations.ui.util.SettingsUtils;
|
import eu.siacs.conversations.ui.util.SettingsUtils;
|
||||||
import eu.siacs.conversations.utils.ThemeHelper;
|
|
||||||
|
|
||||||
public class MemorizingActivity extends AppCompatActivity implements OnClickListener, OnCancelListener {
|
public class MemorizingActivity extends AppCompatActivity implements OnClickListener, OnCancelListener {
|
||||||
|
|
||||||
|
@ -53,10 +54,7 @@ public class MemorizingActivity extends AppCompatActivity implements OnClickList
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
LOGGER.log(Level.FINE, "onCreate");
|
LOGGER.log(Level.FINE, "onCreate");
|
||||||
setTheme(ThemeHelper.find(this));
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
getLayoutInflater().inflate(R.layout.toolbar, findViewById(android.R.id.content));
|
|
||||||
setSupportActionBar(findViewById(R.id.toolbar));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -69,7 +67,7 @@ public class MemorizingActivity extends AppCompatActivity implements OnClickList
|
||||||
int titleId = i.getIntExtra(MemorizingTrustManager.DECISION_TITLE_ID, R.string.mtm_accept_cert);
|
int titleId = i.getIntExtra(MemorizingTrustManager.DECISION_TITLE_ID, R.string.mtm_accept_cert);
|
||||||
String cert = i.getStringExtra(MemorizingTrustManager.DECISION_INTENT_CERT);
|
String cert = i.getStringExtra(MemorizingTrustManager.DECISION_INTENT_CERT);
|
||||||
LOGGER.log(Level.FINE, "onResume with " + i.getExtras() + " decId=" + decisionId + " data: " + i.getData());
|
LOGGER.log(Level.FINE, "onResume with " + i.getExtras() + " decId=" + decisionId + " data: " + i.getData());
|
||||||
dialog = new AlertDialog.Builder(this).setTitle(titleId)
|
dialog = new MaterialAlertDialogBuilder(this).setTitle(titleId)
|
||||||
.setMessage(cert)
|
.setMessage(cert)
|
||||||
.setPositiveButton(R.string.always, this)
|
.setPositiveButton(R.string.always, this)
|
||||||
.setNeutralButton(R.string.once, this)
|
.setNeutralButton(R.string.once, this)
|
||||||
|
|
|
@ -102,8 +102,9 @@ public class MucUsersActivity extends XmppActivity implements XmppConnectionServ
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(final Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
ActivityMucUsersBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_muc_users);
|
final ActivityMucUsersBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_muc_users);
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
configureActionBar(getSupportActionBar(), true);
|
configureActionBar(getSupportActionBar(), true);
|
||||||
this.userAdapter = new UserAdapter(getPreferences().getBoolean("advanced_muc_mode", false));
|
this.userAdapter = new UserAdapter(getPreferences().getBoolean("advanced_muc_mode", false));
|
||||||
binding.list.setAdapter(this.userAdapter);
|
binding.list.setAdapter(this.userAdapter);
|
||||||
|
|
|
@ -11,6 +11,9 @@ import android.widget.Toast;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.crypto.axolotl.FingerprintStatus;
|
import eu.siacs.conversations.crypto.axolotl.FingerprintStatus;
|
||||||
|
@ -33,10 +36,7 @@ public abstract class OmemoActivity extends XmppActivity {
|
||||||
Object account = v.getTag(R.id.TAG_ACCOUNT);
|
Object account = v.getTag(R.id.TAG_ACCOUNT);
|
||||||
Object fingerprint = v.getTag(R.id.TAG_FINGERPRINT);
|
Object fingerprint = v.getTag(R.id.TAG_FINGERPRINT);
|
||||||
Object fingerprintStatus = v.getTag(R.id.TAG_FINGERPRINT_STATUS);
|
Object fingerprintStatus = v.getTag(R.id.TAG_FINGERPRINT_STATUS);
|
||||||
if (account != null
|
if (account instanceof Account
|
||||||
&& fingerprint != null
|
|
||||||
&& account instanceof Account
|
|
||||||
&& fingerprintStatus != null
|
|
||||||
&& fingerprint instanceof String
|
&& fingerprint instanceof String
|
||||||
&& fingerprintStatus instanceof FingerprintStatus) {
|
&& fingerprintStatus instanceof FingerprintStatus) {
|
||||||
getMenuInflater().inflate(R.menu.omemo_key_context, menu);
|
getMenuInflater().inflate(R.menu.omemo_key_context, menu);
|
||||||
|
@ -130,8 +130,8 @@ public abstract class OmemoActivity extends XmppActivity {
|
||||||
binding.tglTrust.setChecked(status.isTrusted());
|
binding.tglTrust.setChecked(status.isTrusted());
|
||||||
|
|
||||||
if (status.isActive()) {
|
if (status.isActive()) {
|
||||||
binding.key.setTextAppearance(this,R.style.TextAppearance_Conversations_Fingerprint);
|
binding.key.setTextColor(MaterialColors.getColor(binding.key, com.google.android.material.R.attr.colorOnSurface));
|
||||||
binding.keyType.setTextAppearance(this,R.style.TextAppearance_Conversations_Caption);
|
binding.keyType.setTextColor(MaterialColors.getColor(binding.keyType, com.google.android.material.R.attr.colorOnSurface));
|
||||||
if (status.isVerified()) {
|
if (status.isVerified()) {
|
||||||
binding.verifiedFingerprint.setVisibility(View.VISIBLE);
|
binding.verifiedFingerprint.setVisibility(View.VISIBLE);
|
||||||
binding.verifiedFingerprint.setAlpha(1.0f);
|
binding.verifiedFingerprint.setAlpha(1.0f);
|
||||||
|
@ -157,8 +157,8 @@ public abstract class OmemoActivity extends XmppActivity {
|
||||||
toast = v -> hideToast();
|
toast = v -> hideToast();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
binding.key.setTextAppearance(this,R.style.TextAppearance_Conversations_Fingerprint_Disabled);
|
binding.key.setTextColor(MaterialColors.getColor(binding.key, com.google.android.material.R.attr.colorOnSurfaceVariant));
|
||||||
binding.keyType.setTextAppearance(this,R.style.TextAppearance_Conversations_Caption_Disabled);
|
binding.keyType.setTextColor(MaterialColors.getColor(binding.keyType, com.google.android.material.R.attr.colorOnSurfaceVariant));
|
||||||
toast = v -> replaceToast(getString(R.string.this_device_is_no_longer_in_use), false);
|
toast = v -> replaceToast(getString(R.string.this_device_is_no_longer_in_use), false);
|
||||||
if (status.isVerified()) {
|
if (status.isVerified()) {
|
||||||
binding.tglTrust.setVisibility(View.GONE);
|
binding.tglTrust.setVisibility(View.GONE);
|
||||||
|
@ -181,7 +181,7 @@ public abstract class OmemoActivity extends XmppActivity {
|
||||||
binding.keyType.setVisibility(View.GONE);
|
binding.keyType.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
if (highlight) {
|
if (highlight) {
|
||||||
binding.keyType.setTextAppearance(this,R.style.TextAppearance_Conversations_Caption_Highlight);
|
binding.keyType.setTextColor(MaterialColors.getColor(binding.keyType, com.google.android.material.R.attr.colorPrimaryVariant));
|
||||||
binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509_selected_message : R.string.omemo_fingerprint_selected_message));
|
binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509_selected_message : R.string.omemo_fingerprint_selected_message));
|
||||||
} else {
|
} else {
|
||||||
binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint));
|
binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint));
|
||||||
|
@ -191,7 +191,7 @@ public abstract class OmemoActivity extends XmppActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showPurgeKeyDialog(final Account account, final String fingerprint) {
|
public void showPurgeKeyDialog(final Account account, final String fingerprint) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(R.string.distrust_omemo_key);
|
builder.setTitle(R.string.distrust_omemo_key);
|
||||||
builder.setMessage(R.string.distrust_omemo_key_text);
|
builder.setMessage(R.string.distrust_omemo_key_text);
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
builder.setNegativeButton(getString(R.string.cancel), null);
|
||||||
|
|
|
@ -91,6 +91,7 @@ public class PublishGroupChatProfilePictureActivity extends XmppActivity impleme
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_publish_profile_picture);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_publish_profile_picture);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(this.binding.toolbar);
|
setSupportActionBar(this.binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
this.binding.cancelButton.setOnClickListener((v) -> this.finish());
|
this.binding.cancelButton.setOnClickListener((v) -> this.finish());
|
||||||
|
@ -114,6 +115,7 @@ public class PublishGroupChatProfilePictureActivity extends XmppActivity impleme
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
|
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
|
||||||
final CropImage.ActivityResult result = CropImage.getActivityResult(data);
|
final CropImage.ActivityResult result = CropImage.getActivityResult(data);
|
||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
|
|
|
@ -18,6 +18,7 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
import com.canhub.cropper.CropImage;
|
import com.canhub.cropper.CropImage;
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.databinding.ActivityPublishProfilePictureBinding;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.ui.interfaces.OnAvatarPublication;
|
import eu.siacs.conversations.ui.interfaces.OnAvatarPublication;
|
||||||
|
@ -77,7 +79,6 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
|
||||||
public void onAvatarPublicationFailed(int res) {
|
public void onAvatarPublicationFailed(int res) {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
hintOrWarning.setText(res);
|
hintOrWarning.setText(res);
|
||||||
hintOrWarning.setTextAppearance(this,R.style.TextAppearance_Conversations_Body1_Warning);
|
|
||||||
hintOrWarning.setVisibility(View.VISIBLE);
|
hintOrWarning.setVisibility(View.VISIBLE);
|
||||||
publishing = false;
|
publishing = false;
|
||||||
togglePublishButton(true, R.string.publish);
|
togglePublishButton(true, R.string.publish);
|
||||||
|
@ -87,8 +88,12 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_publish_profile_picture);
|
|
||||||
setSupportActionBar(findViewById(R.id.toolbar));
|
ActivityPublishProfilePictureBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_publish_profile_picture);
|
||||||
|
|
||||||
|
setSupportActionBar(binding.toolbar);
|
||||||
|
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
|
|
||||||
this.avatar = findViewById(R.id.account_image);
|
this.avatar = findViewById(R.id.account_image);
|
||||||
this.cancelButton = findViewById(R.id.cancel_button);
|
this.cancelButton = findViewById(R.id.cancel_button);
|
||||||
|
@ -220,7 +225,7 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
this.mInitialAccountSetup = intent != null && intent.getBooleanExtra("setup", false);
|
this.mInitialAccountSetup = intent != null && intent.getBooleanExtra("setup", false);
|
||||||
|
@ -261,7 +266,6 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
|
||||||
if (bm == null) {
|
if (bm == null) {
|
||||||
togglePublishButton(false, R.string.publish);
|
togglePublishButton(false, R.string.publish);
|
||||||
this.hintOrWarning.setVisibility(View.VISIBLE);
|
this.hintOrWarning.setVisibility(View.VISIBLE);
|
||||||
this.hintOrWarning.setTextAppearance(this,R.style.TextAppearance_Conversations_Body1_Warning);
|
|
||||||
this.hintOrWarning.setText(R.string.error_publish_avatar_converting);
|
this.hintOrWarning.setText(R.string.error_publish_avatar_converting);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -272,7 +276,6 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
|
||||||
} else {
|
} else {
|
||||||
togglePublishButton(false, R.string.publish);
|
togglePublishButton(false, R.string.publish);
|
||||||
this.hintOrWarning.setVisibility(View.VISIBLE);
|
this.hintOrWarning.setVisibility(View.VISIBLE);
|
||||||
this.hintOrWarning.setTextAppearance(this,R.style.TextAppearance_Conversations_Body1_Warning);
|
|
||||||
if (account.getStatus() == Account.State.ONLINE) {
|
if (account.getStatus() == Account.State.ONLINE) {
|
||||||
this.hintOrWarning.setText(R.string.error_publish_avatar_no_server_support);
|
this.hintOrWarning.setText(R.string.error_publish_avatar_no_server_support);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
@ -33,10 +34,9 @@ import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.ActivityRecordingBinding;
|
import eu.siacs.conversations.databinding.ActivityRecordingBinding;
|
||||||
import eu.siacs.conversations.ui.util.SettingsUtils;
|
import eu.siacs.conversations.ui.util.SettingsUtils;
|
||||||
import eu.siacs.conversations.utils.ThemeHelper;
|
|
||||||
import eu.siacs.conversations.utils.TimeFrameUtils;
|
import eu.siacs.conversations.utils.TimeFrameUtils;
|
||||||
|
|
||||||
public class RecordingActivity extends Activity implements View.OnClickListener {
|
public class RecordingActivity extends BaseActivity implements View.OnClickListener {
|
||||||
|
|
||||||
private ActivityRecordingBinding binding;
|
private ActivityRecordingBinding binding;
|
||||||
|
|
||||||
|
@ -61,7 +61,6 @@ public class RecordingActivity extends Activity implements View.OnClickListener
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setTheme(ThemeHelper.findDialog(this));
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_recording);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_recording);
|
||||||
this.binding.cancelButton.setOnClickListener(this);
|
this.binding.cancelButton.setOnClickListener(this);
|
||||||
|
@ -69,19 +68,13 @@ public class RecordingActivity extends Activity implements View.OnClickListener
|
||||||
this.setFinishOnTouchOutside(false);
|
this.setFinishOnTouchOutside(false);
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
public void onStart() {
|
||||||
super.onResume();
|
|
||||||
SettingsUtils.applyScreenshotPreventionSetting(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
super.onStart();
|
||||||
if (!startRecording()) {
|
if (!startRecording()) {
|
||||||
this.binding.shareButton.setEnabled(false);
|
this.binding.shareButton.setEnabled(false);
|
||||||
this.binding.timer.setTextAppearance(this, R.style.TextAppearance_Conversations_Title);
|
this.binding.timer.setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_BodyMedium);
|
||||||
|
// TODO reset font family. make red?
|
||||||
this.binding.timer.setText(R.string.unable_to_start_recording);
|
this.binding.timer.setText(R.string.unable_to_start_recording);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,6 +179,7 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_rtp_session);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_rtp_session);
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -920,34 +921,34 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
} else if (state == RtpEndUserState.INCOMING_CALL) {
|
} else if (state == RtpEndUserState.INCOMING_CALL) {
|
||||||
this.binding.rejectCall.setContentDescription(getString(R.string.dismiss_call));
|
this.binding.rejectCall.setContentDescription(getString(R.string.dismiss_call));
|
||||||
this.binding.rejectCall.setOnClickListener(this::rejectCall);
|
this.binding.rejectCall.setOnClickListener(this::rejectCall);
|
||||||
this.binding.rejectCall.setImageResource(R.drawable.ic_call_end_white_48dp);
|
this.binding.rejectCall.setImageResource(R.drawable.ic_call_end_24dp);
|
||||||
this.binding.rejectCall.setVisibility(View.VISIBLE);
|
this.binding.rejectCall.setVisibility(View.VISIBLE);
|
||||||
this.binding.endCall.setVisibility(View.INVISIBLE);
|
this.binding.endCall.setVisibility(View.INVISIBLE);
|
||||||
this.binding.acceptCall.setContentDescription(getString(R.string.answer_call));
|
this.binding.acceptCall.setContentDescription(getString(R.string.answer_call));
|
||||||
this.binding.acceptCall.setOnClickListener(this::acceptCall);
|
this.binding.acceptCall.setOnClickListener(this::acceptCall);
|
||||||
this.binding.acceptCall.setImageResource(R.drawable.ic_call_white_48dp);
|
this.binding.acceptCall.setImageResource(R.drawable.ic_call_24dp);
|
||||||
this.binding.acceptCall.setVisibility(View.VISIBLE);
|
this.binding.acceptCall.setVisibility(View.VISIBLE);
|
||||||
} else if (state == RtpEndUserState.INCOMING_CONTENT_ADD) {
|
} else if (state == RtpEndUserState.INCOMING_CONTENT_ADD) {
|
||||||
this.binding.rejectCall.setContentDescription(
|
this.binding.rejectCall.setContentDescription(
|
||||||
getString(R.string.reject_switch_to_video));
|
getString(R.string.reject_switch_to_video));
|
||||||
this.binding.rejectCall.setOnClickListener(this::rejectContentAdd);
|
this.binding.rejectCall.setOnClickListener(this::rejectContentAdd);
|
||||||
this.binding.rejectCall.setImageResource(R.drawable.ic_clear_white_48dp);
|
this.binding.rejectCall.setImageResource(R.drawable.ic_clear_24dp);
|
||||||
this.binding.rejectCall.setVisibility(View.VISIBLE);
|
this.binding.rejectCall.setVisibility(View.VISIBLE);
|
||||||
this.binding.endCall.setVisibility(View.INVISIBLE);
|
this.binding.endCall.setVisibility(View.INVISIBLE);
|
||||||
this.binding.acceptCall.setContentDescription(getString(R.string.accept));
|
this.binding.acceptCall.setContentDescription(getString(R.string.accept));
|
||||||
this.binding.acceptCall.setOnClickListener((v -> acceptContentAdd(contentAddition)));
|
this.binding.acceptCall.setOnClickListener((v -> acceptContentAdd(contentAddition)));
|
||||||
this.binding.acceptCall.setImageResource(R.drawable.ic_baseline_check_24);
|
this.binding.acceptCall.setImageResource(R.drawable.ic_check_24dp);
|
||||||
this.binding.acceptCall.setVisibility(View.VISIBLE);
|
this.binding.acceptCall.setVisibility(View.VISIBLE);
|
||||||
} else if (asList(RtpEndUserState.DECLINED_OR_BUSY, RtpEndUserState.CONTACT_OFFLINE)
|
} else if (asList(RtpEndUserState.DECLINED_OR_BUSY, RtpEndUserState.CONTACT_OFFLINE)
|
||||||
.contains(state)) {
|
.contains(state)) {
|
||||||
this.binding.rejectCall.setContentDescription(getString(R.string.exit));
|
this.binding.rejectCall.setContentDescription(getString(R.string.exit));
|
||||||
this.binding.rejectCall.setOnClickListener(this::exit);
|
this.binding.rejectCall.setOnClickListener(this::exit);
|
||||||
this.binding.rejectCall.setImageResource(R.drawable.ic_clear_white_48dp);
|
this.binding.rejectCall.setImageResource(R.drawable.ic_clear_24dp);
|
||||||
this.binding.rejectCall.setVisibility(View.VISIBLE);
|
this.binding.rejectCall.setVisibility(View.VISIBLE);
|
||||||
this.binding.endCall.setVisibility(View.INVISIBLE);
|
this.binding.endCall.setVisibility(View.INVISIBLE);
|
||||||
this.binding.acceptCall.setContentDescription(getString(R.string.record_voice_mail));
|
this.binding.acceptCall.setContentDescription(getString(R.string.record_voice_mail));
|
||||||
this.binding.acceptCall.setOnClickListener(this::recordVoiceMail);
|
this.binding.acceptCall.setOnClickListener(this::recordVoiceMail);
|
||||||
this.binding.acceptCall.setImageResource(R.drawable.ic_voicemail_white_24dp);
|
this.binding.acceptCall.setImageResource(R.drawable.ic_voicemail_24dp);
|
||||||
this.binding.acceptCall.setVisibility(View.VISIBLE);
|
this.binding.acceptCall.setVisibility(View.VISIBLE);
|
||||||
} else if (asList(
|
} else if (asList(
|
||||||
RtpEndUserState.CONNECTIVITY_ERROR,
|
RtpEndUserState.CONNECTIVITY_ERROR,
|
||||||
|
@ -958,18 +959,18 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
.contains(state)) {
|
.contains(state)) {
|
||||||
this.binding.rejectCall.setContentDescription(getString(R.string.exit));
|
this.binding.rejectCall.setContentDescription(getString(R.string.exit));
|
||||||
this.binding.rejectCall.setOnClickListener(this::exit);
|
this.binding.rejectCall.setOnClickListener(this::exit);
|
||||||
this.binding.rejectCall.setImageResource(R.drawable.ic_clear_white_48dp);
|
this.binding.rejectCall.setImageResource(R.drawable.ic_clear_24dp);
|
||||||
this.binding.rejectCall.setVisibility(View.VISIBLE);
|
this.binding.rejectCall.setVisibility(View.VISIBLE);
|
||||||
this.binding.endCall.setVisibility(View.INVISIBLE);
|
this.binding.endCall.setVisibility(View.INVISIBLE);
|
||||||
this.binding.acceptCall.setContentDescription(getString(R.string.try_again));
|
this.binding.acceptCall.setContentDescription(getString(R.string.try_again));
|
||||||
this.binding.acceptCall.setOnClickListener(this::retry);
|
this.binding.acceptCall.setOnClickListener(this::retry);
|
||||||
this.binding.acceptCall.setImageResource(R.drawable.ic_replay_white_48dp);
|
this.binding.acceptCall.setImageResource(R.drawable.ic_replay_24dp);
|
||||||
this.binding.acceptCall.setVisibility(View.VISIBLE);
|
this.binding.acceptCall.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
this.binding.rejectCall.setVisibility(View.INVISIBLE);
|
this.binding.rejectCall.setVisibility(View.INVISIBLE);
|
||||||
this.binding.endCall.setContentDescription(getString(R.string.hang_up));
|
this.binding.endCall.setContentDescription(getString(R.string.hang_up));
|
||||||
this.binding.endCall.setOnClickListener(this::endCall);
|
this.binding.endCall.setOnClickListener(this::endCall);
|
||||||
this.binding.endCall.setImageResource(R.drawable.ic_call_end_white_48dp);
|
this.binding.endCall.setImageResource(R.drawable.ic_call_end_24dp);
|
||||||
this.binding.endCall.setVisibility(View.VISIBLE);
|
this.binding.endCall.setVisibility(View.VISIBLE);
|
||||||
this.binding.acceptCall.setVisibility(View.INVISIBLE);
|
this.binding.acceptCall.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
@ -1038,7 +1039,7 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
switch (selectedAudioDevice) {
|
switch (selectedAudioDevice) {
|
||||||
case EARPIECE -> {
|
case EARPIECE -> {
|
||||||
this.binding.inCallActionRight.setImageResource(
|
this.binding.inCallActionRight.setImageResource(
|
||||||
R.drawable.ic_volume_off_black_24dp);
|
R.drawable.ic_volume_off_24dp);
|
||||||
if (numberOfChoices >= 2) {
|
if (numberOfChoices >= 2) {
|
||||||
this.binding.inCallActionRight.setOnClickListener(this::switchToSpeaker);
|
this.binding.inCallActionRight.setOnClickListener(this::switchToSpeaker);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1047,12 +1048,12 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case WIRED_HEADSET -> {
|
case WIRED_HEADSET -> {
|
||||||
this.binding.inCallActionRight.setImageResource(R.drawable.ic_headset_black_24dp);
|
this.binding.inCallActionRight.setImageResource(R.drawable.ic_headset_mic_24dp);
|
||||||
this.binding.inCallActionRight.setOnClickListener(null);
|
this.binding.inCallActionRight.setOnClickListener(null);
|
||||||
this.binding.inCallActionRight.setClickable(false);
|
this.binding.inCallActionRight.setClickable(false);
|
||||||
}
|
}
|
||||||
case SPEAKER_PHONE -> {
|
case SPEAKER_PHONE -> {
|
||||||
this.binding.inCallActionRight.setImageResource(R.drawable.ic_volume_up_black_24dp);
|
this.binding.inCallActionRight.setImageResource(R.drawable.ic_volume_up_24dp);
|
||||||
if (numberOfChoices >= 2) {
|
if (numberOfChoices >= 2) {
|
||||||
this.binding.inCallActionRight.setOnClickListener(this::switchToEarpiece);
|
this.binding.inCallActionRight.setOnClickListener(this::switchToEarpiece);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1062,7 +1063,7 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
}
|
}
|
||||||
case BLUETOOTH -> {
|
case BLUETOOTH -> {
|
||||||
this.binding.inCallActionRight.setImageResource(
|
this.binding.inCallActionRight.setImageResource(
|
||||||
R.drawable.ic_bluetooth_audio_black_24dp);
|
R.drawable.ic_bluetooth_audio_24dp);
|
||||||
this.binding.inCallActionRight.setOnClickListener(null);
|
this.binding.inCallActionRight.setOnClickListener(null);
|
||||||
this.binding.inCallActionRight.setClickable(false);
|
this.binding.inCallActionRight.setClickable(false);
|
||||||
}
|
}
|
||||||
|
@ -1076,17 +1077,17 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
this.binding.inCallActionRight.setVisibility(View.VISIBLE);
|
this.binding.inCallActionRight.setVisibility(View.VISIBLE);
|
||||||
if (isCameraSwitchable) {
|
if (isCameraSwitchable) {
|
||||||
this.binding.inCallActionFarRight.setImageResource(
|
this.binding.inCallActionFarRight.setImageResource(
|
||||||
R.drawable.ic_flip_camera_android_black_24dp);
|
R.drawable.ic_flip_camera_android_24dp);
|
||||||
this.binding.inCallActionFarRight.setVisibility(View.VISIBLE);
|
this.binding.inCallActionFarRight.setVisibility(View.VISIBLE);
|
||||||
this.binding.inCallActionFarRight.setOnClickListener(this::switchCamera);
|
this.binding.inCallActionFarRight.setOnClickListener(this::switchCamera);
|
||||||
} else {
|
} else {
|
||||||
this.binding.inCallActionFarRight.setVisibility(View.GONE);
|
this.binding.inCallActionFarRight.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
if (videoEnabled) {
|
if (videoEnabled) {
|
||||||
this.binding.inCallActionRight.setImageResource(R.drawable.ic_videocam_black_24dp);
|
this.binding.inCallActionRight.setImageResource(R.drawable.ic_videocam_24dp);
|
||||||
this.binding.inCallActionRight.setOnClickListener(this::disableVideo);
|
this.binding.inCallActionRight.setOnClickListener(this::disableVideo);
|
||||||
} else {
|
} else {
|
||||||
this.binding.inCallActionRight.setImageResource(R.drawable.ic_videocam_off_black_24dp);
|
this.binding.inCallActionRight.setImageResource(R.drawable.ic_videocam_off_24dp);
|
||||||
this.binding.inCallActionRight.setOnClickListener(this::enableVideo);
|
this.binding.inCallActionRight.setOnClickListener(this::enableVideo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1140,10 +1141,10 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
@SuppressLint("RestrictedApi")
|
@SuppressLint("RestrictedApi")
|
||||||
private void updateInCallButtonConfigurationMicrophone(final boolean microphoneEnabled) {
|
private void updateInCallButtonConfigurationMicrophone(final boolean microphoneEnabled) {
|
||||||
if (microphoneEnabled) {
|
if (microphoneEnabled) {
|
||||||
this.binding.inCallActionLeft.setImageResource(R.drawable.ic_mic_black_24dp);
|
this.binding.inCallActionLeft.setImageResource(R.drawable.ic_mic_24dp);
|
||||||
this.binding.inCallActionLeft.setOnClickListener(this::disableMicrophone);
|
this.binding.inCallActionLeft.setOnClickListener(this::disableMicrophone);
|
||||||
} else {
|
} else {
|
||||||
this.binding.inCallActionLeft.setImageResource(R.drawable.ic_mic_off_black_24dp);
|
this.binding.inCallActionLeft.setImageResource(R.drawable.ic_mic_off_24dp);
|
||||||
this.binding.inCallActionLeft.setOnClickListener(this::enableMicrophone);
|
this.binding.inCallActionLeft.setOnClickListener(this::enableMicrophone);
|
||||||
}
|
}
|
||||||
this.binding.inCallActionLeft.setVisibility(View.VISIBLE);
|
this.binding.inCallActionLeft.setVisibility(View.VISIBLE);
|
||||||
|
|
|
@ -182,7 +182,6 @@ public final class ScanActivity extends Activity implements SurfaceTextureListen
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
SettingsUtils.applyScreenshotPreventionSetting(this);
|
|
||||||
maybeOpenCamera();
|
maybeOpenCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,10 @@ import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
@ -64,7 +66,6 @@ import eu.siacs.conversations.ui.util.DateSeparator;
|
||||||
import eu.siacs.conversations.ui.util.ListViewUtils;
|
import eu.siacs.conversations.ui.util.ListViewUtils;
|
||||||
import eu.siacs.conversations.ui.util.PendingItem;
|
import eu.siacs.conversations.ui.util.PendingItem;
|
||||||
import eu.siacs.conversations.ui.util.ShareUtil;
|
import eu.siacs.conversations.ui.util.ShareUtil;
|
||||||
import eu.siacs.conversations.ui.util.StyledAttributes;
|
|
||||||
import eu.siacs.conversations.utils.FtsUtils;
|
import eu.siacs.conversations.utils.FtsUtils;
|
||||||
import eu.siacs.conversations.utils.MessageUtils;
|
import eu.siacs.conversations.utils.MessageUtils;
|
||||||
|
|
||||||
|
@ -95,6 +96,7 @@ public class SearchActivity extends XmppActivity implements TextWatcher, OnSearc
|
||||||
}
|
}
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_search);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_search);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(this.binding.toolbar);
|
setSupportActionBar(this.binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
this.messageListAdapter = new MessageAdapter(this, this.messages, uuid == null);
|
this.messageListAdapter = new MessageAdapter(this, this.messages, uuid == null);
|
||||||
|
@ -223,12 +225,12 @@ public class SearchActivity extends XmppActivity implements TextWatcher, OnSearc
|
||||||
private void changeBackground(boolean hasSearch, boolean hasResults) {
|
private void changeBackground(boolean hasSearch, boolean hasResults) {
|
||||||
if (hasSearch) {
|
if (hasSearch) {
|
||||||
if (hasResults) {
|
if (hasResults) {
|
||||||
binding.searchResults.setBackgroundColor(StyledAttributes.getColor(this, R.attr.color_background_secondary));
|
binding.searchResults.setBackgroundColor(MaterialColors.getColor(binding.searchResults, com.google.android.material.R.attr.colorSurface));
|
||||||
} else {
|
} else {
|
||||||
binding.searchResults.setBackground(StyledAttributes.getDrawable(this, R.attr.activity_background_no_results));
|
binding.searchResults.setBackgroundResource(R.drawable.background_no_results);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
binding.searchResults.setBackground(StyledAttributes.getDrawable(this, R.attr.activity_background_search));
|
binding.searchResults.setBackgroundResource(R.drawable.background_search);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,14 +250,14 @@ public class SearchActivity extends XmppActivity implements TextWatcher, OnSearc
|
||||||
if (!currentSearch.watch(term)) {
|
if (!currentSearch.watch(term)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (term.size() > 0) {
|
if (term.isEmpty()) {
|
||||||
xmppConnectionService.search(term, uuid,this);
|
|
||||||
} else {
|
|
||||||
MessageSearchTask.cancelRunningTasks();
|
MessageSearchTask.cancelRunningTasks();
|
||||||
this.messages.clear();
|
this.messages.clear();
|
||||||
messageListAdapter.setHighlightedTerm(null);
|
messageListAdapter.setHighlightedTerm(null);
|
||||||
messageListAdapter.notifyDataSetChanged();
|
messageListAdapter.notifyDataSetChanged();
|
||||||
changeBackground(false, false);
|
changeBackground(false, false);
|
||||||
|
} else {
|
||||||
|
xmppConnectionService.search(term, uuid,this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +269,7 @@ public class SearchActivity extends XmppActivity implements TextWatcher, OnSearc
|
||||||
DateSeparator.addAll(messages);
|
DateSeparator.addAll(messages);
|
||||||
this.messages.addAll(messages);
|
this.messages.addAll(messages);
|
||||||
messageListAdapter.notifyDataSetChanged();
|
messageListAdapter.notifyDataSetChanged();
|
||||||
changeBackground(true, messages.size() > 0);
|
changeBackground(true, !messages.isEmpty());
|
||||||
ListViewUtils.scrollToBottom(this.binding.searchResults);
|
ListViewUtils.scrollToBottom(this.binding.searchResults);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,10 @@ import android.widget.Toast;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.color.DynamicColors;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
@ -37,8 +40,10 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
|
import eu.siacs.conversations.Conversations;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.crypto.OmemoSetting;
|
import eu.siacs.conversations.crypto.OmemoSetting;
|
||||||
|
import eu.siacs.conversations.databinding.ActivitySettingsBinding;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.persistance.FileBackend;
|
import eu.siacs.conversations.persistance.FileBackend;
|
||||||
import eu.siacs.conversations.services.ExportBackupService;
|
import eu.siacs.conversations.services.ExportBackupService;
|
||||||
|
@ -46,10 +51,8 @@ import eu.siacs.conversations.services.MemorizingTrustManager;
|
||||||
import eu.siacs.conversations.services.QuickConversationsService;
|
import eu.siacs.conversations.services.QuickConversationsService;
|
||||||
import eu.siacs.conversations.services.UnifiedPushDistributor;
|
import eu.siacs.conversations.services.UnifiedPushDistributor;
|
||||||
import eu.siacs.conversations.ui.util.SettingsUtils;
|
import eu.siacs.conversations.ui.util.SettingsUtils;
|
||||||
import eu.siacs.conversations.ui.util.StyledAttributes;
|
|
||||||
import eu.siacs.conversations.utils.GeoHelper;
|
import eu.siacs.conversations.utils.GeoHelper;
|
||||||
import eu.siacs.conversations.utils.TimeFrameUtils;
|
import eu.siacs.conversations.utils.TimeFrameUtils;
|
||||||
import eu.siacs.conversations.xmpp.InvalidJid;
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
|
||||||
public class SettingsActivity extends XmppActivity implements OnSharedPreferenceChangeListener {
|
public class SettingsActivity extends XmppActivity implements OnSharedPreferenceChangeListener {
|
||||||
|
@ -74,7 +77,7 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_settings);
|
final ActivitySettingsBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_settings);
|
||||||
FragmentManager fm = getFragmentManager();
|
FragmentManager fm = getFragmentManager();
|
||||||
mSettingsFragment = (SettingsFragment) fm.findFragmentById(R.id.settings_content);
|
mSettingsFragment = (SettingsFragment) fm.findFragmentById(R.id.settings_content);
|
||||||
if (mSettingsFragment == null
|
if (mSettingsFragment == null
|
||||||
|
@ -83,13 +86,8 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
|
||||||
fm.beginTransaction().replace(R.id.settings_content, mSettingsFragment).commit();
|
fm.beginTransaction().replace(R.id.settings_content, mSettingsFragment).commit();
|
||||||
}
|
}
|
||||||
mSettingsFragment.setActivityIntent(getIntent());
|
mSettingsFragment.setActivityIntent(getIntent());
|
||||||
this.mTheme = findTheme();
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setTheme(this.mTheme);
|
setSupportActionBar(binding.toolbar);
|
||||||
getWindow()
|
|
||||||
.getDecorView()
|
|
||||||
.setBackgroundColor(
|
|
||||||
StyledAttributes.getColor(this, R.attr.color_background_primary));
|
|
||||||
setSupportActionBar(findViewById(R.id.toolbar));
|
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +183,12 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final PreferenceCategory uiPreferenceCategory = (PreferenceCategory) mSettingsFragment.findPreference("ui");
|
||||||
|
final Preference dynamicColorsPreference = mSettingsFragment.findPreference("dynamic_colors");
|
||||||
|
if (dynamicColorsPreference != null && !DynamicColors.isDynamicColorAvailable()) {
|
||||||
|
uiPreferenceCategory.removePreference(dynamicColorsPreference);
|
||||||
|
}
|
||||||
|
|
||||||
ListPreference automaticMessageDeletionList =
|
ListPreference automaticMessageDeletionList =
|
||||||
(ListPreference) mSettingsFragment.findPreference(AUTOMATIC_MESSAGE_DELETION);
|
(ListPreference) mSettingsFragment.findPreference(AUTOMATIC_MESSAGE_DELETION);
|
||||||
if (automaticMessageDeletionList != null) {
|
if (automaticMessageDeletionList != null) {
|
||||||
|
@ -204,36 +208,6 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
|
||||||
automaticMessageDeletionList.setEntryValues(entryValues);
|
automaticMessageDeletionList.setEntryValues(entryValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean removeLocation =
|
|
||||||
new Intent("eu.siacs.conversations.location.request")
|
|
||||||
.resolveActivity(getPackageManager())
|
|
||||||
== null;
|
|
||||||
boolean removeVoice =
|
|
||||||
new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION)
|
|
||||||
.resolveActivity(getPackageManager())
|
|
||||||
== null;
|
|
||||||
|
|
||||||
ListPreference quickAction =
|
|
||||||
(ListPreference) mSettingsFragment.findPreference("quick_action");
|
|
||||||
if (quickAction != null && (removeLocation || removeVoice)) {
|
|
||||||
ArrayList<CharSequence> entries =
|
|
||||||
new ArrayList<>(Arrays.asList(quickAction.getEntries()));
|
|
||||||
ArrayList<CharSequence> entryValues =
|
|
||||||
new ArrayList<>(Arrays.asList(quickAction.getEntryValues()));
|
|
||||||
int index = entryValues.indexOf("location");
|
|
||||||
if (index > 0 && removeLocation) {
|
|
||||||
entries.remove(index);
|
|
||||||
entryValues.remove(index);
|
|
||||||
}
|
|
||||||
index = entryValues.indexOf("voice");
|
|
||||||
if (index > 0 && removeVoice) {
|
|
||||||
entries.remove(index);
|
|
||||||
entryValues.remove(index);
|
|
||||||
}
|
|
||||||
quickAction.setEntries(entries.toArray(new CharSequence[entries.size()]));
|
|
||||||
quickAction.setEntryValues(entryValues.toArray(new CharSequence[entryValues.size()]));
|
|
||||||
}
|
|
||||||
|
|
||||||
final Preference removeCertsPreference =
|
final Preference removeCertsPreference =
|
||||||
mSettingsFragment.findPreference("remove_trusted_certificates");
|
mSettingsFragment.findPreference("remove_trusted_certificates");
|
||||||
if (removeCertsPreference != null) {
|
if (removeCertsPreference != null) {
|
||||||
|
@ -242,17 +216,16 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
|
||||||
final MemorizingTrustManager mtm =
|
final MemorizingTrustManager mtm =
|
||||||
xmppConnectionService.getMemorizingTrustManager();
|
xmppConnectionService.getMemorizingTrustManager();
|
||||||
final ArrayList<String> aliases = Collections.list(mtm.getCertificates());
|
final ArrayList<String> aliases = Collections.list(mtm.getCertificates());
|
||||||
if (aliases.size() == 0) {
|
if (aliases.isEmpty()) {
|
||||||
displayToast(getString(R.string.toast_no_trusted_certs));
|
displayToast(getString(R.string.toast_no_trusted_certs));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final ArrayList<Integer> selectedItems = new ArrayList<>();
|
final ArrayList<Integer> selectedItems = new ArrayList<>();
|
||||||
final AlertDialog.Builder dialogBuilder =
|
final MaterialAlertDialogBuilder dialogBuilder = new MaterialAlertDialogBuilder(SettingsActivity.this);
|
||||||
new AlertDialog.Builder(SettingsActivity.this);
|
|
||||||
dialogBuilder.setTitle(
|
dialogBuilder.setTitle(
|
||||||
getResources().getString(R.string.dialog_manage_certs_title));
|
getResources().getString(R.string.dialog_manage_certs_title));
|
||||||
dialogBuilder.setMultiChoiceItems(
|
dialogBuilder.setMultiChoiceItems(
|
||||||
aliases.toArray(new CharSequence[aliases.size()]),
|
aliases.toArray(new CharSequence[0]),
|
||||||
null,
|
null,
|
||||||
(dialog, indexSelected, isChecked) -> {
|
(dialog, indexSelected, isChecked) -> {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
|
@ -262,7 +235,7 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
|
||||||
}
|
}
|
||||||
((AlertDialog) dialog)
|
((AlertDialog) dialog)
|
||||||
.getButton(DialogInterface.BUTTON_POSITIVE)
|
.getButton(DialogInterface.BUTTON_POSITIVE)
|
||||||
.setEnabled(selectedItems.size() > 0);
|
.setEnabled(!selectedItems.isEmpty());
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogBuilder.setPositiveButton(
|
dialogBuilder.setPositiveButton(
|
||||||
|
@ -273,13 +246,12 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
try {
|
try {
|
||||||
Integer item =
|
final int item =
|
||||||
Integer.valueOf(
|
Integer.parseInt(
|
||||||
selectedItems.get(i).toString());
|
selectedItems.get(i).toString());
|
||||||
String alias = aliases.get(item);
|
String alias = aliases.get(item);
|
||||||
mtm.deleteCertificate(alias);
|
mtm.deleteCertificate(alias);
|
||||||
} catch (KeyStoreException e) {
|
} catch (final KeyStoreException e) {
|
||||||
e.printStackTrace();
|
|
||||||
displayToast("Error: " + e.getLocalizedMessage());
|
displayToast("Error: " + e.getLocalizedMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,10 +344,8 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
|
||||||
|
|
||||||
private boolean isCallable(final Intent i) {
|
private boolean isCallable(final Intent i) {
|
||||||
return i != null
|
return i != null
|
||||||
&& getPackageManager()
|
&& !getPackageManager()
|
||||||
.queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY)
|
.queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY).isEmpty();
|
||||||
.size()
|
|
||||||
> 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean cleanCache() {
|
private boolean cleanCache() {
|
||||||
|
@ -413,7 +383,7 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean deleteOmemoIdentities() {
|
private boolean deleteOmemoIdentities() {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(R.string.pref_delete_omemo_identities);
|
builder.setTitle(R.string.pref_delete_omemo_identities);
|
||||||
final List<CharSequence> accounts = new ArrayList<>();
|
final List<CharSequence> accounts = new ArrayList<>();
|
||||||
for (Account account : xmppConnectionService.getAccounts()) {
|
for (Account account : xmppConnectionService.getAccounts()) {
|
||||||
|
@ -502,10 +472,12 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
|
||||||
} else if (name.equals(AUTOMATIC_MESSAGE_DELETION)) {
|
} else if (name.equals(AUTOMATIC_MESSAGE_DELETION)) {
|
||||||
xmppConnectionService.expireOldMessages(true);
|
xmppConnectionService.expireOldMessages(true);
|
||||||
} else if (name.equals(THEME)) {
|
} else if (name.equals(THEME)) {
|
||||||
final int theme = findTheme();
|
final var value = preferences.getString(THEME,getString(R.string.theme));
|
||||||
if (this.mTheme != theme) {
|
final int desiredNightMode = Conversations.getDesiredNightMode(value);
|
||||||
recreate();
|
setDesiredNightMode(desiredNightMode);
|
||||||
}
|
} else if (name.equals("dynamic_colors")) {
|
||||||
|
final var value = preferences.getBoolean("dynamic_colors",false);
|
||||||
|
setDynamicColors(value);
|
||||||
} else if (name.equals(PREVENT_SCREENSHOTS)) {
|
} else if (name.equals(PREVENT_SCREENSHOTS)) {
|
||||||
SettingsUtils.applyScreenshotPreventionSetting(this);
|
SettingsUtils.applyScreenshotPreventionSetting(this);
|
||||||
} else if (UnifiedPushDistributor.PREFERENCES.contains(name)) {
|
} else if (UnifiedPushDistributor.PREFERENCES.contains(name)) {
|
||||||
|
@ -572,7 +544,7 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
|
||||||
|
|
||||||
private void createBackup() {
|
private void createBackup() {
|
||||||
ContextCompat.startForegroundService(this, new Intent(this, ExportBackupService.class));
|
ContextCompat.startForegroundService(this, new Intent(this, ExportBackupService.class));
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setMessage(R.string.backup_started_message);
|
builder.setMessage(R.string.backup_started_message);
|
||||||
builder.setPositiveButton(R.string.ok, null);
|
builder.setPositiveButton(R.string.ok, null);
|
||||||
builder.create().show();
|
builder.create().show();
|
||||||
|
|
|
@ -5,7 +5,6 @@ import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.location.LocationListener;
|
import android.location.LocationListener;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
@ -15,11 +14,6 @@ import androidx.databinding.DataBindingUtil;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.google.common.math.DoubleMath;
|
import com.google.common.math.DoubleMath;
|
||||||
|
|
||||||
import org.osmdroid.api.IGeoPoint;
|
|
||||||
import org.osmdroid.util.GeoPoint;
|
|
||||||
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.ActivityShareLocationBinding;
|
import eu.siacs.conversations.databinding.ActivityShareLocationBinding;
|
||||||
|
@ -27,7 +21,11 @@ import eu.siacs.conversations.ui.util.LocationHelper;
|
||||||
import eu.siacs.conversations.ui.widget.Marker;
|
import eu.siacs.conversations.ui.widget.Marker;
|
||||||
import eu.siacs.conversations.ui.widget.MyLocation;
|
import eu.siacs.conversations.ui.widget.MyLocation;
|
||||||
import eu.siacs.conversations.utils.LocationProvider;
|
import eu.siacs.conversations.utils.LocationProvider;
|
||||||
import eu.siacs.conversations.utils.ThemeHelper;
|
|
||||||
|
import org.osmdroid.api.IGeoPoint;
|
||||||
|
import org.osmdroid.util.GeoPoint;
|
||||||
|
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
|
||||||
public class ShareLocationActivity extends LocationActivity implements LocationListener {
|
public class ShareLocationActivity extends LocationActivity implements LocationListener {
|
||||||
|
|
||||||
|
@ -58,6 +56,7 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_share_location);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_share_location);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
setupMapView(binding.map, LocationProvider.getGeoPoint(this));
|
setupMapView(binding.map, LocationProvider.getGeoPoint(this));
|
||||||
|
@ -71,13 +70,12 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
|
||||||
this.snackBar.setAction(R.string.enable, view -> {
|
this.snackBar.setAction(R.string.enable, view -> {
|
||||||
if (isLocationEnabledAndAllowed()) {
|
if (isLocationEnabledAndAllowed()) {
|
||||||
updateUi();
|
updateUi();
|
||||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !hasLocationPermissions()) {
|
} else if (!hasLocationPermissions()) {
|
||||||
requestPermissions(REQUEST_CODE_SNACKBAR_PRESSED);
|
requestPermissions(REQUEST_CODE_SNACKBAR_PRESSED);
|
||||||
} else if (!isLocationEnabled()) {
|
} else if (!isLocationEnabled()) {
|
||||||
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
|
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ThemeHelper.fix(this.snackBar);
|
|
||||||
|
|
||||||
this.binding.shareButton.setOnClickListener(this::shareLocation);
|
this.binding.shareButton.setOnClickListener(this::shareLocation);
|
||||||
|
|
||||||
|
@ -87,7 +85,7 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
|
||||||
if (!marker_fixed_to_loc) {
|
if (!marker_fixed_to_loc) {
|
||||||
if (!isLocationEnabled()) {
|
if (!isLocationEnabled()) {
|
||||||
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
|
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
|
||||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
} else {
|
||||||
requestPermissions(REQUEST_CODE_FAB_PRESSED);
|
requestPermissions(REQUEST_CODE_FAB_PRESSED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,16 +115,9 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
|
||||||
@NonNull final int[] grantResults) {
|
@NonNull final int[] grantResults) {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
|
||||||
if (grantResults.length > 0 &&
|
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED && permissions.length > 0 && (
|
||||||
grantResults[0] != PackageManager.PERMISSION_GRANTED &&
|
Manifest.permission.LOCATION_HARDWARE.equals(permissions[0]) || Manifest.permission.ACCESS_FINE_LOCATION.equals(permissions[0]) || Manifest.permission.ACCESS_COARSE_LOCATION.equals(permissions[0])
|
||||||
Build.VERSION.SDK_INT >= 23 &&
|
) && !shouldShowRequestPermissionRationale(permissions[0])) {
|
||||||
permissions.length > 0 &&
|
|
||||||
(
|
|
||||||
Manifest.permission.LOCATION_HARDWARE.equals(permissions[0]) ||
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION.equals(permissions[0]) ||
|
|
||||||
Manifest.permission.ACCESS_COARSE_LOCATION.equals(permissions[0])
|
|
||||||
) &&
|
|
||||||
!shouldShowRequestPermissionRationale(permissions[0])) {
|
|
||||||
noAskAgain = true;
|
noAskAgain = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +163,7 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLocationChanged(final Location location) {
|
public void onLocationChanged(@NonNull final Location location) {
|
||||||
if (this.myLoc == null) {
|
if (this.myLoc == null) {
|
||||||
this.marker_fixed_to_loc = true;
|
this.marker_fixed_to_loc = true;
|
||||||
}
|
}
|
||||||
|
@ -206,7 +197,7 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isLocationEnabledAndAllowed() {
|
private boolean isLocationEnabledAndAllowed() {
|
||||||
return this.hasLocationFeature && (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || this.hasLocationPermissions()) && this.isLocationEnabled();
|
return this.hasLocationFeature && this.hasLocationPermissions() && this.isLocationEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toggleFixedLocation() {
|
private void toggleFixedLocation() {
|
||||||
|
@ -229,8 +220,8 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
|
||||||
if (isLocationEnabledAndAllowed()) {
|
if (isLocationEnabledAndAllowed()) {
|
||||||
this.binding.fab.setVisibility(View.VISIBLE);
|
this.binding.fab.setVisibility(View.VISIBLE);
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
this.binding.fab.setImageResource(marker_fixed_to_loc ? R.drawable.ic_gps_fixed_white_24dp :
|
this.binding.fab.setImageResource(marker_fixed_to_loc ? R.drawable.ic_gps_fixed_24dp :
|
||||||
R.drawable.ic_gps_not_fixed_white_24dp);
|
R.drawable.ic_gps_not_fixed_24dp);
|
||||||
this.binding.fab.setContentDescription(getResources().getString(
|
this.binding.fab.setContentDescription(getResources().getString(
|
||||||
marker_fixed_to_loc ? R.string.action_unfix_from_location : R.string.action_fix_to_location
|
marker_fixed_to_loc ? R.string.action_unfix_from_location : R.string.action_fix_to_location
|
||||||
));
|
));
|
||||||
|
|
|
@ -9,21 +9,24 @@ import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.databinding.ActivityShareWithBinding;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.ui.adapter.ConversationAdapter;
|
import eu.siacs.conversations.ui.adapter.ConversationAdapter;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
|
||||||
public class ShareWithActivity extends XmppActivity implements XmppConnectionService.OnConversationUpdate {
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ShareWithActivity extends XmppActivity
|
||||||
|
implements XmppConnectionService.OnConversationUpdate {
|
||||||
|
|
||||||
private static final int REQUEST_STORAGE_PERMISSION = 0x733f32;
|
private static final int REQUEST_STORAGE_PERMISSION = 0x733f32;
|
||||||
private Conversation mPendingConversation = null;
|
private Conversation mPendingConversation = null;
|
||||||
|
@ -48,11 +51,10 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
|
||||||
private ConversationAdapter mAdapter;
|
private ConversationAdapter mAdapter;
|
||||||
private final List<Conversation> mConversations = new ArrayList<>();
|
private final List<Conversation> mConversations = new ArrayList<>();
|
||||||
|
|
||||||
|
protected void onActivityResult(
|
||||||
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
|
final int requestCode, final int resultCode, final Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
if (requestCode == REQUEST_START_NEW_CONVERSATION
|
if (requestCode == REQUEST_START_NEW_CONVERSATION && resultCode == RESULT_OK) {
|
||||||
&& resultCode == RESULT_OK) {
|
|
||||||
share.contact = data.getStringExtra("contact");
|
share.contact = data.getStringExtra("contact");
|
||||||
share.account = data.getStringExtra(EXTRA_ACCOUNT);
|
share.account = data.getStringExtra(EXTRA_ACCOUNT);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +67,10 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
public void onRequestPermissionsResult(
|
||||||
|
final int requestCode,
|
||||||
|
@NonNull final String[] permissions,
|
||||||
|
@NonNull final int[] grantResults) {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
if (grantResults.length > 0)
|
if (grantResults.length > 0)
|
||||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
@ -77,27 +82,35 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(this, getString(R.string.no_storage_permission, getString(R.string.app_name)), Toast.LENGTH_SHORT).show();
|
Toast.makeText(
|
||||||
|
this,
|
||||||
|
getString(
|
||||||
|
R.string.no_storage_permission,
|
||||||
|
getString(R.string.app_name)),
|
||||||
|
Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_share_with);
|
|
||||||
|
|
||||||
setSupportActionBar(findViewById(R.id.toolbar));
|
final ActivityShareWithBinding binding =
|
||||||
if (getSupportActionBar() != null) {
|
DataBindingUtil.setContentView(this, R.layout.activity_share_with);
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
setSupportActionBar(binding.toolbar);
|
||||||
getSupportActionBar().setHomeButtonEnabled(false);
|
final var actionBar = getSupportActionBar();
|
||||||
|
if (actionBar != null) {
|
||||||
|
actionBar.setDisplayHomeAsUpEnabled(false);
|
||||||
|
actionBar.setHomeButtonEnabled(false);
|
||||||
}
|
}
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
|
setTitle(R.string.title_activity_share_with);
|
||||||
|
|
||||||
setTitle(getString(R.string.title_activity_sharewith));
|
|
||||||
|
|
||||||
RecyclerView mListView = findViewById(R.id.choose_conversation_list);
|
|
||||||
mAdapter = new ConversationAdapter(this, this.mConversations);
|
mAdapter = new ConversationAdapter(this, this.mConversations);
|
||||||
mListView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
|
binding.chooseConversationList.setLayoutManager(
|
||||||
mListView.setAdapter(mAdapter);
|
new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
|
||||||
|
binding.chooseConversationList.setAdapter(mAdapter);
|
||||||
mAdapter.setConversationClickListener((view, conversation) -> share(conversation));
|
mAdapter.setConversationClickListener((view, conversation) -> share(conversation));
|
||||||
this.share = new Share();
|
this.share = new Share();
|
||||||
}
|
}
|
||||||
|
@ -112,8 +125,9 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
|
||||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_add:
|
case R.id.action_add:
|
||||||
final Intent intent = new Intent(getApplicationContext(), ChooseContactActivity.class);
|
final Intent intent =
|
||||||
intent.putExtra("direct_search",true);
|
new Intent(getApplicationContext(), ChooseContactActivity.class);
|
||||||
|
intent.putExtra("direct_search", true);
|
||||||
startActivityForResult(intent, REQUEST_START_NEW_CONVERSATION);
|
startActivityForResult(intent, REQUEST_START_NEW_CONVERSATION);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +147,8 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
|
||||||
if (Intent.ACTION_SEND.equals(action)) {
|
if (Intent.ACTION_SEND.equals(action)) {
|
||||||
final String text = intent.getStringExtra(Intent.EXTRA_TEXT);
|
final String text = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||||
final Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
final Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||||
final boolean asQuote = intent.getBooleanExtra(ConversationsActivity.EXTRA_AS_QUOTE, false);
|
final boolean asQuote =
|
||||||
|
intent.getBooleanExtra(ConversationsActivity.EXTRA_AS_QUOTE, false);
|
||||||
|
|
||||||
if (data != null && "geo".equals(data.getScheme())) {
|
if (data != null && "geo".equals(data.getScheme())) {
|
||||||
this.share.uris.clear();
|
this.share.uris.clear();
|
||||||
|
@ -151,14 +166,16 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
|
||||||
this.share.uris = uris == null ? new ArrayList<>() : uris;
|
this.share.uris = uris == null ? new ArrayList<>() : uris;
|
||||||
}
|
}
|
||||||
if (xmppConnectionServiceBound) {
|
if (xmppConnectionServiceBound) {
|
||||||
xmppConnectionService.populateWithOrderedConversations(mConversations, this.share.uris.size() == 0, false);
|
xmppConnectionService.populateWithOrderedConversations(
|
||||||
|
mConversations, this.share.uris.isEmpty(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onBackendConnected() {
|
void onBackendConnected() {
|
||||||
if (xmppConnectionServiceBound && share != null && ((share.contact != null && share.account != null))) {
|
if (xmppConnectionServiceBound
|
||||||
|
&& share != null
|
||||||
|
&& ((share.contact != null && share.account != null))) {
|
||||||
share();
|
share();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -167,32 +184,34 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
|
||||||
|
|
||||||
private void share() {
|
private void share() {
|
||||||
final Conversation conversation;
|
final Conversation conversation;
|
||||||
Account account;
|
Account account;
|
||||||
try {
|
try {
|
||||||
account = xmppConnectionService.findAccountByJid(Jid.ofEscaped(share.account));
|
account = xmppConnectionService.findAccountByJid(Jid.ofEscaped(share.account));
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
account = null;
|
account = null;
|
||||||
}
|
}
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
conversation = xmppConnectionService.findOrCreateConversation(account, Jid.of(share.contact), false, true);
|
conversation =
|
||||||
} catch (final IllegalArgumentException e) {
|
xmppConnectionService.findOrCreateConversation(
|
||||||
return;
|
account, Jid.of(share.contact), false, true);
|
||||||
}
|
} catch (final IllegalArgumentException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
share(conversation);
|
share(conversation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void share(final Conversation conversation) {
|
private void share(final Conversation conversation) {
|
||||||
if (share.uris.size() != 0 && !hasStoragePermission(REQUEST_STORAGE_PERMISSION)) {
|
if (!share.uris.isEmpty() && !hasStoragePermission(REQUEST_STORAGE_PERMISSION)) {
|
||||||
mPendingConversation = conversation;
|
mPendingConversation = conversation;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Intent intent = new Intent(this, ConversationsActivity.class);
|
final Intent intent = new Intent(this, ConversationsActivity.class);
|
||||||
intent.putExtra(ConversationsActivity.EXTRA_CONVERSATION, conversation.getUuid());
|
intent.putExtra(ConversationsActivity.EXTRA_CONVERSATION, conversation.getUuid());
|
||||||
if (share.uris.size() > 0) {
|
if (!share.uris.isEmpty()) {
|
||||||
intent.setAction(Intent.ACTION_SEND_MULTIPLE);
|
intent.setAction(Intent.ACTION_SEND_MULTIPLE);
|
||||||
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, share.uris);
|
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, share.uris);
|
||||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
@ -207,15 +226,20 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
|
||||||
try {
|
try {
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
Toast.makeText(this, R.string.sharing_application_not_grant_permission, Toast.LENGTH_SHORT).show();
|
Toast.makeText(
|
||||||
|
this,
|
||||||
|
R.string.sharing_application_not_grant_permission,
|
||||||
|
Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshUiReal() {
|
public void refreshUiReal() {
|
||||||
//TODO inject desired order to not resort on refresh
|
// TODO inject desired order to not resort on refresh
|
||||||
xmppConnectionService.populateWithOrderedConversations(mConversations, this.share != null && this.share.uris.size() == 0, false);
|
xmppConnectionService.populateWithOrderedConversations(
|
||||||
|
mConversations, this.share != null && this.share.uris.isEmpty(), false);
|
||||||
mAdapter.notifyDataSetChanged();
|
mAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class ShortcutActivity extends AbstractSearchableListItemActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
ActionBar bar = getSupportActionBar();
|
ActionBar bar = getSupportActionBar();
|
||||||
if(bar != null){
|
if(bar != null){
|
||||||
|
|
|
@ -49,6 +49,8 @@ public class ShowLocationActivity extends LocationActivity implements LocationLi
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_show_location);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_show_location);
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
|
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
|
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
setupMapView(this.binding.map, this.loc);
|
setupMapView(this.binding.map, this.loc);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import android.app.Dialog;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
@ -55,7 +54,10 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
import androidx.viewpager.widget.PagerAdapter;
|
import androidx.viewpager.widget.PagerAdapter;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.leinardi.android.speeddial.SpeedDialActionItem;
|
import com.leinardi.android.speeddial.SpeedDialActionItem;
|
||||||
import com.leinardi.android.speeddial.SpeedDialView;
|
import com.leinardi.android.speeddial.SpeedDialView;
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
private ListItemAdapter mContactsAdapter;
|
private ListItemAdapter mContactsAdapter;
|
||||||
private final List<ListItem> conferences = new ArrayList<>();
|
private final List<ListItem> conferences = new ArrayList<>();
|
||||||
private ListItemAdapter mConferenceAdapter;
|
private ListItemAdapter mConferenceAdapter;
|
||||||
private final List<String> mActivatedAccounts = new ArrayList<>();
|
private final ArrayList<String> mActivatedAccounts = new ArrayList<>();
|
||||||
private EditText mSearchEditText;
|
private EditText mSearchEditText;
|
||||||
private final AtomicBoolean mRequestedContactsPermission = new AtomicBoolean(false);
|
private final AtomicBoolean mRequestedContactsPermission = new AtomicBoolean(false);
|
||||||
private final AtomicBoolean mOpenedFab = new AtomicBoolean(false);
|
private final AtomicBoolean mOpenedFab = new AtomicBoolean(false);
|
||||||
|
@ -220,19 +222,20 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static void populateAccountSpinner(Context context, List<String> accounts, Spinner spinner) {
|
public static void populateAccountSpinner(final Context context, final List<String> accounts, final AutoCompleteTextView spinner) {
|
||||||
if (accounts.size() > 0) {
|
if (accounts.isEmpty()) {
|
||||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(context, R.layout.simple_list_item, accounts);
|
|
||||||
adapter.setDropDownViewResource(R.layout.simple_list_item);
|
|
||||||
spinner.setAdapter(adapter);
|
|
||||||
spinner.setEnabled(true);
|
|
||||||
} else {
|
|
||||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(context,
|
ArrayAdapter<String> adapter = new ArrayAdapter<>(context,
|
||||||
R.layout.simple_list_item,
|
R.layout.item_autocomplete,
|
||||||
Collections.singletonList(context.getString(R.string.no_accounts)));
|
Collections.singletonList(context.getString(R.string.no_accounts)));
|
||||||
adapter.setDropDownViewResource(R.layout.simple_list_item);
|
adapter.setDropDownViewResource(R.layout.item_autocomplete);
|
||||||
spinner.setAdapter(adapter);
|
spinner.setAdapter(adapter);
|
||||||
spinner.setEnabled(false);
|
spinner.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
final ArrayAdapter<String> adapter = new ArrayAdapter<>(context, R.layout.item_autocomplete, accounts);
|
||||||
|
adapter.setDropDownViewResource(R.layout.item_autocomplete);
|
||||||
|
spinner.setAdapter(adapter);
|
||||||
|
spinner.setEnabled(true);
|
||||||
|
spinner.setText(Iterables.getFirst(accounts,null),false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,6 +276,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_start_conversation);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_start_conversation);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
configureActionBar(getSupportActionBar());
|
configureActionBar(getSupportActionBar());
|
||||||
|
|
||||||
|
@ -363,7 +367,8 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
}
|
}
|
||||||
final SpeedDialActionItem actionItem = new SpeedDialActionItem.Builder(menuItem.getItemId(), menuItem.getIcon())
|
final SpeedDialActionItem actionItem = new SpeedDialActionItem.Builder(menuItem.getItemId(), menuItem.getIcon())
|
||||||
.setLabel(menuItem.getTitle() != null ? menuItem.getTitle().toString() : null)
|
.setLabel(menuItem.getTitle() != null ? menuItem.getTitle().toString() : null)
|
||||||
.setFabImageTintColor(ContextCompat.getColor(this, R.color.white))
|
.setFabImageTintColor(MaterialColors.getColor(speedDialView, com.google.android.material.R.attr.colorOnSurface))
|
||||||
|
.setFabBackgroundColor(MaterialColors.getColor(speedDialView, com.google.android.material.R.attr.colorSurfaceContainerHighest))
|
||||||
.create();
|
.create();
|
||||||
speedDialView.addActionItem(actionItem);
|
speedDialView.addActionItem(actionItem);
|
||||||
}
|
}
|
||||||
|
@ -394,13 +399,8 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
final int theme = findTheme();
|
if (pendingViewIntent.peek() == null) {
|
||||||
if (this.mTheme != theme) {
|
askForContactsPermissions();
|
||||||
recreate();
|
|
||||||
} else {
|
|
||||||
if (pendingViewIntent.peek() == null) {
|
|
||||||
askForContactsPermissions();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mConferenceAdapter.refreshSettings();
|
mConferenceAdapter.refreshSettings();
|
||||||
mContactsAdapter.refreshSettings();
|
mContactsAdapter.refreshSettings();
|
||||||
|
@ -490,7 +490,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
protected void deleteContact() {
|
protected void deleteContact() {
|
||||||
final int position = contact_context_id;
|
final int position = contact_context_id;
|
||||||
final Contact contact = (Contact) contacts.get(position);
|
final Contact contact = (Contact) contacts.get(position);
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
builder.setTitle(R.string.action_delete_contact);
|
builder.setTitle(R.string.action_delete_contact);
|
||||||
builder.setMessage(JidDialog.style(this, R.string.remove_contact_text, contact.getJid().toEscapedString()));
|
builder.setMessage(JidDialog.style(this, R.string.remove_contact_text, contact.getJid().toEscapedString()));
|
||||||
|
@ -506,7 +506,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
final Bookmark bookmark = (Bookmark) conferences.get(position);
|
final Bookmark bookmark = (Bookmark) conferences.get(position);
|
||||||
final var conversation = bookmark.getConversation();
|
final var conversation = bookmark.getConversation();
|
||||||
final boolean hasConversation = conversation != null;
|
final boolean hasConversation = conversation != null;
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
builder.setTitle(R.string.delete_bookmark);
|
builder.setTitle(R.string.delete_bookmark);
|
||||||
if (hasConversation) {
|
if (hasConversation) {
|
||||||
|
@ -611,18 +611,14 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
dialog.show(ft, FRAGMENT_TAG_DIALOG);
|
dialog.show(ft, FRAGMENT_TAG_DIALOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Account getSelectedAccount(Context context, Spinner spinner) {
|
public static Account getSelectedAccount(final Context context, final AutoCompleteTextView spinner) {
|
||||||
if (spinner == null || !spinner.isEnabled()) {
|
if (spinner == null || !spinner.isEnabled()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (context instanceof XmppActivity) {
|
if (context instanceof XmppActivity) {
|
||||||
Jid jid;
|
final Jid jid;
|
||||||
try {
|
try {
|
||||||
if (Config.DOMAIN_LOCK != null) {
|
jid = Jid.ofEscaped(spinner.getText().toString());
|
||||||
jid = Jid.ofEscaped((String) spinner.getSelectedItem(), Config.DOMAIN_LOCK, null);
|
|
||||||
} else {
|
|
||||||
jid = Jid.ofEscaped((String) spinner.getSelectedItem());
|
|
||||||
}
|
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -792,7 +788,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
if (requiresConsent
|
if (requiresConsent
|
||||||
|| shouldShowRequestPermissionRationale(
|
|| shouldShowRequestPermissionRationale(
|
||||||
Manifest.permission.READ_CONTACTS)) {
|
Manifest.permission.READ_CONTACTS)) {
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
final AtomicBoolean requestPermission = new AtomicBoolean(false);
|
final AtomicBoolean requestPermission = new AtomicBoolean(false);
|
||||||
if (QuickConversationsService.isQuicksy()) {
|
if (QuickConversationsService.isQuicksy()) {
|
||||||
builder.setTitle(R.string.quicksy_wants_your_consent);
|
builder.setTitle(R.string.quicksy_wants_your_consent);
|
||||||
|
@ -1007,7 +1003,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayVerificationWarningDialog(final Contact contact, final Invite invite) {
|
private void displayVerificationWarningDialog(final Contact contact, final Invite invite) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(R.string.verify_omemo_keys);
|
builder.setTitle(R.string.verify_omemo_keys);
|
||||||
View view = getLayoutInflater().inflate(R.layout.dialog_verify_fingerprints, null);
|
View view = getLayoutInflater().inflate(R.layout.dialog_verify_fingerprints, null);
|
||||||
final CheckBox isTrustedSource = view.findViewById(R.id.trusted_source);
|
final CheckBox isTrustedSource = view.findViewById(R.id.trusted_source);
|
||||||
|
@ -1104,7 +1100,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateDialogPositiveClick(Spinner spinner, String name) {
|
public void onCreateDialogPositiveClick(AutoCompleteTextView spinner, String name) {
|
||||||
if (!xmppConnectionServiceBound) {
|
if (!xmppConnectionServiceBound) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1122,7 +1118,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onJoinDialogPositiveClick(Dialog dialog, Spinner spinner, TextInputLayout layout, AutoCompleteTextView jid, boolean isBookmarkChecked) {
|
public void onJoinDialogPositiveClick(Dialog dialog, AutoCompleteTextView spinner, TextInputLayout layout, AutoCompleteTextView jid, boolean isBookmarkChecked) {
|
||||||
if (!xmppConnectionServiceBound) {
|
if (!xmppConnectionServiceBound) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,7 @@ import android.widget.Toast;
|
||||||
import androidx.appcompat.app.ActionBar;
|
import androidx.appcompat.app.ActionBar;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
import org.whispersystems.libsignal.IdentityKey;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
|
@ -40,6 +33,14 @@ import eu.siacs.conversations.utils.XmppUri;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
|
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
|
||||||
|
|
||||||
|
import org.whispersystems.libsignal.IdentityKey;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdated {
|
public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdated {
|
||||||
private final Map<String, Boolean> ownKeysToTrust = new HashMap<>();
|
private final Map<String, Boolean> ownKeysToTrust = new HashMap<>();
|
||||||
|
@ -70,12 +71,14 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
|
||||||
protected void onCreate(final Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_trust_keys);
|
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_trust_keys);
|
||||||
|
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||||
this.contactJids = new ArrayList<>();
|
this.contactJids = new ArrayList<>();
|
||||||
for (String jid : getIntent().getStringArrayExtra("contacts")) {
|
final var intent = getIntent();
|
||||||
|
final String[] contacts = intent == null ? null : intent.getStringArrayExtra("contacts");
|
||||||
|
for (final String jid : (contacts == null ? new String[0] : contacts)) {
|
||||||
try {
|
try {
|
||||||
this.contactJids.add(Jid.of(jid));
|
this.contactJids.add(Jid.of(jid));
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (final IllegalArgumentException ignored) {
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +103,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.trust_keys, menu);
|
getMenuInflater().inflate(R.menu.trust_keys, menu);
|
||||||
MenuItem scanQrCode = menu.findItem(R.id.action_scan_qr_code);
|
MenuItem scanQrCode = menu.findItem(R.id.action_scan_qr_code);
|
||||||
scanQrCode.setVisible((ownKeysToTrust.size() > 0 || foreignActuallyHasKeys()) && isCameraFeatureAvailable());
|
scanQrCode.setVisible((!ownKeysToTrust.isEmpty() || foreignActuallyHasKeys()) && isCameraFeatureAvailable());
|
||||||
return super.onCreateOptionsMenu(menu);
|
return super.onCreateOptionsMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +194,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (fingerprints.size() == 0) {
|
if (fingerprints.isEmpty()) {
|
||||||
keysCardBinding.noKeysToAccept.setVisibility(View.VISIBLE);
|
keysCardBinding.noKeysToAccept.setVisibility(View.VISIBLE);
|
||||||
if (hasNoOtherTrustedKeys(jid)) {
|
if (hasNoOtherTrustedKeys(jid)) {
|
||||||
if (!mAccount.getRoster().getContact(jid).mutualPresenceSubscription()) {
|
if (!mAccount.getRoster().getContact(jid).mutualPresenceSubscription()) {
|
||||||
|
@ -254,8 +257,8 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disableEncryptionDialog(View view) {
|
private void disableEncryptionDialog(final View view) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(R.string.disable_encryption);
|
builder.setTitle(R.string.disable_encryption);
|
||||||
builder.setMessage(R.string.disable_encryption_message);
|
builder.setMessage(R.string.disable_encryption_message);
|
||||||
builder.setPositiveButton(R.string.disable_now, (dialog, which) -> {
|
builder.setPositiveButton(R.string.disable_now, (dialog, which) -> {
|
||||||
|
@ -279,7 +282,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
|
||||||
private boolean foreignActuallyHasKeys() {
|
private boolean foreignActuallyHasKeys() {
|
||||||
synchronized (this.foreignKeysToTrust) {
|
synchronized (this.foreignKeysToTrust) {
|
||||||
for (Map.Entry<Jid, Map<String, Boolean>> entry : foreignKeysToTrust.entrySet()) {
|
for (Map.Entry<Jid, Map<String, Boolean>> entry : foreignKeysToTrust.entrySet()) {
|
||||||
if (entry.getValue().size() > 0) {
|
if (!entry.getValue().isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,7 +308,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
|
||||||
foreignKeysToTrust.clear();
|
foreignKeysToTrust.clear();
|
||||||
for (Jid jid : contactJids) {
|
for (Jid jid : contactJids) {
|
||||||
Set<IdentityKey> foreignKeysSet = service.getKeysWithTrust(FingerprintStatus.createActiveUndecided(), jid);
|
Set<IdentityKey> foreignKeysSet = service.getKeysWithTrust(FingerprintStatus.createActiveUndecided(), jid);
|
||||||
if (hasNoOtherTrustedKeys(jid) && ownKeysSet.size() == 0) {
|
if (hasNoOtherTrustedKeys(jid) && ownKeysSet.isEmpty()) {
|
||||||
foreignKeysSet.addAll(service.getKeysWithTrust(FingerprintStatus.createActive(false), jid));
|
foreignKeysSet.addAll(service.getKeysWithTrust(FingerprintStatus.createActive(false), jid));
|
||||||
}
|
}
|
||||||
Map<String, Boolean> foreignFingerprints = new HashMap<>();
|
Map<String, Boolean> foreignFingerprints = new HashMap<>();
|
||||||
|
@ -315,7 +318,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
|
||||||
foreignFingerprints.put(fingerprint, false);
|
foreignFingerprints.put(fingerprint, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (foreignFingerprints.size() > 0 || !acceptedTargets.contains(jid)) {
|
if (!foreignFingerprints.isEmpty() || !acceptedTargets.contains(jid)) {
|
||||||
foreignKeysToTrust.put(jid, foreignFingerprints);
|
foreignKeysToTrust.put(jid, foreignFingerprints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class UriHandlerActivity extends AppCompatActivity {
|
public class UriHandlerActivity extends BaseActivity {
|
||||||
|
|
||||||
public static final String ACTION_SCAN_QR_CODE = "scan_qr_code";
|
public static final String ACTION_SCAN_QR_CODE = "scan_qr_code";
|
||||||
private static final String EXTRA_ALLOW_PROVISIONING = "extra_allow_provisioning";
|
private static final String EXTRA_ALLOW_PROVISIONING = "extra_allow_provisioning";
|
||||||
|
|
|
@ -2,7 +2,6 @@ package eu.siacs.conversations.ui;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
|
@ -17,10 +16,10 @@ import android.content.ServiceConnection;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
@ -50,10 +49,11 @@ import androidx.annotation.BoolRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AlertDialog.Builder;
|
|
||||||
import androidx.appcompat.app.AppCompatDelegate;
|
import androidx.appcompat.app.AppCompatDelegate;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
import eu.siacs.conversations.BuildConfig;
|
import eu.siacs.conversations.BuildConfig;
|
||||||
|
@ -80,7 +80,6 @@ import eu.siacs.conversations.utils.AccountUtils;
|
||||||
import eu.siacs.conversations.utils.Compatibility;
|
import eu.siacs.conversations.utils.Compatibility;
|
||||||
import eu.siacs.conversations.utils.ExceptionHelper;
|
import eu.siacs.conversations.utils.ExceptionHelper;
|
||||||
import eu.siacs.conversations.utils.SignupUtils;
|
import eu.siacs.conversations.utils.SignupUtils;
|
||||||
import eu.siacs.conversations.utils.ThemeHelper;
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
|
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
|
||||||
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
||||||
|
@ -106,7 +105,6 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
|
|
||||||
private boolean isCameraFeatureAvailable = false;
|
private boolean isCameraFeatureAvailable = false;
|
||||||
|
|
||||||
protected int mTheme;
|
|
||||||
protected boolean mUsingEnterKey = false;
|
protected boolean mUsingEnterKey = false;
|
||||||
protected boolean mUseTor = false;
|
protected boolean mUseTor = false;
|
||||||
protected Toast mToast;
|
protected Toast mToast;
|
||||||
|
@ -154,7 +152,6 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public boolean mSkipBackgroundBinding = false;
|
|
||||||
|
|
||||||
public static boolean cancelPotentialWork(Message message, ImageView imageView) {
|
public static boolean cancelPotentialWork(Message message, ImageView imageView) {
|
||||||
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
||||||
|
@ -212,14 +209,10 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
abstract protected void refreshUiReal();
|
abstract protected void refreshUiReal();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
if (!xmppConnectionServiceBound) {
|
if (!xmppConnectionServiceBound) {
|
||||||
if (this.mSkipBackgroundBinding) {
|
connectToBackend();
|
||||||
Log.d(Config.LOGTAG, "skipping background binding");
|
|
||||||
} else {
|
|
||||||
connectToBackend();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.registerListeners();
|
this.registerListeners();
|
||||||
this.onBackendConnected();
|
this.onBackendConnected();
|
||||||
|
@ -255,7 +248,7 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showInstallPgpDialog() {
|
public void showInstallPgpDialog() {
|
||||||
Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(getString(R.string.openkeychain_required));
|
builder.setTitle(getString(R.string.openkeychain_required));
|
||||||
builder.setIconAttribute(android.R.attr.alertDialogIcon);
|
builder.setIconAttribute(android.R.attr.alertDialogIcon);
|
||||||
builder.setMessage(Html.fromHtml(getString(R.string.openkeychain_required_long, getString(R.string.app_name))));
|
builder.setMessage(Html.fromHtml(getString(R.string.openkeychain_required_long, getString(R.string.app_name))));
|
||||||
|
@ -298,7 +291,7 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void deleteAccount(final Account account, final Runnable postDelete) {
|
protected void deleteAccount(final Account account, final Runnable postDelete) {
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
final View dialogView = getLayoutInflater().inflate(R.layout.dialog_delete_account, null);
|
final View dialogView = getLayoutInflater().inflate(R.layout.dialog_delete_account, null);
|
||||||
final CheckBox deleteFromServer =
|
final CheckBox deleteFromServer =
|
||||||
dialogView.findViewById(R.id.delete_from_server);
|
dialogView.findViewById(R.id.delete_from_server);
|
||||||
|
@ -495,28 +488,12 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
ExceptionHelper.init(getApplicationContext());
|
ExceptionHelper.init(getApplicationContext());
|
||||||
EmojiInitializationService.execute(this);
|
EmojiInitializationService.execute(this);
|
||||||
this.isCameraFeatureAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
|
this.isCameraFeatureAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
|
||||||
this.mTheme = findTheme();
|
|
||||||
setTheme(this.mTheme);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isCameraFeatureAvailable() {
|
protected boolean isCameraFeatureAvailable() {
|
||||||
return this.isCameraFeatureAvailable;
|
return this.isCameraFeatureAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDarkTheme() {
|
|
||||||
return ThemeHelper.isDark(mTheme);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getThemeResource(int r_attr_name, int r_drawable_def) {
|
|
||||||
int[] attrs = {r_attr_name};
|
|
||||||
TypedArray ta = this.getTheme().obtainStyledAttributes(attrs);
|
|
||||||
|
|
||||||
int res = ta.getResourceId(0, r_drawable_def);
|
|
||||||
ta.recycle();
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isOptimizingBattery() {
|
protected boolean isOptimizingBattery() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
final PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
final PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
||||||
|
@ -698,21 +675,10 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
protected void choosePgpSignId(final Account account) {
|
||||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
xmppConnectionService.getPgpEngine().chooseKey(account, new UiCallback<>() {
|
||||||
protected void setListItemBackgroundOnView(View view) {
|
|
||||||
int sdk = android.os.Build.VERSION.SDK_INT;
|
|
||||||
if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
|
|
||||||
view.setBackgroundDrawable(getResources().getDrawable(R.drawable.greybackground));
|
|
||||||
} else {
|
|
||||||
view.setBackground(getResources().getDrawable(R.drawable.greybackground));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void choosePgpSignId(Account account) {
|
|
||||||
xmppConnectionService.getPgpEngine().chooseKey(account, new UiCallback<Account>() {
|
|
||||||
@Override
|
@Override
|
||||||
public void success(Account account1) {
|
public void success(final Account a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -733,8 +699,7 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
|
|
||||||
protected void displayErrorDialog(final int errorCode) {
|
protected void displayErrorDialog(final int errorCode) {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
Builder builder = new Builder(XmppActivity.this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(XmppActivity.this);
|
||||||
builder.setIconAttribute(android.R.attr.alertDialogIcon);
|
|
||||||
builder.setTitle(getString(R.string.error));
|
builder.setTitle(getString(R.string.error));
|
||||||
builder.setMessage(errorCode);
|
builder.setMessage(errorCode);
|
||||||
builder.setNeutralButton(R.string.accept, null);
|
builder.setNeutralButton(R.string.accept, null);
|
||||||
|
@ -744,7 +709,7 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void showAddToRosterDialog(final Contact contact) {
|
protected void showAddToRosterDialog(final Contact contact) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(contact.getJid().toString());
|
builder.setTitle(contact.getJid().toString());
|
||||||
builder.setMessage(getString(R.string.not_in_roster));
|
builder.setMessage(getString(R.string.not_in_roster));
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
builder.setNegativeButton(getString(R.string.cancel), null);
|
||||||
|
@ -753,7 +718,7 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showAskForPresenceDialog(final Contact contact) {
|
private void showAskForPresenceDialog(final Contact contact) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setTitle(contact.getJid().toString());
|
builder.setTitle(contact.getJid().toString());
|
||||||
builder.setMessage(R.string.request_presence_updates);
|
builder.setMessage(R.string.request_presence_updates);
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
|
@ -787,8 +752,8 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
final @StringRes int hint,
|
final @StringRes int hint,
|
||||||
boolean password,
|
boolean password,
|
||||||
boolean permitEmpty) {
|
boolean permitEmpty) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
DialogQuickeditBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.dialog_quickedit, null, false);
|
final DialogQuickeditBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.dialog_quickedit, null, false);
|
||||||
if (password) {
|
if (password) {
|
||||||
binding.inputEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
binding.inputEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||||
}
|
}
|
||||||
|
@ -829,7 +794,7 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean hasStoragePermission(int requestCode) {
|
protected boolean hasStoragePermission(int requestCode) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
|
||||||
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
|
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
|
||||||
return false;
|
return false;
|
||||||
|
@ -911,10 +876,6 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
SettingsUtils.applyScreenshotPreventionSetting(this);
|
SettingsUtils.applyScreenshotPreventionSetting(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int findTheme() {
|
|
||||||
return ThemeHelper.find(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
@ -936,14 +897,26 @@ public abstract class XmppActivity extends ActionBarActivity {
|
||||||
if (uri == null || uri.isEmpty()) {
|
if (uri == null || uri.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Point size = new Point();
|
final Point size = new Point();
|
||||||
getWindowManager().getDefaultDisplay().getSize(size);
|
getWindowManager().getDefaultDisplay().getSize(size);
|
||||||
final int width = (size.x < size.y ? size.x : size.y);
|
final int width = Math.min(size.x, size.y);
|
||||||
Bitmap bitmap = BarcodeProvider.create2dBarcodeBitmap(uri, width);
|
final boolean nightMode = (this.getResources().getConfiguration().uiMode
|
||||||
ImageView view = new ImageView(this);
|
& Configuration.UI_MODE_NIGHT_MASK)
|
||||||
view.setBackgroundColor(Color.WHITE);
|
== Configuration.UI_MODE_NIGHT_YES;
|
||||||
|
final int black;
|
||||||
|
final int white;
|
||||||
|
if (nightMode) {
|
||||||
|
black = MaterialColors.getColor(this, com.google.android.material.R.attr.colorSurfaceContainerHighest,"No surface color configured");
|
||||||
|
white = MaterialColors.getColor(this, com.google.android.material.R.attr.colorSurfaceInverse,"No inverse surface color configured");
|
||||||
|
} else {
|
||||||
|
black = MaterialColors.getColor(this, com.google.android.material.R.attr.colorSurfaceInverse,"No inverse surface color configured");
|
||||||
|
white = MaterialColors.getColor(this, com.google.android.material.R.attr.colorSurfaceContainerHighest,"No surface color configured");
|
||||||
|
}
|
||||||
|
final var bitmap = BarcodeProvider.create2dBarcodeBitmap(uri, width, black, white);
|
||||||
|
final ImageView view = new ImageView(this);
|
||||||
|
view.setBackgroundColor(white);
|
||||||
view.setImageBitmap(bitmap);
|
view.setImageBitmap(bitmap);
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setView(view);
|
builder.setView(view);
|
||||||
builder.create().show();
|
builder.create().show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,16 @@ import android.widget.ArrayAdapter;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
import java.util.List;
|
import com.google.android.material.color.MaterialColors;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.AccountRowBinding;
|
import eu.siacs.conversations.databinding.ItemAccountBinding;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.ui.XmppActivity;
|
import eu.siacs.conversations.ui.XmppActivity;
|
||||||
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
||||||
import eu.siacs.conversations.ui.util.StyledAttributes;
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class AccountAdapter extends ArrayAdapter<Account> {
|
public class AccountAdapter extends ArrayAdapter<Account> {
|
||||||
|
|
||||||
|
@ -35,36 +36,33 @@ public class AccountAdapter extends ArrayAdapter<Account> {
|
||||||
this.showStateButton = true;
|
this.showStateButton = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View view, @NonNull ViewGroup parent) {
|
public View getView(int position, View view, @NonNull ViewGroup parent) {
|
||||||
final Account account = getItem(position);
|
final Account account = getItem(position);
|
||||||
final ViewHolder viewHolder;
|
final ViewHolder viewHolder;
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
AccountRowBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.account_row, parent, false);
|
ItemAccountBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.item_account, parent, false);
|
||||||
view = binding.getRoot();
|
view = binding.getRoot();
|
||||||
viewHolder = new ViewHolder(binding);
|
viewHolder = new ViewHolder(binding);
|
||||||
view.setTag(viewHolder);
|
view.setTag(viewHolder);
|
||||||
} else {
|
} else {
|
||||||
viewHolder = (ViewHolder) view.getTag();
|
viewHolder = (ViewHolder) view.getTag();
|
||||||
}
|
}
|
||||||
if (Config.DOMAIN_LOCK != null) {
|
viewHolder.binding.accountJid.setText(account.getJid().asBareJid().toEscapedString());
|
||||||
viewHolder.binding.accountJid.setText(account.getJid().getLocal());
|
|
||||||
} else {
|
|
||||||
viewHolder.binding.accountJid.setText(account.getJid().asBareJid().toEscapedString());
|
|
||||||
}
|
|
||||||
AvatarWorkerTask.loadAvatar(account, viewHolder.binding.accountImage, R.dimen.avatar);
|
AvatarWorkerTask.loadAvatar(account, viewHolder.binding.accountImage, R.dimen.avatar);
|
||||||
viewHolder.binding.accountStatus.setText(getContext().getString(account.getStatus().getReadableId()));
|
viewHolder.binding.accountStatus.setText(getContext().getString(account.getStatus().getReadableId()));
|
||||||
switch (account.getStatus()) {
|
switch (account.getStatus()) {
|
||||||
case ONLINE:
|
case ONLINE:
|
||||||
viewHolder.binding.accountStatus.setTextColor(StyledAttributes.getColor(activity, R.attr.TextColorOnline));
|
viewHolder.binding.accountStatus.setTextColor(MaterialColors.getColor(viewHolder.binding.accountStatus, com.google.android.material.R.attr.colorPrimary));
|
||||||
break;
|
break;
|
||||||
case DISABLED:
|
case DISABLED:
|
||||||
case LOGGED_OUT:
|
case LOGGED_OUT:
|
||||||
case CONNECTING:
|
case CONNECTING:
|
||||||
viewHolder.binding.accountStatus.setTextColor(StyledAttributes.getColor(activity, android.R.attr.textColorSecondary));
|
viewHolder.binding.accountStatus.setTextColor(MaterialColors.getColor(viewHolder.binding.accountStatus, com.google.android.material.R.attr.colorOnSurfaceVariant));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
viewHolder.binding.accountStatus.setTextColor(StyledAttributes.getColor(activity, R.attr.TextColorError));
|
viewHolder.binding.accountStatus.setTextColor(MaterialColors.getColor(viewHolder.binding.accountStatus, com.google.android.material.R.attr.colorError));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
final boolean isDisabled = (account.getStatus() == Account.State.DISABLED);
|
final boolean isDisabled = (account.getStatus() == Account.State.DISABLED);
|
||||||
|
@ -84,9 +82,9 @@ public class AccountAdapter extends ArrayAdapter<Account> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ViewHolder {
|
private static class ViewHolder {
|
||||||
private final AccountRowBinding binding;
|
private final ItemAccountBinding binding;
|
||||||
|
|
||||||
private ViewHolder(AccountRowBinding binding) {
|
private ViewHolder(ItemAccountBinding binding) {
|
||||||
this.binding = binding;
|
this.binding = binding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,18 +13,18 @@ import androidx.recyclerview.widget.DiffUtil;
|
||||||
import androidx.recyclerview.widget.ListAdapter;
|
import androidx.recyclerview.widget.ListAdapter;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.SearchResultItemBinding;
|
import eu.siacs.conversations.databinding.ItemChannelDiscoveryBinding;
|
||||||
import eu.siacs.conversations.entities.Room;
|
import eu.siacs.conversations.entities.Room;
|
||||||
import eu.siacs.conversations.ui.XmppActivity;
|
import eu.siacs.conversations.ui.XmppActivity;
|
||||||
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class ChannelSearchResultAdapter extends ListAdapter<Room, ChannelSearchResultAdapter.ViewHolder> implements View.OnCreateContextMenuListener {
|
public class ChannelSearchResultAdapter extends ListAdapter<Room, ChannelSearchResultAdapter.ViewHolder> implements View.OnCreateContextMenuListener {
|
||||||
|
|
||||||
private static final DiffUtil.ItemCallback<Room> DIFF = new DiffUtil.ItemCallback<Room>() {
|
private static final DiffUtil.ItemCallback<Room> DIFF = new DiffUtil.ItemCallback<>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean areItemsTheSame(@NonNull Room a, @NonNull Room b) {
|
public boolean areItemsTheSame(@NonNull Room a, @NonNull Room b) {
|
||||||
return a.address != null && a.address.equals(b.address);
|
return a.address != null && a.address.equals(b.address);
|
||||||
|
@ -45,7 +45,7 @@ public class ChannelSearchResultAdapter extends ListAdapter<Room, ChannelSearchR
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
|
||||||
return new ViewHolder(DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), R.layout.search_result_item, viewGroup, false));
|
return new ViewHolder(DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), R.layout.item_channel_discovery, viewGroup, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -99,9 +99,9 @@ public class ChannelSearchResultAdapter extends ListAdapter<Room, ChannelSearchR
|
||||||
|
|
||||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
private final SearchResultItemBinding binding;
|
private final ItemChannelDiscoveryBinding binding;
|
||||||
|
|
||||||
private ViewHolder(SearchResultItemBinding binding) {
|
private ViewHolder(final ItemChannelDiscoveryBinding binding) {
|
||||||
super(binding.getRoot());
|
super(binding.getRoot());
|
||||||
this.binding = binding;
|
this.binding = binding;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,30 +6,30 @@ import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.base.Strings;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.ConversationListRowBinding;
|
import eu.siacs.conversations.databinding.ItemConversationBinding;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.Conversational;
|
import eu.siacs.conversations.entities.Conversational;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
import eu.siacs.conversations.ui.ConversationFragment;
|
import eu.siacs.conversations.ui.ConversationFragment;
|
||||||
import eu.siacs.conversations.ui.XmppActivity;
|
import eu.siacs.conversations.ui.XmppActivity;
|
||||||
|
import eu.siacs.conversations.ui.util.Attachment;
|
||||||
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
||||||
import eu.siacs.conversations.ui.util.StyledAttributes;
|
|
||||||
import eu.siacs.conversations.utils.IrregularUnicodeDetector;
|
import eu.siacs.conversations.utils.IrregularUnicodeDetector;
|
||||||
import eu.siacs.conversations.utils.MimeUtils;
|
|
||||||
import eu.siacs.conversations.utils.UIHelper;
|
import eu.siacs.conversations.utils.UIHelper;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession;
|
import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ConversationAdapter
|
public class ConversationAdapter
|
||||||
extends RecyclerView.Adapter<ConversationAdapter.ConversationViewHolder> {
|
extends RecyclerView.Adapter<ConversationAdapter.ConversationViewHolder> {
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ public class ConversationAdapter
|
||||||
return new ConversationViewHolder(
|
return new ConversationViewHolder(
|
||||||
DataBindingUtil.inflate(
|
DataBindingUtil.inflate(
|
||||||
LayoutInflater.from(parent.getContext()),
|
LayoutInflater.from(parent.getContext()),
|
||||||
R.layout.conversation_list_row,
|
R.layout.item_conversation,
|
||||||
parent,
|
parent,
|
||||||
false));
|
false));
|
||||||
}
|
}
|
||||||
|
@ -68,14 +68,13 @@ public class ConversationAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversation == ConversationFragment.getConversation(activity)) {
|
if (conversation == ConversationFragment.getConversation(activity)) {
|
||||||
viewHolder.binding.frame.setBackgroundColor(
|
viewHolder.binding.frame.setBackgroundResource(R.drawable.background_selected_item_conversation);
|
||||||
StyledAttributes.getColor(activity, R.attr.color_background_tertiary));
|
//viewHolder.binding.frame.setBackgroundColor(MaterialColors.getColor(viewHolder.binding.frame, com.google.android.material.R.attr.colorSurfaceDim));
|
||||||
} else {
|
} else {
|
||||||
viewHolder.binding.frame.setBackgroundColor(
|
viewHolder.binding.frame.setBackgroundColor(MaterialColors.getColor(viewHolder.binding.frame, com.google.android.material.R.attr.colorSurface));
|
||||||
StyledAttributes.getColor(activity, R.attr.color_background_primary));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Message message = conversation.getLatestMessage();
|
final Message message = conversation.getLatestMessage();
|
||||||
final int unreadCount = conversation.unreadCount();
|
final int unreadCount = conversation.unreadCount();
|
||||||
final boolean isRead = conversation.isRead();
|
final boolean isRead = conversation.isRead();
|
||||||
final Conversation.Draft draft = isRead ? conversation.getDraft() : null;
|
final Conversation.Draft draft = isRead ? conversation.getDraft() : null;
|
||||||
|
@ -106,68 +105,9 @@ public class ConversationAdapter
|
||||||
&& (message.isFileOrImage()
|
&& (message.isFileOrImage()
|
||||||
|| message.treatAsDownloadable()
|
|| message.treatAsDownloadable()
|
||||||
|| message.isGeoUri())) {
|
|| message.isGeoUri())) {
|
||||||
final int imageResource;
|
final var attachment = Attachment.of(message);
|
||||||
if (message.isGeoUri()) {
|
final @DrawableRes int imageResource = MediaAdapter.getImageDrawable(attachment);
|
||||||
imageResource =
|
showPreviewText = false;
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.ic_attach_location, R.drawable.ic_attach_location);
|
|
||||||
showPreviewText = false;
|
|
||||||
} else {
|
|
||||||
// TODO move this into static MediaPreview method and use same icons as in
|
|
||||||
// MediaAdapter
|
|
||||||
final String mime = message.getMimeType();
|
|
||||||
if (MimeUtils.AMBIGUOUS_CONTAINER_FORMATS.contains(mime)) {
|
|
||||||
final Message.FileParams fileParams = message.getFileParams();
|
|
||||||
if (fileParams.width > 0 && fileParams.height > 0) {
|
|
||||||
imageResource =
|
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.ic_attach_videocam,
|
|
||||||
R.drawable.ic_attach_videocam);
|
|
||||||
showPreviewText = false;
|
|
||||||
} else if (fileParams.runtime > 0) {
|
|
||||||
imageResource =
|
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.ic_attach_record, R.drawable.ic_attach_record);
|
|
||||||
showPreviewText = false;
|
|
||||||
} else {
|
|
||||||
imageResource =
|
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.ic_attach_document,
|
|
||||||
R.drawable.ic_attach_document);
|
|
||||||
showPreviewText = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (Strings.nullToEmpty(mime).split("/")[0]) {
|
|
||||||
case "image":
|
|
||||||
imageResource =
|
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.ic_attach_photo, R.drawable.ic_attach_photo);
|
|
||||||
showPreviewText = false;
|
|
||||||
break;
|
|
||||||
case "video":
|
|
||||||
imageResource =
|
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.ic_attach_videocam,
|
|
||||||
R.drawable.ic_attach_videocam);
|
|
||||||
showPreviewText = false;
|
|
||||||
break;
|
|
||||||
case "audio":
|
|
||||||
imageResource =
|
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.ic_attach_record,
|
|
||||||
R.drawable.ic_attach_record);
|
|
||||||
showPreviewText = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
imageResource =
|
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.ic_attach_document,
|
|
||||||
R.drawable.ic_attach_document);
|
|
||||||
showPreviewText = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
viewHolder.binding.conversationLastmsgImg.setImageResource(imageResource);
|
viewHolder.binding.conversationLastmsgImg.setImageResource(imageResource);
|
||||||
viewHolder.binding.conversationLastmsgImg.setVisibility(View.VISIBLE);
|
viewHolder.binding.conversationLastmsgImg.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -231,36 +171,21 @@ public class ConversationAdapter
|
||||||
|
|
||||||
if (ongoingCall.isPresent()) {
|
if (ongoingCall.isPresent()) {
|
||||||
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
|
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
|
||||||
final int ic_ongoing_call =
|
viewHolder.binding.notificationStatus.setImageResource(R.drawable.ic_phone_in_talk_24dp);
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.ic_ongoing_call_hint, R.drawable.ic_phone_in_talk_black_18dp);
|
|
||||||
viewHolder.binding.notificationStatus.setImageResource(ic_ongoing_call);
|
|
||||||
} else {
|
} else {
|
||||||
final long muted_till =
|
final long muted_till =
|
||||||
conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
|
conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
|
||||||
if (muted_till == Long.MAX_VALUE) {
|
if (muted_till == Long.MAX_VALUE) {
|
||||||
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
|
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
|
||||||
int ic_notifications_off =
|
viewHolder.binding.notificationStatus.setImageResource(R.drawable.ic_notifications_off_24dp);
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.icon_notifications_off,
|
|
||||||
R.drawable.ic_notifications_off_black_24dp);
|
|
||||||
viewHolder.binding.notificationStatus.setImageResource(ic_notifications_off);
|
|
||||||
} else if (muted_till >= System.currentTimeMillis()) {
|
} else if (muted_till >= System.currentTimeMillis()) {
|
||||||
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
|
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
|
||||||
int ic_notifications_paused =
|
viewHolder.binding.notificationStatus.setImageResource(R.drawable.ic_notifications_paused_24dp);
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.icon_notifications_paused,
|
|
||||||
R.drawable.ic_notifications_paused_black_24dp);
|
|
||||||
viewHolder.binding.notificationStatus.setImageResource(ic_notifications_paused);
|
|
||||||
} else if (conversation.alwaysNotify()) {
|
} else if (conversation.alwaysNotify()) {
|
||||||
viewHolder.binding.notificationStatus.setVisibility(View.GONE);
|
viewHolder.binding.notificationStatus.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
|
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
|
||||||
int ic_notifications_none =
|
viewHolder.binding.notificationStatus.setImageResource(R.drawable.ic_notifications_none_24dp);
|
||||||
activity.getThemeResource(
|
|
||||||
R.attr.icon_notifications_none,
|
|
||||||
R.drawable.ic_notifications_none_black_24dp);
|
|
||||||
viewHolder.binding.notificationStatus.setImageResource(ic_notifications_none);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,9 +232,9 @@ public class ConversationAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ConversationViewHolder extends RecyclerView.ViewHolder {
|
static class ConversationViewHolder extends RecyclerView.ViewHolder {
|
||||||
private final ConversationListRowBinding binding;
|
private final ItemConversationBinding binding;
|
||||||
|
|
||||||
private ConversationViewHolder(ConversationListRowBinding binding) {
|
private ConversationViewHolder(final ItemConversationBinding binding) {
|
||||||
super(binding.getRoot());
|
super(binding.getRoot());
|
||||||
this.binding = binding;
|
this.binding = binding;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,32 +6,35 @@ import android.widget.Filter;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.util.Collection;
|
import com.google.common.collect.Ordering;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class KnownHostsAdapter extends ArrayAdapter<String> {
|
public class KnownHostsAdapter extends ArrayAdapter<String> {
|
||||||
|
|
||||||
private static final Pattern E164_PATTERN = Pattern.compile("^\\+[1-9]\\d{1,14}$");
|
private static final Pattern E164_PATTERN = Pattern.compile("^\\+[1-9]\\d{1,14}$");
|
||||||
|
|
||||||
private ArrayList<String> domains;
|
private List<String> domains;
|
||||||
private final Filter domainFilter = new Filter() {
|
private final Filter domainFilter = new Filter() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FilterResults performFiltering(CharSequence constraint) {
|
protected FilterResults performFiltering(final CharSequence constraint) {
|
||||||
final ArrayList<String> suggestions = new ArrayList<>();
|
final ImmutableList.Builder<String> builder = new ImmutableList.Builder<>();
|
||||||
final String[] split = constraint == null ? new String[0] : constraint.toString().split("@");
|
final String[] split = constraint == null ? new String[0] : constraint.toString().split("@");
|
||||||
if (split.length == 1) {
|
if (split.length == 1) {
|
||||||
final String local = split[0].toLowerCase(Locale.ENGLISH);
|
final String local = split[0].toLowerCase(Locale.ENGLISH);
|
||||||
if (Config.QUICKSY_DOMAIN != null && E164_PATTERN.matcher(local).matches()) {
|
if (Config.QUICKSY_DOMAIN != null && E164_PATTERN.matcher(local).matches()) {
|
||||||
suggestions.add(local + '@' + Config.QUICKSY_DOMAIN.toEscapedString());
|
builder.add(local + '@' + Config.QUICKSY_DOMAIN.toEscapedString());
|
||||||
} else {
|
} else {
|
||||||
for (String domain : domains) {
|
for (String domain : domains) {
|
||||||
suggestions.add(local + '@' + domain);
|
builder.add(local + '@' + domain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (split.length == 2) {
|
} else if (split.length == 2) {
|
||||||
|
@ -40,45 +43,49 @@ public class KnownHostsAdapter extends ArrayAdapter<String> {
|
||||||
if (domains.contains(domainPart)) {
|
if (domains.contains(domainPart)) {
|
||||||
return new FilterResults();
|
return new FilterResults();
|
||||||
}
|
}
|
||||||
for (String domain : domains) {
|
for (final String domain : domains) {
|
||||||
if (domain.contains(domainPart)) {
|
if (domain.contains(domainPart)) {
|
||||||
suggestions.add(localPart + "@" + domain);
|
builder.add(localPart + "@" + domain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return new FilterResults();
|
return new FilterResults();
|
||||||
}
|
}
|
||||||
FilterResults filterResults = new FilterResults();
|
final var suggestions = builder.build();
|
||||||
|
final FilterResults filterResults = new FilterResults();
|
||||||
filterResults.values = suggestions;
|
filterResults.values = suggestions;
|
||||||
filterResults.count = suggestions.size();
|
filterResults.count = suggestions.size();
|
||||||
return filterResults;
|
return filterResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
protected void publishResults(final CharSequence constraint, final FilterResults results) {
|
||||||
ArrayList filteredList = (ArrayList) results.values;
|
final ImmutableList.Builder<String> suggestions = new ImmutableList.Builder<>();
|
||||||
if (results.count > 0) {
|
if (results.values instanceof Collection<?> collection) {
|
||||||
clear();
|
for(final Object item : collection) {
|
||||||
addAll(filteredList);
|
if (item instanceof String string) {
|
||||||
notifyDataSetChanged();
|
suggestions.add(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
clear();
|
||||||
|
addAll(suggestions.build());
|
||||||
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public KnownHostsAdapter(Context context, int viewResourceId, Collection<String> mKnownHosts) {
|
public KnownHostsAdapter(final Context context, final int viewResourceId, final Collection<String> knownHosts) {
|
||||||
super(context, viewResourceId, new ArrayList<>());
|
super(context, viewResourceId, new ArrayList<>());
|
||||||
domains = new ArrayList<>(mKnownHosts);
|
domains = Ordering.natural().sortedCopy(knownHosts);
|
||||||
Collections.sort(domains);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public KnownHostsAdapter(Context context, int viewResourceId) {
|
public KnownHostsAdapter(final Context context, final int viewResourceId) {
|
||||||
super(context, viewResourceId, new ArrayList<>());
|
super(context, viewResourceId, new ArrayList<>());
|
||||||
domains = new ArrayList<>();
|
domains = ImmutableList.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refresh(Collection<String> knownHosts) {
|
public void refresh(final Collection<String> knownHosts) {
|
||||||
domains = new ArrayList<>(knownHosts);
|
this.domains = Ordering.natural().sortedCopy(knownHosts);
|
||||||
Collections.sort(domains);
|
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package eu.siacs.conversations.ui.adapter;
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -9,30 +10,30 @@ import android.widget.ArrayAdapter;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
import com.wefika.flowlayout.FlowLayout;
|
import com.wefika.flowlayout.FlowLayout;
|
||||||
|
|
||||||
import java.util.List;
|
import eu.siacs.conversations.Config;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.ContactBinding;
|
import eu.siacs.conversations.databinding.ItemContactBinding;
|
||||||
import eu.siacs.conversations.entities.ListItem;
|
import eu.siacs.conversations.entities.ListItem;
|
||||||
import eu.siacs.conversations.ui.SettingsActivity;
|
import eu.siacs.conversations.ui.SettingsActivity;
|
||||||
import eu.siacs.conversations.ui.XmppActivity;
|
import eu.siacs.conversations.ui.XmppActivity;
|
||||||
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
||||||
import eu.siacs.conversations.ui.util.StyledAttributes;
|
|
||||||
import eu.siacs.conversations.utils.IrregularUnicodeDetector;
|
import eu.siacs.conversations.utils.IrregularUnicodeDetector;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ListItemAdapter extends ArrayAdapter<ListItem> {
|
public class ListItemAdapter extends ArrayAdapter<ListItem> {
|
||||||
|
|
||||||
protected XmppActivity activity;
|
protected XmppActivity activity;
|
||||||
private boolean showDynamicTags = false;
|
private boolean showDynamicTags = false;
|
||||||
private OnTagClickedListener mOnTagClickedListener = null;
|
private OnTagClickedListener mOnTagClickedListener = null;
|
||||||
private final View.OnClickListener onTagTvClick = view -> {
|
private final View.OnClickListener onTagTvClick = view -> {
|
||||||
if (view instanceof TextView && mOnTagClickedListener != null) {
|
if (view instanceof TextView tv && mOnTagClickedListener != null) {
|
||||||
TextView tv = (TextView) view;
|
|
||||||
final String tag = tv.getText().toString();
|
final String tag = tv.getText().toString();
|
||||||
mOnTagClickedListener.onTagClicked(tag);
|
mOnTagClickedListener.onTagClicked(tag);
|
||||||
}
|
}
|
||||||
|
@ -49,22 +50,25 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
|
||||||
this.showDynamicTags = preferences.getBoolean(SettingsActivity.SHOW_DYNAMIC_TAGS, false);
|
this.showDynamicTags = preferences.getBoolean(SettingsActivity.SHOW_DYNAMIC_TAGS, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View view, ViewGroup parent) {
|
public View getView(int position, View view, @NonNull ViewGroup parent) {
|
||||||
LayoutInflater inflater = activity.getLayoutInflater();
|
LayoutInflater inflater = activity.getLayoutInflater();
|
||||||
ListItem item = getItem(position);
|
ListItem item = getItem(position);
|
||||||
ViewHolder viewHolder;
|
ViewHolder viewHolder;
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
ContactBinding binding = DataBindingUtil.inflate(inflater,R.layout.contact,parent,false);
|
final ItemContactBinding binding = DataBindingUtil.inflate(inflater,R.layout.item_contact,parent,false);
|
||||||
viewHolder = ViewHolder.get(binding);
|
viewHolder = ViewHolder.get(binding);
|
||||||
view = binding.getRoot();
|
view = binding.getRoot();
|
||||||
} else {
|
} else {
|
||||||
viewHolder = (ViewHolder) view.getTag();
|
viewHolder = (ViewHolder) view.getTag();
|
||||||
}
|
}
|
||||||
view.setBackground(StyledAttributes.getDrawable(view.getContext(),R.attr.list_item_background));
|
if (view.isActivated()) {
|
||||||
|
Log.d(Config.LOGTAG,"item "+item.getDisplayName()+" is activated");
|
||||||
List<ListItem.Tag> tags = item.getTags(activity);
|
}
|
||||||
if (tags.size() == 0 || !this.showDynamicTags) {
|
//view.setBackground(StyledAttributes.getDrawable(view.getContext(),R.attr.list_item_background));
|
||||||
|
final List<ListItem.Tag> tags = item.getTags(activity);
|
||||||
|
if (tags.isEmpty() || !this.showDynamicTags) {
|
||||||
viewHolder.tags.setVisibility(View.GONE);
|
viewHolder.tags.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
viewHolder.tags.setVisibility(View.VISIBLE);
|
viewHolder.tags.setVisibility(View.VISIBLE);
|
||||||
|
@ -108,7 +112,7 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ViewHolder get(ContactBinding binding) {
|
public static ViewHolder get(final ItemContactBinding binding) {
|
||||||
ViewHolder viewHolder = new ViewHolder();
|
ViewHolder viewHolder = new ViewHolder();
|
||||||
viewHolder.name = binding.contactDisplayName;
|
viewHolder.name = binding.contactDisplayName;
|
||||||
viewHolder.jid = binding.contactJid;
|
viewHolder.jid = binding.contactJid;
|
||||||
|
|
|
@ -1,47 +1,50 @@
|
||||||
package eu.siacs.conversations.ui.adapter;
|
package eu.siacs.conversations.ui.adapter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.res.ColorStateList;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import androidx.annotation.AttrRes;
|
|
||||||
import androidx.annotation.DimenRes;
|
import androidx.annotation.DimenRes;
|
||||||
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.widget.ImageViewCompat;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.databinding.ItemMediaBinding;
|
||||||
|
import eu.siacs.conversations.services.ExportBackupService;
|
||||||
|
import eu.siacs.conversations.ui.XmppActivity;
|
||||||
|
import eu.siacs.conversations.ui.util.Attachment;
|
||||||
|
import eu.siacs.conversations.ui.util.ViewUtil;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
|
||||||
import eu.siacs.conversations.R;
|
|
||||||
import eu.siacs.conversations.databinding.MediaBinding;
|
|
||||||
import eu.siacs.conversations.services.ExportBackupService;
|
|
||||||
import eu.siacs.conversations.ui.XmppActivity;
|
|
||||||
import eu.siacs.conversations.ui.util.Attachment;
|
|
||||||
import eu.siacs.conversations.ui.util.StyledAttributes;
|
|
||||||
import eu.siacs.conversations.ui.util.ViewUtil;
|
|
||||||
|
|
||||||
public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHolder> {
|
public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHolder> {
|
||||||
|
|
||||||
public static final List<String> DOCUMENT_MIMES = Arrays.asList(
|
public static final List<String> DOCUMENT_MIMES =
|
||||||
"application/pdf",
|
Arrays.asList(
|
||||||
"application/vnd.oasis.opendocument.text",
|
"application/pdf",
|
||||||
"application/msword",
|
"application/vnd.oasis.opendocument.text",
|
||||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
"application/msword",
|
||||||
"text/x-tex",
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
"text/plain"
|
"text/x-tex",
|
||||||
);
|
"text/plain");
|
||||||
|
public static final List<String> CODE_MIMES = Arrays.asList("text/html", "text/xml");
|
||||||
|
|
||||||
private final ArrayList<Attachment> attachments = new ArrayList<>();
|
private final ArrayList<Attachment> attachments = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -55,58 +58,77 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
public static void setMediaSize(RecyclerView recyclerView, int mediaSize) {
|
public static void setMediaSize(final RecyclerView recyclerView, int mediaSize) {
|
||||||
final RecyclerView.Adapter adapter = recyclerView.getAdapter();
|
final RecyclerView.Adapter adapter = recyclerView.getAdapter();
|
||||||
if (adapter instanceof MediaAdapter) {
|
if (adapter instanceof MediaAdapter mediaAdapter) {
|
||||||
((MediaAdapter) adapter).setMediaSize(mediaSize);
|
mediaAdapter.setMediaSize(mediaSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @AttrRes
|
public static @DrawableRes int getImageDrawable(final Attachment attachment) {
|
||||||
int getImageAttr(Attachment attachment) {
|
|
||||||
final @AttrRes int attr;
|
|
||||||
if (attachment.getType() == Attachment.Type.LOCATION) {
|
if (attachment.getType() == Attachment.Type.LOCATION) {
|
||||||
attr = R.attr.media_preview_location;
|
return R.drawable.ic_location_pin_48dp;
|
||||||
} else if (attachment.getType() == Attachment.Type.RECORDING) {
|
} else if (attachment.getType() == Attachment.Type.RECORDING) {
|
||||||
attr = R.attr.media_preview_recording;
|
return R.drawable.ic_mic_48dp;
|
||||||
} else {
|
} else {
|
||||||
final String mime = attachment.getMime();
|
return getImageDrawable(attachment.getMime());
|
||||||
Log.d(Config.LOGTAG, "mime=" + mime);
|
|
||||||
if (mime == null) {
|
|
||||||
attr = R.attr.media_preview_unknown;
|
|
||||||
} else if (mime.equals("audio/x-m4b")) {
|
|
||||||
attr = R.attr.media_preview_audiobook;
|
|
||||||
} else if (mime.startsWith("audio/")) {
|
|
||||||
attr = R.attr.media_preview_audio;
|
|
||||||
} else if (mime.equals("text/calendar") || (mime.equals("text/x-vcalendar"))) {
|
|
||||||
attr = R.attr.media_preview_calendar;
|
|
||||||
} else if (mime.equals("text/x-vcard")) {
|
|
||||||
attr = R.attr.media_preview_contact;
|
|
||||||
} else if (mime.equals("application/vnd.android.package-archive")) {
|
|
||||||
attr = R.attr.media_preview_app;
|
|
||||||
} else if (mime.equals("application/zip") || mime.equals("application/rar")) {
|
|
||||||
attr = R.attr.media_preview_archive;
|
|
||||||
} else if (mime.equals("application/epub+zip") || mime.equals("application/vnd.amazon.mobi8-ebook")) {
|
|
||||||
attr = R.attr.media_preview_ebook;
|
|
||||||
} else if (mime.equals(ExportBackupService.MIME_TYPE)) {
|
|
||||||
attr = R.attr.media_preview_backup;
|
|
||||||
} else if (DOCUMENT_MIMES.contains(mime)) {
|
|
||||||
attr = R.attr.media_preview_document;
|
|
||||||
} else if (mime.equals("application/gpx+xml")) {
|
|
||||||
attr = R.attr.media_preview_tour;
|
|
||||||
} else if (mime.startsWith("image/")) {
|
|
||||||
attr = R.attr.media_preview_image;
|
|
||||||
} else {
|
|
||||||
attr = R.attr.media_preview_unknown;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return attr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void renderPreview(Context context, Attachment attachment, ImageView imageView) {
|
private static @DrawableRes int getImageDrawable(final String mime) {
|
||||||
imageView.setBackgroundColor(StyledAttributes.getColor(context, R.attr.color_background_tertiary));
|
|
||||||
imageView.setImageAlpha(Math.round(StyledAttributes.getFloat(context, R.attr.icon_alpha) * 255));
|
// TODO ideas for more mime types: XML, HTML documents, GPG/PGP files, eml files,
|
||||||
imageView.setImageDrawable(StyledAttributes.getDrawable(context, getImageAttr(attachment)));
|
// spreadsheets (table symbol)
|
||||||
|
|
||||||
|
// add bz2 and tar.gz to archive detection
|
||||||
|
|
||||||
|
if (Strings.isNullOrEmpty(mime)) {
|
||||||
|
return R.drawable.ic_help_center_48dp;
|
||||||
|
} else if (mime.equals("audio/x-m4b")) {
|
||||||
|
return R.drawable.ic_play_lesson_48dp;
|
||||||
|
} else if (mime.startsWith("audio/")) {
|
||||||
|
return R.drawable.ic_headphones_48dp;
|
||||||
|
} else if (mime.equals("text/calendar") || (mime.equals("text/x-vcalendar"))) {
|
||||||
|
return R.drawable.ic_event_48dp;
|
||||||
|
} else if (mime.equals("text/x-vcard")) {
|
||||||
|
return R.drawable.ic_person_48dp;
|
||||||
|
} else if (mime.equals("application/vnd.android.package-archive")) {
|
||||||
|
return R.drawable.ic_adb_48dp;
|
||||||
|
} else if (mime.equals("application/zip") || mime.equals("application/rar")) {
|
||||||
|
return R.drawable.ic_archive_48dp;
|
||||||
|
} else if (mime.equals("application/epub+zip")
|
||||||
|
|| mime.equals("application/vnd.amazon.mobi8-ebook")) {
|
||||||
|
return R.drawable.ic_book_48dp;
|
||||||
|
} else if (mime.equals(ExportBackupService.MIME_TYPE)) {
|
||||||
|
return R.drawable.ic_backup_48dp;
|
||||||
|
} else if (DOCUMENT_MIMES.contains(mime)) {
|
||||||
|
return R.drawable.ic_description_48dp;
|
||||||
|
} else if (mime.equals("application/gpx+xml")) {
|
||||||
|
return R.drawable.ic_tour_48dp;
|
||||||
|
} else if (mime.startsWith("image/")) {
|
||||||
|
return R.drawable.ic_image_48dp;
|
||||||
|
} else if (mime.startsWith("video/")) {
|
||||||
|
return R.drawable.ic_movie_48dp;
|
||||||
|
} else if (CODE_MIMES.contains(mime)) {
|
||||||
|
return R.drawable.ic_code_48dp;
|
||||||
|
} else if (mime.equals("message/rfc822")) {
|
||||||
|
return R.drawable.ic_email_48dp;
|
||||||
|
} else {
|
||||||
|
return R.drawable.ic_help_center_48dp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void renderPreview(final Attachment attachment, final ImageView imageView) {
|
||||||
|
ImageViewCompat.setImageTintList(
|
||||||
|
imageView,
|
||||||
|
ColorStateList.valueOf(
|
||||||
|
MaterialColors.getColor(
|
||||||
|
imageView, com.google.android.material.R.attr.colorOnSurface)));
|
||||||
|
imageView.setImageResource(getImageDrawable(attachment));
|
||||||
|
imageView.setBackgroundColor(
|
||||||
|
MaterialColors.getColor(
|
||||||
|
imageView,
|
||||||
|
com.google.android.material.R.attr.colorSurfaceContainerHighest));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean cancelPotentialWork(Attachment attachment, ImageView imageView) {
|
private static boolean cancelPotentialWork(Attachment attachment, ImageView imageView) {
|
||||||
|
@ -126,8 +148,7 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
|
||||||
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
|
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
|
||||||
if (imageView != null) {
|
if (imageView != null) {
|
||||||
final Drawable drawable = imageView.getDrawable();
|
final Drawable drawable = imageView.getDrawable();
|
||||||
if (drawable instanceof AsyncDrawable) {
|
if (drawable instanceof AsyncDrawable asyncDrawable) {
|
||||||
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
|
|
||||||
return asyncDrawable.getBitmapWorkerTask();
|
return asyncDrawable.getBitmapWorkerTask();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,8 +158,9 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public MediaViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
public MediaViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
|
final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
|
||||||
MediaBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.media, parent, false);
|
ItemMediaBinding binding =
|
||||||
|
DataBindingUtil.inflate(layoutInflater, R.layout.item_media, parent, false);
|
||||||
return new MediaViewHolder(binding);
|
return new MediaViewHolder(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,16 +168,15 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
|
||||||
public void onBindViewHolder(@NonNull MediaViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull MediaViewHolder holder, int position) {
|
||||||
final Attachment attachment = attachments.get(position);
|
final Attachment attachment = attachments.get(position);
|
||||||
if (attachment.renderThumbnail()) {
|
if (attachment.renderThumbnail()) {
|
||||||
holder.binding.media.setImageAlpha(255);
|
|
||||||
loadPreview(attachment, holder.binding.media);
|
loadPreview(attachment, holder.binding.media);
|
||||||
} else {
|
} else {
|
||||||
cancelPotentialWork(attachment, holder.binding.media);
|
cancelPotentialWork(attachment, holder.binding.media);
|
||||||
renderPreview(activity, attachment, holder.binding.media);
|
renderPreview(attachment, holder.binding.media);
|
||||||
}
|
}
|
||||||
holder.binding.getRoot().setOnClickListener(v -> ViewUtil.view(activity, attachment));
|
holder.binding.getRoot().setOnClickListener(v -> ViewUtil.view(activity, attachment));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAttachments(List<Attachment> attachments) {
|
public void setAttachments(final List<Attachment> attachments) {
|
||||||
this.attachments.clear();
|
this.attachments.clear();
|
||||||
this.attachments.addAll(attachments);
|
this.attachments.addAll(attachments);
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
|
@ -167,16 +188,21 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
|
||||||
|
|
||||||
private void loadPreview(Attachment attachment, ImageView imageView) {
|
private void loadPreview(Attachment attachment, ImageView imageView) {
|
||||||
if (cancelPotentialWork(attachment, imageView)) {
|
if (cancelPotentialWork(attachment, imageView)) {
|
||||||
final Bitmap bm = activity.xmppConnectionService.getFileBackend().getPreviewForUri(attachment, mediaSize, true);
|
final Bitmap bm =
|
||||||
|
activity.xmppConnectionService
|
||||||
|
.getFileBackend()
|
||||||
|
.getPreviewForUri(attachment, mediaSize, true);
|
||||||
if (bm != null) {
|
if (bm != null) {
|
||||||
cancelPotentialWork(attachment, imageView);
|
cancelPotentialWork(attachment, imageView);
|
||||||
imageView.setImageBitmap(bm);
|
imageView.setImageBitmap(bm);
|
||||||
imageView.setBackgroundColor(0x00000000);
|
imageView.setBackgroundColor(Color.TRANSPARENT);
|
||||||
} else {
|
} else {
|
||||||
|
// TODO consider if this is still a good, general purpose loading color
|
||||||
imageView.setBackgroundColor(0xff333333);
|
imageView.setBackgroundColor(0xff333333);
|
||||||
imageView.setImageDrawable(null);
|
imageView.setImageDrawable(null);
|
||||||
final BitmapWorkerTask task = new BitmapWorkerTask(mediaSize, imageView);
|
final BitmapWorkerTask task = new BitmapWorkerTask(mediaSize, imageView);
|
||||||
final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
|
final AsyncDrawable asyncDrawable =
|
||||||
|
new AsyncDrawable(activity.getResources(), null, task);
|
||||||
imageView.setImageDrawable(asyncDrawable);
|
imageView.setImageDrawable(asyncDrawable);
|
||||||
try {
|
try {
|
||||||
task.execute(attachment);
|
task.execute(attachment);
|
||||||
|
@ -204,11 +230,11 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MediaViewHolder extends RecyclerView.ViewHolder {
|
static class MediaViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
private final MediaBinding binding;
|
private final ItemMediaBinding binding;
|
||||||
|
|
||||||
MediaViewHolder(MediaBinding binding) {
|
MediaViewHolder(ItemMediaBinding binding) {
|
||||||
super(binding.getRoot());
|
super(binding.getRoot());
|
||||||
this.binding = binding;
|
this.binding = binding;
|
||||||
}
|
}
|
||||||
|
@ -225,13 +251,15 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Bitmap doInBackground(Attachment... params) {
|
protected Bitmap doInBackground(final Attachment... params) {
|
||||||
this.attachment = params[0];
|
this.attachment = params[0];
|
||||||
final XmppActivity activity = XmppActivity.find(imageViewReference);
|
final XmppActivity activity = XmppActivity.find(imageViewReference);
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return activity.xmppConnectionService.getFileBackend().getPreviewForUri(this.attachment, mediaSize, false);
|
return activity.xmppConnectionService
|
||||||
|
.getFileBackend()
|
||||||
|
.getPreviewForUri(this.attachment, mediaSize, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,22 +15,25 @@ import android.widget.ImageView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.core.widget.ImageViewCompat;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.databinding.ItemMediaPreviewBinding;
|
||||||
|
import eu.siacs.conversations.persistance.FileBackend;
|
||||||
|
import eu.siacs.conversations.ui.ConversationFragment;
|
||||||
|
import eu.siacs.conversations.ui.XmppActivity;
|
||||||
|
import eu.siacs.conversations.ui.util.Attachment;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
public class MediaPreviewAdapter
|
||||||
import eu.siacs.conversations.databinding.MediaPreviewBinding;
|
extends RecyclerView.Adapter<MediaPreviewAdapter.MediaPreviewViewHolder> {
|
||||||
import eu.siacs.conversations.persistance.FileBackend;
|
|
||||||
import eu.siacs.conversations.ui.ConversationFragment;
|
|
||||||
import eu.siacs.conversations.ui.XmppActivity;
|
|
||||||
import eu.siacs.conversations.ui.util.Attachment;
|
|
||||||
|
|
||||||
public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapter.MediaPreviewViewHolder> {
|
|
||||||
|
|
||||||
private final ArrayList<Attachment> mediaPreviews = new ArrayList<>();
|
private final ArrayList<Attachment> mediaPreviews = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -43,8 +46,9 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public MediaPreviewViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
public MediaPreviewViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
|
final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
|
||||||
MediaPreviewBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.media_preview, parent, false);
|
ItemMediaPreviewBinding binding =
|
||||||
|
DataBindingUtil.inflate(layoutInflater, R.layout.item_media_preview, parent, false);
|
||||||
return new MediaPreviewViewHolder(binding);
|
return new MediaPreviewViewHolder(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,18 +57,19 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
|
||||||
final Context context = conversationFragment.getActivity();
|
final Context context = conversationFragment.getActivity();
|
||||||
final Attachment attachment = mediaPreviews.get(position);
|
final Attachment attachment = mediaPreviews.get(position);
|
||||||
if (attachment.renderThumbnail()) {
|
if (attachment.renderThumbnail()) {
|
||||||
holder.binding.mediaPreview.setImageAlpha(255);
|
ImageViewCompat.setImageTintList(holder.binding.mediaPreview, null);
|
||||||
loadPreview(attachment, holder.binding.mediaPreview);
|
loadPreview(attachment, holder.binding.mediaPreview);
|
||||||
} else {
|
} else {
|
||||||
cancelPotentialWork(attachment, holder.binding.mediaPreview);
|
cancelPotentialWork(attachment, holder.binding.mediaPreview);
|
||||||
MediaAdapter.renderPreview(context, attachment, holder.binding.mediaPreview);
|
MediaAdapter.renderPreview(attachment, holder.binding.mediaPreview);
|
||||||
}
|
}
|
||||||
holder.binding.deleteButton.setOnClickListener(v -> {
|
holder.binding.deleteButton.setOnClickListener(
|
||||||
final int pos = mediaPreviews.indexOf(attachment);
|
v -> {
|
||||||
mediaPreviews.remove(pos);
|
final int pos = mediaPreviews.indexOf(attachment);
|
||||||
notifyItemRemoved(pos);
|
mediaPreviews.remove(pos);
|
||||||
conversationFragment.toggleInputMethod();
|
notifyItemRemoved(pos);
|
||||||
});
|
conversationFragment.toggleInputMethod();
|
||||||
|
});
|
||||||
holder.binding.mediaPreview.setOnClickListener(v -> view(context, attachment));
|
holder.binding.mediaPreview.setOnClickListener(v -> view(context, attachment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,9 +81,14 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
|
||||||
try {
|
try {
|
||||||
context.startActivity(view);
|
context.startActivity(view);
|
||||||
} catch (final ActivityNotFoundException e) {
|
} catch (final ActivityNotFoundException e) {
|
||||||
Toast.makeText(context, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
} catch (final SecurityException e) {
|
} catch (final SecurityException e) {
|
||||||
Toast.makeText(context, R.string.sharing_application_not_grant_permission, Toast.LENGTH_SHORT).show();
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
R.string.sharing_application_not_grant_permission,
|
||||||
|
Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,16 +100,27 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
|
||||||
private void loadPreview(Attachment attachment, ImageView imageView) {
|
private void loadPreview(Attachment attachment, ImageView imageView) {
|
||||||
if (cancelPotentialWork(attachment, imageView)) {
|
if (cancelPotentialWork(attachment, imageView)) {
|
||||||
XmppActivity activity = (XmppActivity) conversationFragment.getActivity();
|
XmppActivity activity = (XmppActivity) conversationFragment.getActivity();
|
||||||
final Bitmap bm = activity.xmppConnectionService.getFileBackend().getPreviewForUri(attachment,Math.round(activity.getResources().getDimension(R.dimen.media_preview_size)),true);
|
final Bitmap bm =
|
||||||
|
activity.xmppConnectionService
|
||||||
|
.getFileBackend()
|
||||||
|
.getPreviewForUri(
|
||||||
|
attachment,
|
||||||
|
Math.round(
|
||||||
|
activity.getResources()
|
||||||
|
.getDimension(R.dimen.media_preview_size)),
|
||||||
|
true);
|
||||||
if (bm != null) {
|
if (bm != null) {
|
||||||
cancelPotentialWork(attachment, imageView);
|
cancelPotentialWork(attachment, imageView);
|
||||||
imageView.setImageBitmap(bm);
|
imageView.setImageBitmap(bm);
|
||||||
imageView.setBackgroundColor(0x00000000);
|
imageView.setBackgroundColor(0x00000000);
|
||||||
} else {
|
} else {
|
||||||
imageView.setBackgroundColor(0xff333333);
|
imageView.setBackgroundColor(
|
||||||
|
ContextCompat.getColor(imageView.getContext(), R.color.gray_800));
|
||||||
imageView.setImageDrawable(null);
|
imageView.setImageDrawable(null);
|
||||||
final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
|
final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
|
||||||
final AsyncDrawable asyncDrawable = new AsyncDrawable(conversationFragment.getActivity().getResources(), null, task);
|
final AsyncDrawable asyncDrawable =
|
||||||
|
new AsyncDrawable(
|
||||||
|
conversationFragment.getActivity().getResources(), null, task);
|
||||||
imageView.setImageDrawable(asyncDrawable);
|
imageView.setImageDrawable(asyncDrawable);
|
||||||
try {
|
try {
|
||||||
task.execute(attachment);
|
task.execute(attachment);
|
||||||
|
@ -126,8 +147,7 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
|
||||||
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
|
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
|
||||||
if (imageView != null) {
|
if (imageView != null) {
|
||||||
final Drawable drawable = imageView.getDrawable();
|
final Drawable drawable = imageView.getDrawable();
|
||||||
if (drawable instanceof AsyncDrawable) {
|
if (drawable instanceof AsyncDrawable asyncDrawable) {
|
||||||
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
|
|
||||||
return asyncDrawable.getBitmapWorkerTask();
|
return asyncDrawable.getBitmapWorkerTask();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +160,7 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAttachments() {
|
public boolean hasAttachments() {
|
||||||
return mediaPreviews.size() > 0;
|
return !mediaPreviews.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Attachment> getAttachments() {
|
public ArrayList<Attachment> getAttachments() {
|
||||||
|
@ -153,9 +173,9 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
|
||||||
|
|
||||||
static class MediaPreviewViewHolder extends RecyclerView.ViewHolder {
|
static class MediaPreviewViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
private final MediaPreviewBinding binding;
|
private final ItemMediaPreviewBinding binding;
|
||||||
|
|
||||||
MediaPreviewViewHolder(MediaPreviewBinding binding) {
|
MediaPreviewViewHolder(ItemMediaPreviewBinding binding) {
|
||||||
super(binding.getRoot());
|
super(binding.getRoot());
|
||||||
this.binding = binding;
|
this.binding = binding;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +209,14 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return activity.xmppConnectionService.getFileBackend().getPreviewForUri(this.attachment, Math.round(activity.getResources().getDimension(R.dimen.media_preview_size)), false);
|
return activity.xmppConnectionService
|
||||||
|
.getFileBackend()
|
||||||
|
.getPreviewForUri(
|
||||||
|
this.attachment,
|
||||||
|
Math.round(
|
||||||
|
activity.getResources()
|
||||||
|
.getDimension(R.dimen.media_preview_size)),
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
@ -20,16 +21,22 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.AttrRes;
|
||||||
|
import androidx.annotation.ColorInt;
|
||||||
|
import androidx.annotation.DrawableRes;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.core.widget.ImageViewCompat;
|
||||||
|
|
||||||
|
import com.google.android.material.button.MaterialButton;
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -58,6 +65,7 @@ import eu.siacs.conversations.ui.XmppActivity;
|
||||||
import eu.siacs.conversations.ui.service.AudioPlayer;
|
import eu.siacs.conversations.ui.service.AudioPlayer;
|
||||||
import eu.siacs.conversations.ui.text.DividerSpan;
|
import eu.siacs.conversations.ui.text.DividerSpan;
|
||||||
import eu.siacs.conversations.ui.text.QuoteSpan;
|
import eu.siacs.conversations.ui.text.QuoteSpan;
|
||||||
|
import eu.siacs.conversations.ui.util.Attachment;
|
||||||
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
||||||
import eu.siacs.conversations.ui.util.MyLinkify;
|
import eu.siacs.conversations.ui.util.MyLinkify;
|
||||||
import eu.siacs.conversations.ui.util.QuoteHelper;
|
import eu.siacs.conversations.ui.util.QuoteHelper;
|
||||||
|
@ -160,15 +168,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
return this.getItemViewType(getItem(position));
|
return this.getItemViewType(getItem(position));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMessageTextColor(boolean onDark, boolean primary) {
|
private void displayStatus(ViewHolder viewHolder, Message message, int type, final BubbleColor bubbleColor) {
|
||||||
if (onDark) {
|
|
||||||
return ContextCompat.getColor(activity, primary ? R.color.white : R.color.white70);
|
|
||||||
} else {
|
|
||||||
return ContextCompat.getColor(activity, primary ? R.color.black87 : R.color.black54);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void displayStatus(ViewHolder viewHolder, Message message, int type, boolean darkBackground) {
|
|
||||||
String filesize = null;
|
String filesize = null;
|
||||||
String info = null;
|
String info = null;
|
||||||
boolean error = false;
|
boolean error = false;
|
||||||
|
@ -179,8 +179,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
if (viewHolder.edit_indicator != null) {
|
if (viewHolder.edit_indicator != null) {
|
||||||
if (message.edited()) {
|
if (message.edited()) {
|
||||||
viewHolder.edit_indicator.setVisibility(View.VISIBLE);
|
viewHolder.edit_indicator.setVisibility(View.VISIBLE);
|
||||||
viewHolder.edit_indicator.setImageResource(darkBackground ? R.drawable.ic_mode_edit_white_18dp : R.drawable.ic_mode_edit_black_18dp);
|
setImageTint(viewHolder.edit_indicator, bubbleColor);
|
||||||
viewHolder.edit_indicator.setAlpha(darkBackground ? 0.7f : 0.57f);
|
|
||||||
} else {
|
} else {
|
||||||
viewHolder.edit_indicator.setVisibility(View.GONE);
|
viewHolder.edit_indicator.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
@ -211,8 +210,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
break;
|
break;
|
||||||
case Message.STATUS_SEND_RECEIVED:
|
case Message.STATUS_SEND_RECEIVED:
|
||||||
case Message.STATUS_SEND_DISPLAYED:
|
case Message.STATUS_SEND_DISPLAYED:
|
||||||
viewHolder.indicatorReceived.setImageResource(darkBackground ? R.drawable.ic_done_white_18dp : R.drawable.ic_done_black_18dp);
|
setImageTint(viewHolder.indicatorReceived, bubbleColor);
|
||||||
viewHolder.indicatorReceived.setAlpha(darkBackground ? 0.7f : 0.57f);
|
|
||||||
viewHolder.indicatorReceived.setVisibility(View.VISIBLE);
|
viewHolder.indicatorReceived.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
case Message.STATUS_SEND_FAILED:
|
case Message.STATUS_SEND_FAILED:
|
||||||
|
@ -245,18 +243,9 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (error && type == SENT) {
|
if (error && type == SENT) {
|
||||||
if (darkBackground) {
|
viewHolder.time.setTextColor(MaterialColors.getColor(viewHolder.time, com.google.android.material.R.attr.colorError));
|
||||||
viewHolder.time.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Caption_Warning_OnDark);
|
|
||||||
} else {
|
|
||||||
viewHolder.time.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Caption_Warning);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (darkBackground) {
|
setTextColor(viewHolder.time,bubbleColor);
|
||||||
viewHolder.time.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Caption_OnDark);
|
|
||||||
} else {
|
|
||||||
viewHolder.time.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Caption);
|
|
||||||
}
|
|
||||||
viewHolder.time.setTextColor(this.getMessageTextColor(darkBackground, false));
|
|
||||||
}
|
}
|
||||||
if (message.getEncryption() == Message.ENCRYPTION_NONE) {
|
if (message.getEncryption() == Message.ENCRYPTION_NONE) {
|
||||||
viewHolder.indicator.setVisibility(View.GONE);
|
viewHolder.indicator.setVisibility(View.GONE);
|
||||||
|
@ -271,15 +260,11 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (verified) {
|
if (verified) {
|
||||||
viewHolder.indicator.setImageResource(darkBackground ? R.drawable.ic_verified_user_white_18dp : R.drawable.ic_verified_user_black_18dp);
|
viewHolder.indicator.setImageResource(R.drawable.ic_verified_user_24dp);
|
||||||
} else {
|
} else {
|
||||||
viewHolder.indicator.setImageResource(darkBackground ? R.drawable.ic_lock_white_18dp : R.drawable.ic_lock_black_18dp);
|
viewHolder.indicator.setImageResource(R.drawable.ic_lock_24dp);
|
||||||
}
|
|
||||||
if (darkBackground) {
|
|
||||||
viewHolder.indicator.setAlpha(0.7f);
|
|
||||||
} else {
|
|
||||||
viewHolder.indicator.setAlpha(0.57f);
|
|
||||||
}
|
}
|
||||||
|
setImageTint(viewHolder.indicator, bubbleColor);
|
||||||
viewHolder.indicator.setVisibility(View.VISIBLE);
|
viewHolder.indicator.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,37 +298,29 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayInfoMessage(ViewHolder viewHolder, CharSequence text, boolean darkBackground) {
|
private void displayInfoMessage(ViewHolder viewHolder, CharSequence text, final BubbleColor bubbleColor) {
|
||||||
viewHolder.download_button.setVisibility(View.GONE);
|
viewHolder.download_button.setVisibility(View.GONE);
|
||||||
viewHolder.audioPlayer.setVisibility(View.GONE);
|
viewHolder.audioPlayer.setVisibility(View.GONE);
|
||||||
viewHolder.image.setVisibility(View.GONE);
|
viewHolder.image.setVisibility(View.GONE);
|
||||||
viewHolder.messageBody.setVisibility(View.VISIBLE);
|
viewHolder.messageBody.setVisibility(View.VISIBLE);
|
||||||
viewHolder.messageBody.setText(text);
|
viewHolder.messageBody.setText(text);
|
||||||
if (darkBackground) {
|
viewHolder.messageBody.setTextColor(bubbleToOnSurfaceVariant(viewHolder.messageBody,bubbleColor));
|
||||||
viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1_Secondary_OnDark);
|
|
||||||
} else {
|
|
||||||
viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1_Secondary);
|
|
||||||
}
|
|
||||||
viewHolder.messageBody.setTextIsSelectable(false);
|
viewHolder.messageBody.setTextIsSelectable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayEmojiMessage(final ViewHolder viewHolder, final String body, final boolean darkBackground) {
|
private void displayEmojiMessage(final ViewHolder viewHolder, final String body, final BubbleColor bubbleColor) {
|
||||||
viewHolder.download_button.setVisibility(View.GONE);
|
viewHolder.download_button.setVisibility(View.GONE);
|
||||||
viewHolder.audioPlayer.setVisibility(View.GONE);
|
viewHolder.audioPlayer.setVisibility(View.GONE);
|
||||||
viewHolder.image.setVisibility(View.GONE);
|
viewHolder.image.setVisibility(View.GONE);
|
||||||
viewHolder.messageBody.setVisibility(View.VISIBLE);
|
viewHolder.messageBody.setVisibility(View.VISIBLE);
|
||||||
if (darkBackground) {
|
setTextColor(viewHolder.messageBody, bubbleColor);
|
||||||
viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1_Emoji_OnDark);
|
final Spannable span = new SpannableString(body);
|
||||||
} else {
|
|
||||||
viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1_Emoji);
|
|
||||||
}
|
|
||||||
Spannable span = new SpannableString(body);
|
|
||||||
float size = Emoticons.isEmoji(body) ? 3.0f : 2.0f;
|
float size = Emoticons.isEmoji(body) ? 3.0f : 2.0f;
|
||||||
span.setSpan(new RelativeSizeSpan(size), 0, body.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
span.setSpan(new RelativeSizeSpan(size), 0, body.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
viewHolder.messageBody.setText(span);
|
viewHolder.messageBody.setText(span);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyQuoteSpan(SpannableStringBuilder body, int start, int end, boolean darkBackground) {
|
private void applyQuoteSpan(final TextView textView, SpannableStringBuilder body, int start, int end, final BubbleColor bubbleColor) {
|
||||||
if (start > 1 && !"\n\n".equals(body.subSequence(start - 2, start).toString())) {
|
if (start > 1 && !"\n\n".equals(body.subSequence(start - 2, start).toString())) {
|
||||||
body.insert(start++, "\n");
|
body.insert(start++, "\n");
|
||||||
body.setSpan(new DividerSpan(false), start - 2, start, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
body.setSpan(new DividerSpan(false), start - 2, start, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
@ -353,17 +330,15 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
body.insert(end, "\n");
|
body.insert(end, "\n");
|
||||||
body.setSpan(new DividerSpan(false), end, end + 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
body.setSpan(new DividerSpan(false), end, end + 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
}
|
}
|
||||||
int color = darkBackground ? this.getMessageTextColor(darkBackground, false)
|
final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
|
||||||
: ContextCompat.getColor(activity, R.color.green700_desaturated);
|
body.setSpan(new QuoteSpan(bubbleToOnSurfaceVariant(textView, bubbleColor), metrics), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
|
|
||||||
body.setSpan(new QuoteSpan(color, metrics), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies QuoteSpan to group of lines which starts with > or » characters.
|
* Applies QuoteSpan to group of lines which starts with > or » characters.
|
||||||
* Appends likebreaks and applies DividerSpan to them to show a padding between quote and text.
|
* Appends likebreaks and applies DividerSpan to them to show a padding between quote and text.
|
||||||
*/
|
*/
|
||||||
private boolean handleTextQuotes(SpannableStringBuilder body, boolean darkBackground) {
|
private boolean handleTextQuotes(final TextView textView, final SpannableStringBuilder body, final BubbleColor bubbleColor) {
|
||||||
boolean startsWithQuote = false;
|
boolean startsWithQuote = false;
|
||||||
int quoteDepth = 1;
|
int quoteDepth = 1;
|
||||||
while (QuoteHelper.bodyContainsQuoteStart(body) && quoteDepth <= Config.QUOTE_MAX_DEPTH) {
|
while (QuoteHelper.bodyContainsQuoteStart(body) && quoteDepth <= Config.QUOTE_MAX_DEPTH) {
|
||||||
|
@ -382,7 +357,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
if (i == 0) startsWithQuote = true;
|
if (i == 0) startsWithQuote = true;
|
||||||
} else if (quoteStart >= 0) {
|
} else if (quoteStart >= 0) {
|
||||||
// Line start without quote, apply spans there
|
// Line start without quote, apply spans there
|
||||||
applyQuoteSpan(body, quoteStart, i - 1, darkBackground);
|
applyQuoteSpan(textView, body, quoteStart, i - 1, bubbleColor);
|
||||||
quoteStart = -1;
|
quoteStart = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -407,26 +382,19 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
}
|
}
|
||||||
if (quoteStart >= 0) {
|
if (quoteStart >= 0) {
|
||||||
// Apply spans to finishing open quote
|
// Apply spans to finishing open quote
|
||||||
applyQuoteSpan(body, quoteStart, body.length(), darkBackground);
|
applyQuoteSpan(textView, body, quoteStart, body.length(), bubbleColor);
|
||||||
}
|
}
|
||||||
quoteDepth++;
|
quoteDepth++;
|
||||||
}
|
}
|
||||||
return startsWithQuote;
|
return startsWithQuote;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayTextMessage(final ViewHolder viewHolder, final Message message, boolean darkBackground, int type) {
|
private void displayTextMessage(final ViewHolder viewHolder, final Message message, final BubbleColor bubbleColor, int type) {
|
||||||
viewHolder.download_button.setVisibility(View.GONE);
|
viewHolder.download_button.setVisibility(View.GONE);
|
||||||
viewHolder.image.setVisibility(View.GONE);
|
viewHolder.image.setVisibility(View.GONE);
|
||||||
viewHolder.audioPlayer.setVisibility(View.GONE);
|
viewHolder.audioPlayer.setVisibility(View.GONE);
|
||||||
viewHolder.messageBody.setVisibility(View.VISIBLE);
|
viewHolder.messageBody.setVisibility(View.VISIBLE);
|
||||||
|
setTextColor(viewHolder.messageBody, bubbleColor);
|
||||||
if (darkBackground) {
|
|
||||||
viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1_OnDark);
|
|
||||||
} else {
|
|
||||||
viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1);
|
|
||||||
}
|
|
||||||
viewHolder.messageBody.setHighlightColor(ContextCompat.getColor(activity, darkBackground
|
|
||||||
? (type == SENT || !mUseGreenBackground ? R.color.black26 : R.color.grey800) : R.color.grey500));
|
|
||||||
viewHolder.messageBody.setTypeface(null, Typeface.NORMAL);
|
viewHolder.messageBody.setTypeface(null, Typeface.NORMAL);
|
||||||
|
|
||||||
if (message.getBody() != null) {
|
if (message.getBody() != null) {
|
||||||
|
@ -446,7 +414,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
int end = body.getSpanEnd(mergeSeparator);
|
int end = body.getSpanEnd(mergeSeparator);
|
||||||
body.setSpan(new DividerSpan(true), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
body.setSpan(new DividerSpan(true), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
}
|
}
|
||||||
boolean startsWithQuote = handleTextQuotes(body, darkBackground);
|
boolean startsWithQuote = handleTextQuotes(viewHolder.messageBody, body, bubbleColor);
|
||||||
if (!message.isPrivateMessage()) {
|
if (!message.isPrivateMessage()) {
|
||||||
if (hasMeCommand) {
|
if (hasMeCommand) {
|
||||||
body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(),
|
body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(),
|
||||||
|
@ -469,7 +437,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
} else {
|
} else {
|
||||||
body.insert(privateMarkerIndex, " ");
|
body.insert(privateMarkerIndex, " ");
|
||||||
}
|
}
|
||||||
body.setSpan(new ForegroundColorSpan(getMessageTextColor(darkBackground, false)), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
body.setSpan(new ForegroundColorSpan(bubbleToOnSurfaceVariant(viewHolder.messageBody, bubbleColor)), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
body.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
body.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
if (hasMeCommand) {
|
if (hasMeCommand) {
|
||||||
body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarkerIndex + 1,
|
body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarkerIndex + 1,
|
||||||
|
@ -477,8 +445,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (message.getConversation().getMode() == Conversation.MODE_MULTI && message.getStatus() == Message.STATUS_RECEIVED) {
|
if (message.getConversation().getMode() == Conversation.MODE_MULTI && message.getStatus() == Message.STATUS_RECEIVED) {
|
||||||
if (message.getConversation() instanceof Conversation) {
|
if (message.getConversation() instanceof Conversation conversation) {
|
||||||
final Conversation conversation = (Conversation) message.getConversation();
|
|
||||||
Pattern pattern = NotificationService.generateNickHighlightPattern(conversation.getMucOptions().getActualNick());
|
Pattern pattern = NotificationService.generateNickHighlightPattern(conversation.getMucOptions().getActualNick());
|
||||||
Matcher matcher = pattern.matcher(body);
|
Matcher matcher = pattern.matcher(body);
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
|
@ -495,7 +462,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
|
|
||||||
StylingHelper.format(body, viewHolder.messageBody.getCurrentTextColor());
|
StylingHelper.format(body, viewHolder.messageBody.getCurrentTextColor());
|
||||||
if (highlightedTerm != null) {
|
if (highlightedTerm != null) {
|
||||||
StylingHelper.highlight(activity, body, highlightedTerm, StylingHelper.isDarkText(viewHolder.messageBody));
|
StylingHelper.highlight(viewHolder.messageBody, body, highlightedTerm);
|
||||||
}
|
}
|
||||||
MyLinkify.addLinks(body, true);
|
MyLinkify.addLinks(body, true);
|
||||||
viewHolder.messageBody.setAutoLinkMask(0);
|
viewHolder.messageBody.setAutoLinkMask(0);
|
||||||
|
@ -507,45 +474,54 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayDownloadableMessage(ViewHolder viewHolder, final Message message, String text, final boolean darkBackground) {
|
private void displayDownloadableMessage(ViewHolder viewHolder, final Message message, String text, final BubbleColor bubbleColor) {
|
||||||
toggleWhisperInfo(viewHolder, message, darkBackground);
|
toggleWhisperInfo(viewHolder, message, bubbleColor);
|
||||||
viewHolder.image.setVisibility(View.GONE);
|
viewHolder.image.setVisibility(View.GONE);
|
||||||
viewHolder.audioPlayer.setVisibility(View.GONE);
|
viewHolder.audioPlayer.setVisibility(View.GONE);
|
||||||
viewHolder.download_button.setVisibility(View.VISIBLE);
|
viewHolder.download_button.setVisibility(View.VISIBLE);
|
||||||
viewHolder.download_button.setText(text);
|
viewHolder.download_button.setText(text);
|
||||||
|
final var attachment = Attachment.of(message);
|
||||||
|
final @DrawableRes int imageResource = MediaAdapter.getImageDrawable(attachment);
|
||||||
|
viewHolder.download_button.setIconResource(imageResource);
|
||||||
viewHolder.download_button.setOnClickListener(v -> ConversationFragment.downloadFile(activity, message));
|
viewHolder.download_button.setOnClickListener(v -> ConversationFragment.downloadFile(activity, message));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayOpenableMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) {
|
private void displayOpenableMessage(ViewHolder viewHolder, final Message message, final BubbleColor bubbleColor) {
|
||||||
toggleWhisperInfo(viewHolder, message, darkBackground);
|
toggleWhisperInfo(viewHolder, message, bubbleColor);
|
||||||
viewHolder.image.setVisibility(View.GONE);
|
viewHolder.image.setVisibility(View.GONE);
|
||||||
viewHolder.audioPlayer.setVisibility(View.GONE);
|
viewHolder.audioPlayer.setVisibility(View.GONE);
|
||||||
viewHolder.download_button.setVisibility(View.VISIBLE);
|
viewHolder.download_button.setVisibility(View.VISIBLE);
|
||||||
viewHolder.download_button.setText(activity.getString(R.string.open_x_file, UIHelper.getFileDescriptionString(activity, message)));
|
viewHolder.download_button.setText(activity.getString(R.string.open_x_file, UIHelper.getFileDescriptionString(activity, message)));
|
||||||
|
final var attachment = Attachment.of(message);
|
||||||
|
final @DrawableRes int imageResource = MediaAdapter.getImageDrawable(attachment);
|
||||||
|
viewHolder.download_button.setIconResource(imageResource);
|
||||||
viewHolder.download_button.setOnClickListener(v -> openDownloadable(message));
|
viewHolder.download_button.setOnClickListener(v -> openDownloadable(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayLocationMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) {
|
private void displayLocationMessage(ViewHolder viewHolder, final Message message, final BubbleColor bubbleColor) {
|
||||||
toggleWhisperInfo(viewHolder, message, darkBackground);
|
toggleWhisperInfo(viewHolder, message, bubbleColor);
|
||||||
viewHolder.image.setVisibility(View.GONE);
|
viewHolder.image.setVisibility(View.GONE);
|
||||||
viewHolder.audioPlayer.setVisibility(View.GONE);
|
viewHolder.audioPlayer.setVisibility(View.GONE);
|
||||||
viewHolder.download_button.setVisibility(View.VISIBLE);
|
viewHolder.download_button.setVisibility(View.VISIBLE);
|
||||||
viewHolder.download_button.setText(R.string.show_location);
|
viewHolder.download_button.setText(R.string.show_location);
|
||||||
|
final var attachment = Attachment.of(message);
|
||||||
|
final @DrawableRes int imageResource = MediaAdapter.getImageDrawable(attachment);
|
||||||
|
viewHolder.download_button.setIconResource(imageResource);
|
||||||
viewHolder.download_button.setOnClickListener(v -> showLocation(message));
|
viewHolder.download_button.setOnClickListener(v -> showLocation(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayAudioMessage(ViewHolder viewHolder, Message message, boolean darkBackground) {
|
private void displayAudioMessage(ViewHolder viewHolder, Message message, final BubbleColor bubbleColor) {
|
||||||
toggleWhisperInfo(viewHolder, message, darkBackground);
|
toggleWhisperInfo(viewHolder, message, bubbleColor);
|
||||||
viewHolder.image.setVisibility(View.GONE);
|
viewHolder.image.setVisibility(View.GONE);
|
||||||
viewHolder.download_button.setVisibility(View.GONE);
|
viewHolder.download_button.setVisibility(View.GONE);
|
||||||
final RelativeLayout audioPlayer = viewHolder.audioPlayer;
|
final RelativeLayout audioPlayer = viewHolder.audioPlayer;
|
||||||
audioPlayer.setVisibility(View.VISIBLE);
|
audioPlayer.setVisibility(View.VISIBLE);
|
||||||
AudioPlayer.ViewHolder.get(audioPlayer).setDarkBackground(darkBackground);
|
AudioPlayer.ViewHolder.get(audioPlayer).setBubbleColor(bubbleColor);
|
||||||
this.audioPlayer.init(audioPlayer, message);
|
this.audioPlayer.init(audioPlayer, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayMediaPreviewMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) {
|
private void displayMediaPreviewMessage(ViewHolder viewHolder, final Message message, final BubbleColor bubbleColor) {
|
||||||
toggleWhisperInfo(viewHolder, message, darkBackground);
|
toggleWhisperInfo(viewHolder, message, bubbleColor);
|
||||||
viewHolder.download_button.setVisibility(View.GONE);
|
viewHolder.download_button.setVisibility(View.GONE);
|
||||||
viewHolder.audioPlayer.setVisibility(View.GONE);
|
viewHolder.audioPlayer.setVisibility(View.GONE);
|
||||||
viewHolder.image.setVisibility(View.VISIBLE);
|
viewHolder.image.setVisibility(View.VISIBLE);
|
||||||
|
@ -573,7 +549,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
viewHolder.image.setOnClickListener(v -> openDownloadable(message));
|
viewHolder.image.setOnClickListener(v -> openDownloadable(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toggleWhisperInfo(ViewHolder viewHolder, final Message message, final boolean darkBackground) {
|
private void toggleWhisperInfo(ViewHolder viewHolder, final Message message, final BubbleColor bubbleColor) {
|
||||||
if (message.isPrivateMessage()) {
|
if (message.isPrivateMessage()) {
|
||||||
final String privateMarker;
|
final String privateMarker;
|
||||||
if (message.getStatus() <= Message.STATUS_RECEIVED) {
|
if (message.getStatus() <= Message.STATUS_RECEIVED) {
|
||||||
|
@ -583,7 +559,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
privateMarker = activity.getString(R.string.private_message_to, Strings.nullToEmpty(cp == null ? null : cp.getResource()));
|
privateMarker = activity.getString(R.string.private_message_to, Strings.nullToEmpty(cp == null ? null : cp.getResource()));
|
||||||
}
|
}
|
||||||
final SpannableString body = new SpannableString(privateMarker);
|
final SpannableString body = new SpannableString(privateMarker);
|
||||||
body.setSpan(new ForegroundColorSpan(getMessageTextColor(darkBackground, false)), 0, privateMarker.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
body.setSpan(new ForegroundColorSpan(bubbleToOnSurfaceVariant(viewHolder.messageBody, bubbleColor)), 0, privateMarker.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
body.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarker.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
body.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarker.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
viewHolder.messageBody.setText(body);
|
viewHolder.messageBody.setText(body);
|
||||||
viewHolder.messageBody.setVisibility(View.VISIBLE);
|
viewHolder.messageBody.setVisibility(View.VISIBLE);
|
||||||
|
@ -611,7 +587,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View view, ViewGroup parent) {
|
public View getView(final int position, View view, final @NonNull ViewGroup parent) {
|
||||||
final Message message = getItem(position);
|
final Message message = getItem(position);
|
||||||
final boolean omemoEncryption = message.getEncryption() == Message.ENCRYPTION_AXOLOTL;
|
final boolean omemoEncryption = message.getEncryption() == Message.ENCRYPTION_AXOLOTL;
|
||||||
final boolean isInValidSession = message.isValidInSession() && (!omemoEncryption || message.isTrusted());
|
final boolean isInValidSession = message.isValidInSession() && (!omemoEncryption || message.isTrusted());
|
||||||
|
@ -623,19 +599,18 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
viewHolder = new ViewHolder();
|
viewHolder = new ViewHolder();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DATE_SEPARATOR:
|
case DATE_SEPARATOR:
|
||||||
view = activity.getLayoutInflater().inflate(R.layout.message_date_bubble, parent, false);
|
view = activity.getLayoutInflater().inflate(R.layout.item_message_date_bubble, parent, false);
|
||||||
viewHolder.status_message = view.findViewById(R.id.message_body);
|
viewHolder.status_message = view.findViewById(R.id.message_body);
|
||||||
viewHolder.message_box = view.findViewById(R.id.message_box);
|
viewHolder.message_box = view.findViewById(R.id.message_box);
|
||||||
viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received);
|
|
||||||
break;
|
break;
|
||||||
case RTP_SESSION:
|
case RTP_SESSION:
|
||||||
view = activity.getLayoutInflater().inflate(R.layout.message_rtp_session, parent, false);
|
view = activity.getLayoutInflater().inflate(R.layout.item_message_rtp_session, parent, false);
|
||||||
viewHolder.status_message = view.findViewById(R.id.message_body);
|
viewHolder.status_message = view.findViewById(R.id.message_body);
|
||||||
viewHolder.message_box = view.findViewById(R.id.message_box);
|
viewHolder.message_box = view.findViewById(R.id.message_box);
|
||||||
viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received);
|
viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received);
|
||||||
break;
|
break;
|
||||||
case SENT:
|
case SENT:
|
||||||
view = activity.getLayoutInflater().inflate(R.layout.message_sent, parent, false);
|
view = activity.getLayoutInflater().inflate(R.layout.item_message_sent, parent, false);
|
||||||
viewHolder.message_box = view.findViewById(R.id.message_box);
|
viewHolder.message_box = view.findViewById(R.id.message_box);
|
||||||
viewHolder.contact_picture = view.findViewById(R.id.message_photo);
|
viewHolder.contact_picture = view.findViewById(R.id.message_photo);
|
||||||
viewHolder.download_button = view.findViewById(R.id.download_button);
|
viewHolder.download_button = view.findViewById(R.id.download_button);
|
||||||
|
@ -648,7 +623,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
viewHolder.audioPlayer = view.findViewById(R.id.audio_player);
|
viewHolder.audioPlayer = view.findViewById(R.id.audio_player);
|
||||||
break;
|
break;
|
||||||
case RECEIVED:
|
case RECEIVED:
|
||||||
view = activity.getLayoutInflater().inflate(R.layout.message_received, parent, false);
|
view = activity.getLayoutInflater().inflate(R.layout.item_message_received, parent, false);
|
||||||
viewHolder.message_box = view.findViewById(R.id.message_box);
|
viewHolder.message_box = view.findViewById(R.id.message_box);
|
||||||
viewHolder.contact_picture = view.findViewById(R.id.message_photo);
|
viewHolder.contact_picture = view.findViewById(R.id.message_photo);
|
||||||
viewHolder.download_button = view.findViewById(R.id.download_button);
|
viewHolder.download_button = view.findViewById(R.id.download_button);
|
||||||
|
@ -662,7 +637,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
viewHolder.audioPlayer = view.findViewById(R.id.audio_player);
|
viewHolder.audioPlayer = view.findViewById(R.id.audio_player);
|
||||||
break;
|
break;
|
||||||
case STATUS:
|
case STATUS:
|
||||||
view = activity.getLayoutInflater().inflate(R.layout.message_status, parent, false);
|
view = activity.getLayoutInflater().inflate(R.layout.item_message_status, parent, false);
|
||||||
viewHolder.contact_picture = view.findViewById(R.id.message_photo);
|
viewHolder.contact_picture = view.findViewById(R.id.message_photo);
|
||||||
viewHolder.status_message = view.findViewById(R.id.status_message);
|
viewHolder.status_message = view.findViewById(R.id.status_message);
|
||||||
viewHolder.load_more_messages = view.findViewById(R.id.load_more_messages);
|
viewHolder.load_more_messages = view.findViewById(R.id.load_more_messages);
|
||||||
|
@ -678,7 +653,17 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean darkBackground = type == RECEIVED && (!isInValidSession || mUseGreenBackground) || activity.isDarkTheme();
|
final boolean colorfulBackground = mUseGreenBackground;
|
||||||
|
final BubbleColor bubbleColor;
|
||||||
|
if (type == RECEIVED) {
|
||||||
|
if (isInValidSession) {
|
||||||
|
bubbleColor = colorfulBackground ? BubbleColor.TERTIARY : BubbleColor.SURFACE;
|
||||||
|
} else {
|
||||||
|
bubbleColor = BubbleColor.WARNING;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bubbleColor = colorfulBackground ? BubbleColor.SECONDARY : BubbleColor.SURFACE;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == DATE_SEPARATOR) {
|
if (type == DATE_SEPARATOR) {
|
||||||
if (UIHelper.today(message.getTimeSent())) {
|
if (UIHelper.today(message.getTimeSent())) {
|
||||||
|
@ -688,10 +673,15 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
} else {
|
} else {
|
||||||
viewHolder.status_message.setText(DateUtils.formatDateTime(activity, message.getTimeSent(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
|
viewHolder.status_message.setText(DateUtils.formatDateTime(activity, message.getTimeSent(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
|
||||||
}
|
}
|
||||||
viewHolder.message_box.setBackgroundResource(activity.isDarkTheme() ? R.drawable.date_bubble_grey : R.drawable.date_bubble_white);
|
if (colorfulBackground) {
|
||||||
|
setBackgroundTint(viewHolder.message_box,BubbleColor.PRIMARY);
|
||||||
|
setTextColor(viewHolder.status_message, BubbleColor.PRIMARY);
|
||||||
|
} else {
|
||||||
|
setBackgroundTint(viewHolder.message_box,BubbleColor.SURFACE);
|
||||||
|
setTextColor(viewHolder.status_message, BubbleColor.SURFACE);
|
||||||
|
}
|
||||||
return view;
|
return view;
|
||||||
} else if (type == RTP_SESSION) {
|
} else if (type == RTP_SESSION) {
|
||||||
final boolean isDarkTheme = activity.isDarkTheme();
|
|
||||||
final boolean received = message.getStatus() <= Message.STATUS_RECEIVED;
|
final boolean received = message.getStatus() <= Message.STATUS_RECEIVED;
|
||||||
final RtpSessionStatus rtpSessionStatus = RtpSessionStatus.of(message.getBody());
|
final RtpSessionStatus rtpSessionStatus = RtpSessionStatus.of(message.getBody());
|
||||||
final long duration = rtpSessionStatus.duration;
|
final long duration = rtpSessionStatus.duration;
|
||||||
|
@ -710,9 +700,16 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
viewHolder.status_message.setText(activity.getString(R.string.outgoing_call_timestamp, UIHelper.readableTimeDifferenceFull(activity, message.getTimeSent())));
|
viewHolder.status_message.setText(activity.getString(R.string.outgoing_call_timestamp, UIHelper.readableTimeDifferenceFull(activity, message.getTimeSent())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
viewHolder.indicatorReceived.setImageResource(RtpSessionStatus.getDrawable(received, rtpSessionStatus.successful, isDarkTheme));
|
if (colorfulBackground) {
|
||||||
viewHolder.indicatorReceived.setAlpha(isDarkTheme ? 0.7f : 0.57f);
|
setBackgroundTint(viewHolder.message_box,BubbleColor.TERTIARY);
|
||||||
viewHolder.message_box.setBackgroundResource(isDarkTheme ? R.drawable.date_bubble_grey : R.drawable.date_bubble_white);
|
setTextColor(viewHolder.status_message, BubbleColor.TERTIARY);
|
||||||
|
setImageTint(viewHolder.indicatorReceived, BubbleColor.TERTIARY);
|
||||||
|
} else {
|
||||||
|
setBackgroundTint(viewHolder.message_box,BubbleColor.SURFACE);
|
||||||
|
setTextColor(viewHolder.status_message, BubbleColor.SURFACE);
|
||||||
|
setImageTint(viewHolder.indicatorReceived, BubbleColor.SURFACE);
|
||||||
|
}
|
||||||
|
viewHolder.indicatorReceived.setImageResource(RtpSessionStatus.getDrawable(received, rtpSessionStatus.successful));
|
||||||
return view;
|
return view;
|
||||||
} else if (type == STATUS) {
|
} else if (type == STATUS) {
|
||||||
if ("LOAD_MORE".equals(message.getBody())) {
|
if ("LOAD_MORE".equals(message.getBody())) {
|
||||||
|
@ -769,43 +766,43 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(message);
|
final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(message);
|
||||||
if (unInitiatedButKnownSize || message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) {
|
if (unInitiatedButKnownSize || message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) {
|
||||||
if (unInitiatedButKnownSize || transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER) {
|
if (unInitiatedButKnownSize || transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER) {
|
||||||
displayDownloadableMessage(viewHolder, message, activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message)), darkBackground);
|
displayDownloadableMessage(viewHolder, message, activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message)), bubbleColor);
|
||||||
} else if (transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER_CHECK_FILESIZE) {
|
} 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);
|
displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message)), bubbleColor);
|
||||||
} else {
|
} else {
|
||||||
displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first, darkBackground);
|
displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first, bubbleColor);
|
||||||
}
|
}
|
||||||
} else if (message.isFileOrImage() && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) {
|
} else if (message.isFileOrImage() && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) {
|
||||||
if (message.getFileParams().width > 0 && message.getFileParams().height > 0) {
|
if (message.getFileParams().width > 0 && message.getFileParams().height > 0) {
|
||||||
displayMediaPreviewMessage(viewHolder, message, darkBackground);
|
displayMediaPreviewMessage(viewHolder, message, bubbleColor);
|
||||||
} else if (message.getFileParams().runtime > 0) {
|
} else if (message.getFileParams().runtime > 0) {
|
||||||
displayAudioMessage(viewHolder, message, darkBackground);
|
displayAudioMessage(viewHolder, message, bubbleColor);
|
||||||
} else {
|
} else {
|
||||||
displayOpenableMessage(viewHolder, message, darkBackground);
|
displayOpenableMessage(viewHolder, message, bubbleColor);
|
||||||
}
|
}
|
||||||
} else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
|
} else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
|
||||||
if (account.isPgpDecryptionServiceConnected()) {
|
if (account.isPgpDecryptionServiceConnected()) {
|
||||||
if (conversation instanceof Conversation && !account.hasPendingPgpIntent((Conversation) conversation)) {
|
if (conversation instanceof Conversation && !account.hasPendingPgpIntent((Conversation) conversation)) {
|
||||||
displayInfoMessage(viewHolder, activity.getString(R.string.message_decrypting), darkBackground);
|
displayInfoMessage(viewHolder, activity.getString(R.string.message_decrypting), bubbleColor);
|
||||||
} else {
|
} else {
|
||||||
displayInfoMessage(viewHolder, activity.getString(R.string.pgp_message), darkBackground);
|
displayInfoMessage(viewHolder, activity.getString(R.string.pgp_message), bubbleColor);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
displayInfoMessage(viewHolder, activity.getString(R.string.install_openkeychain), darkBackground);
|
displayInfoMessage(viewHolder, activity.getString(R.string.install_openkeychain), bubbleColor);
|
||||||
viewHolder.message_box.setOnClickListener(this::promptOpenKeychainInstall);
|
viewHolder.message_box.setOnClickListener(this::promptOpenKeychainInstall);
|
||||||
viewHolder.messageBody.setOnClickListener(this::promptOpenKeychainInstall);
|
viewHolder.messageBody.setOnClickListener(this::promptOpenKeychainInstall);
|
||||||
}
|
}
|
||||||
} else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
|
} else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
|
||||||
displayInfoMessage(viewHolder, activity.getString(R.string.decryption_failed), darkBackground);
|
displayInfoMessage(viewHolder, activity.getString(R.string.decryption_failed), bubbleColor);
|
||||||
} else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_NOT_FOR_THIS_DEVICE) {
|
} else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_NOT_FOR_THIS_DEVICE) {
|
||||||
displayInfoMessage(viewHolder, activity.getString(R.string.not_encrypted_for_this_device), darkBackground);
|
displayInfoMessage(viewHolder, activity.getString(R.string.not_encrypted_for_this_device), bubbleColor);
|
||||||
} else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_FAILED) {
|
} else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_FAILED) {
|
||||||
displayInfoMessage(viewHolder, activity.getString(R.string.omemo_decryption_failed), darkBackground);
|
displayInfoMessage(viewHolder, activity.getString(R.string.omemo_decryption_failed), bubbleColor);
|
||||||
} else {
|
} else {
|
||||||
if (message.isGeoUri()) {
|
if (message.isGeoUri()) {
|
||||||
displayLocationMessage(viewHolder, message, darkBackground);
|
displayLocationMessage(viewHolder, message, bubbleColor);
|
||||||
} else if (message.bodyIsOnlyEmojis() && message.getType() != Message.TYPE_PRIVATE) {
|
} else if (message.bodyIsOnlyEmojis() && message.getType() != Message.TYPE_PRIVATE) {
|
||||||
displayEmojiMessage(viewHolder, message.getBody().trim(), darkBackground);
|
displayEmojiMessage(viewHolder, message.getBody().trim(), bubbleColor);
|
||||||
} else if (message.treatAsDownloadable()) {
|
} else if (message.treatAsDownloadable()) {
|
||||||
try {
|
try {
|
||||||
final URI uri = new URI(message.getBody());
|
final URI uri = new URI(message.getBody());
|
||||||
|
@ -814,31 +811,27 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
activity.getString(R.string.check_x_filesize_on_host,
|
activity.getString(R.string.check_x_filesize_on_host,
|
||||||
UIHelper.getFileDescriptionString(activity, message),
|
UIHelper.getFileDescriptionString(activity, message),
|
||||||
uri.getHost()),
|
uri.getHost()),
|
||||||
darkBackground);
|
bubbleColor);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
displayDownloadableMessage(viewHolder,
|
displayDownloadableMessage(viewHolder,
|
||||||
message,
|
message,
|
||||||
activity.getString(R.string.check_x_filesize,
|
activity.getString(R.string.check_x_filesize,
|
||||||
UIHelper.getFileDescriptionString(activity, message)),
|
UIHelper.getFileDescriptionString(activity, message)),
|
||||||
darkBackground);
|
bubbleColor);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
displayTextMessage(viewHolder, message, darkBackground, type);
|
displayTextMessage(viewHolder, message, bubbleColor, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setBackgroundTint(viewHolder.message_box, bubbleColor);
|
||||||
|
setTextColor(viewHolder.messageBody, bubbleColor);
|
||||||
|
|
||||||
if (type == RECEIVED) {
|
if (type == RECEIVED) {
|
||||||
|
setTextColor(viewHolder.encryption, bubbleColor);
|
||||||
if (isInValidSession) {
|
if (isInValidSession) {
|
||||||
int bubble;
|
|
||||||
if (!mUseGreenBackground) {
|
|
||||||
bubble = activity.getThemeResource(R.attr.message_bubble_received_monochrome, R.drawable.message_bubble_received_white);
|
|
||||||
} else {
|
|
||||||
bubble = activity.getThemeResource(R.attr.message_bubble_received_green, R.drawable.message_bubble_received);
|
|
||||||
}
|
|
||||||
viewHolder.message_box.setBackgroundResource(bubble);
|
|
||||||
viewHolder.encryption.setVisibility(View.GONE);
|
viewHolder.encryption.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received_warning);
|
|
||||||
viewHolder.encryption.setVisibility(View.VISIBLE);
|
viewHolder.encryption.setVisibility(View.VISIBLE);
|
||||||
if (omemoEncryption && !message.isTrusted()) {
|
if (omemoEncryption && !message.isTrusted()) {
|
||||||
viewHolder.encryption.setText(R.string.not_trusted);
|
viewHolder.encryption.setText(R.string.not_trusted);
|
||||||
|
@ -848,7 +841,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
displayStatus(viewHolder, message, type, darkBackground);
|
displayStatus(viewHolder, message, type, bubbleColor);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -911,13 +904,68 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
||||||
void onContactPictureLongClicked(View v, Message message);
|
void onContactPictureLongClicked(View v, Message message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void setBackgroundTint(final View view, final BubbleColor bubbleColor) {
|
||||||
|
view.setBackgroundTintList(bubbleToColorStateList(view, bubbleColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ColorStateList bubbleToColorStateList(final View view, final BubbleColor bubbleColor) {
|
||||||
|
final @AttrRes int colorAttributeResId = switch (bubbleColor) {
|
||||||
|
case SURFACE -> com.google.android.material.R.attr.colorSurfaceContainerHigh;
|
||||||
|
case PRIMARY -> com.google.android.material.R.attr.colorPrimaryContainer;
|
||||||
|
case SECONDARY -> com.google.android.material.R.attr.colorSecondaryContainer;
|
||||||
|
case TERTIARY -> com.google.android.material.R.attr.colorTertiaryContainer;
|
||||||
|
case WARNING -> com.google.android.material.R.attr.colorErrorContainer;
|
||||||
|
};
|
||||||
|
return ColorStateList.valueOf(MaterialColors.getColor(view,colorAttributeResId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setImageTint(final ImageView imageView, final BubbleColor bubbleColor) {
|
||||||
|
ImageViewCompat.setImageTintList(imageView,bubbleToOnSurfaceColorStateList(imageView, bubbleColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setTextColor(final TextView textView, final BubbleColor bubbleColor) {
|
||||||
|
textView.setTextColor(bubbleToOnSurfaceColor(textView, bubbleColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @ColorInt int bubbleToOnSurfaceVariant(final View view, final BubbleColor bubbleColor) {
|
||||||
|
final @AttrRes int colorAttributeResId;
|
||||||
|
if (bubbleColor == BubbleColor.SURFACE) {
|
||||||
|
colorAttributeResId = com.google.android.material.R.attr.colorOnSurfaceVariant;
|
||||||
|
} else {
|
||||||
|
colorAttributeResId = bubbleToOnSurface(bubbleColor);
|
||||||
|
}
|
||||||
|
return MaterialColors.getColor(view,colorAttributeResId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @ColorInt int bubbleToOnSurfaceColor(final View view, final BubbleColor bubbleColor) {
|
||||||
|
return MaterialColors.getColor(view, bubbleToOnSurface(bubbleColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ColorStateList bubbleToOnSurfaceColorStateList(final View view, final BubbleColor bubbleColor) {
|
||||||
|
return ColorStateList.valueOf(bubbleToOnSurfaceColor(view, bubbleColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @AttrRes int bubbleToOnSurface(final BubbleColor bubbleColor) {
|
||||||
|
return switch (bubbleColor) {
|
||||||
|
case SURFACE -> com.google.android.material.R.attr.colorOnSurface;
|
||||||
|
case PRIMARY -> com.google.android.material.R.attr.colorOnPrimaryContainer;
|
||||||
|
case SECONDARY -> com.google.android.material.R.attr.colorOnSecondaryContainer;
|
||||||
|
case TERTIARY -> com.google.android.material.R.attr.colorOnTertiaryContainer;
|
||||||
|
case WARNING -> com.google.android.material.R.attr.colorOnErrorContainer;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum BubbleColor {
|
||||||
|
SURFACE, PRIMARY, SECONDARY, TERTIARY, WARNING
|
||||||
|
}
|
||||||
|
|
||||||
private static class ViewHolder {
|
private static class ViewHolder {
|
||||||
|
|
||||||
public Button load_more_messages;
|
public MaterialButton load_more_messages;
|
||||||
public ImageView edit_indicator;
|
public ImageView edit_indicator;
|
||||||
public RelativeLayout audioPlayer;
|
public RelativeLayout audioPlayer;
|
||||||
protected LinearLayout message_box;
|
protected LinearLayout message_box;
|
||||||
protected Button download_button;
|
protected MaterialButton download_button;
|
||||||
protected ImageView image;
|
protected ImageView image;
|
||||||
protected ImageView indicator;
|
protected ImageView indicator;
|
||||||
protected ImageView indicatorReceived;
|
protected ImageView indicatorReceived;
|
||||||
|
|
|
@ -17,7 +17,7 @@ import org.openintents.openpgp.util.OpenPgpUtils;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.crypto.PgpEngine;
|
import eu.siacs.conversations.crypto.PgpEngine;
|
||||||
import eu.siacs.conversations.databinding.ContactBinding;
|
import eu.siacs.conversations.databinding.ItemContactBinding;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.MucOptions;
|
import eu.siacs.conversations.entities.MucOptions;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
|
@ -62,7 +62,7 @@ public class UserAdapter extends ListAdapter<MucOptions.User, UserAdapter.ViewHo
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
|
||||||
return new ViewHolder(DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), R.layout.contact, viewGroup, false));
|
return new ViewHolder(DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), R.layout.item_contact, viewGroup, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -129,11 +129,11 @@ public class UserAdapter extends ListAdapter<MucOptions.User, UserAdapter.ViewHo
|
||||||
MucDetailsContextMenuHelper.onCreateContextMenu(menu,v);
|
MucDetailsContextMenuHelper.onCreateContextMenu(menu,v);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewHolder extends RecyclerView.ViewHolder {
|
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
private final ContactBinding binding;
|
private final ItemContactBinding binding;
|
||||||
|
|
||||||
private ViewHolder(ContactBinding binding) {
|
private ViewHolder(ItemContactBinding binding) {
|
||||||
super(binding.getRoot());
|
super(binding.getRoot());
|
||||||
this.binding = binding;
|
this.binding = binding;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,14 @@ import androidx.recyclerview.widget.ListAdapter;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.UserPreviewBinding;
|
import eu.siacs.conversations.databinding.ItemUserPreviewBinding;
|
||||||
import eu.siacs.conversations.entities.MucOptions;
|
import eu.siacs.conversations.entities.MucOptions;
|
||||||
import eu.siacs.conversations.ui.XmppActivity;
|
import eu.siacs.conversations.ui.XmppActivity;
|
||||||
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
||||||
import eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper;
|
import eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper;
|
||||||
|
|
||||||
public class UserPreviewAdapter extends ListAdapter<MucOptions.User, UserPreviewAdapter.ViewHolder> implements View.OnCreateContextMenuListener {
|
public class UserPreviewAdapter extends ListAdapter<MucOptions.User, UserPreviewAdapter.ViewHolder>
|
||||||
|
implements View.OnCreateContextMenuListener {
|
||||||
|
|
||||||
private MucOptions.User selectedUser = null;
|
private MucOptions.User selectedUser = null;
|
||||||
|
|
||||||
|
@ -28,29 +29,43 @@ public class UserPreviewAdapter extends ListAdapter<MucOptions.User, UserPreview
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
|
||||||
return new ViewHolder(DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), R.layout.user_preview, viewGroup, false));
|
return new ViewHolder(
|
||||||
|
DataBindingUtil.inflate(
|
||||||
|
LayoutInflater.from(viewGroup.getContext()),
|
||||||
|
R.layout.item_user_preview,
|
||||||
|
viewGroup,
|
||||||
|
false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
|
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
|
||||||
final MucOptions.User user = getItem(position);
|
final MucOptions.User user = getItem(position);
|
||||||
AvatarWorkerTask.loadAvatar(user, viewHolder.binding.avatar, R.dimen.media_size);
|
AvatarWorkerTask.loadAvatar(user, viewHolder.binding.avatar, R.dimen.media_size);
|
||||||
viewHolder.binding.getRoot().setOnClickListener(v -> {
|
viewHolder
|
||||||
final XmppActivity activity = XmppActivity.find(v);
|
.binding
|
||||||
if (activity != null) {
|
.getRoot()
|
||||||
activity.highlightInMuc(user.getConversation(), user.getName());
|
.setOnClickListener(
|
||||||
}
|
v -> {
|
||||||
});
|
final XmppActivity activity = XmppActivity.find(v);
|
||||||
|
if (activity != null) {
|
||||||
|
activity.highlightInMuc(user.getConversation(), user.getName());
|
||||||
|
}
|
||||||
|
});
|
||||||
viewHolder.binding.getRoot().setOnCreateContextMenuListener(this);
|
viewHolder.binding.getRoot().setOnCreateContextMenuListener(this);
|
||||||
viewHolder.binding.getRoot().setTag(user);
|
viewHolder.binding.getRoot().setTag(user);
|
||||||
viewHolder.binding.getRoot().setOnLongClickListener(v -> {
|
viewHolder
|
||||||
selectedUser = user;
|
.binding
|
||||||
return false;
|
.getRoot()
|
||||||
});
|
.setOnLongClickListener(
|
||||||
|
v -> {
|
||||||
|
selectedUser = user;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
public void onCreateContextMenu(
|
||||||
|
ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||||
MucDetailsContextMenuHelper.onCreateContextMenu(menu, v);
|
MucDetailsContextMenuHelper.onCreateContextMenu(menu, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,9 +75,9 @@ public class UserPreviewAdapter extends ListAdapter<MucOptions.User, UserPreview
|
||||||
|
|
||||||
class ViewHolder extends RecyclerView.ViewHolder {
|
class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
private final UserPreviewBinding binding;
|
private final ItemUserPreviewBinding binding;
|
||||||
|
|
||||||
private ViewHolder(UserPreviewBinding binding) {
|
private ViewHolder(final ItemUserPreviewBinding binding) {
|
||||||
super(binding.getRoot());
|
super(binding.getRoot());
|
||||||
this.binding = binding;
|
this.binding = binding;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
package eu.siacs.conversations.ui.forms;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.CompoundButton;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
|
||||||
import eu.siacs.conversations.xmpp.forms.Field;
|
|
||||||
|
|
||||||
public class FormBooleanFieldWrapper extends FormFieldWrapper {
|
|
||||||
|
|
||||||
protected CheckBox checkBox;
|
|
||||||
|
|
||||||
protected FormBooleanFieldWrapper(Context context, Field field) {
|
|
||||||
super(context, field);
|
|
||||||
checkBox = view.findViewById(R.id.field);
|
|
||||||
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
||||||
checkBox.setError(null);
|
|
||||||
invokeOnFormFieldValuesEdited();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setLabel(String label, boolean required) {
|
|
||||||
CheckBox checkBox = view.findViewById(R.id.field);
|
|
||||||
checkBox.setText(createSpannableLabelString(label, required));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getValues() {
|
|
||||||
List<String> values = new ArrayList<>();
|
|
||||||
values.add(Boolean.toString(checkBox.isChecked()));
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setValues(List<String> values) {
|
|
||||||
if (values.size() == 0) {
|
|
||||||
checkBox.setChecked(false);
|
|
||||||
} else {
|
|
||||||
checkBox.setChecked(Boolean.parseBoolean(values.get(0)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean validates() {
|
|
||||||
if (checkBox.isChecked() || !field.isRequired()) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
checkBox.setError(context.getString(R.string.this_field_is_required));
|
|
||||||
checkBox.requestFocus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean edited() {
|
|
||||||
if (field.getValues().size() == 0) {
|
|
||||||
return checkBox.isChecked();
|
|
||||||
} else {
|
|
||||||
return super.edited();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getLayoutResource() {
|
|
||||||
return R.layout.form_boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void setReadOnly(boolean readOnly) {
|
|
||||||
checkBox.setEnabled(!readOnly);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package eu.siacs.conversations.ui.forms;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import java.util.Hashtable;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.forms.Field;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class FormFieldFactory {
|
|
||||||
|
|
||||||
private static final Hashtable<String, Class> typeTable = new Hashtable<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
typeTable.put("text-single", FormTextFieldWrapper.class);
|
|
||||||
typeTable.put("text-multi", FormTextFieldWrapper.class);
|
|
||||||
typeTable.put("text-private", FormTextFieldWrapper.class);
|
|
||||||
typeTable.put("jid-single", FormJidSingleFieldWrapper.class);
|
|
||||||
typeTable.put("boolean", FormBooleanFieldWrapper.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static FormFieldWrapper createFromField(Context context, Field field) {
|
|
||||||
Class clazz = typeTable.get(field.getType());
|
|
||||||
if (clazz == null) {
|
|
||||||
clazz = FormTextFieldWrapper.class;
|
|
||||||
}
|
|
||||||
return FormFieldWrapper.createFromField(clazz, context, field);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
package eu.siacs.conversations.ui.forms;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.text.SpannableString;
|
|
||||||
import android.text.style.ForegroundColorSpan;
|
|
||||||
import android.text.style.StyleSpan;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.ui.util.StyledAttributes;
|
|
||||||
import eu.siacs.conversations.xmpp.forms.Field;
|
|
||||||
|
|
||||||
public abstract class FormFieldWrapper {
|
|
||||||
|
|
||||||
protected final Context context;
|
|
||||||
protected final Field field;
|
|
||||||
protected final View view;
|
|
||||||
OnFormFieldValuesEdited onFormFieldValuesEditedListener;
|
|
||||||
|
|
||||||
FormFieldWrapper(Context context, Field field) {
|
|
||||||
this.context = context;
|
|
||||||
this.field = field;
|
|
||||||
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
this.view = inflater.inflate(getLayoutResource(), null);
|
|
||||||
String label = field.getLabel();
|
|
||||||
if (label == null) {
|
|
||||||
label = field.getFieldName();
|
|
||||||
}
|
|
||||||
setLabel(label, field.isRequired());
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void submit() {
|
|
||||||
this.field.setValues(getValues());
|
|
||||||
}
|
|
||||||
|
|
||||||
public final View getView() {
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void setLabel(String label, boolean required);
|
|
||||||
|
|
||||||
abstract List<String> getValues();
|
|
||||||
|
|
||||||
protected abstract void setValues(List<String> values);
|
|
||||||
|
|
||||||
abstract boolean validates();
|
|
||||||
|
|
||||||
abstract protected int getLayoutResource();
|
|
||||||
|
|
||||||
abstract void setReadOnly(boolean readOnly);
|
|
||||||
|
|
||||||
protected SpannableString createSpannableLabelString(String label, boolean required) {
|
|
||||||
SpannableString spannableString = new SpannableString(label + (required ? " *" : ""));
|
|
||||||
if (required) {
|
|
||||||
int start = label.length();
|
|
||||||
int end = label.length() + 2;
|
|
||||||
spannableString.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), start, end, 0);
|
|
||||||
spannableString.setSpan(new ForegroundColorSpan(StyledAttributes.getColor(context, androidx.appcompat.R.attr.colorAccent)), start, end, 0);
|
|
||||||
}
|
|
||||||
return spannableString;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void invokeOnFormFieldValuesEdited() {
|
|
||||||
if (this.onFormFieldValuesEditedListener != null) {
|
|
||||||
this.onFormFieldValuesEditedListener.onFormFieldValuesEdited();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean edited() {
|
|
||||||
return !field.getValues().equals(getValues());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnFormFieldValuesEditedListener(OnFormFieldValuesEdited listener) {
|
|
||||||
this.onFormFieldValuesEditedListener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static <F extends FormFieldWrapper> FormFieldWrapper createFromField(Class<F> c, Context context, Field field) {
|
|
||||||
try {
|
|
||||||
F fieldWrapper = c.getDeclaredConstructor(Context.class, Field.class).newInstance(context,field);
|
|
||||||
fieldWrapper.setValues(field.getValues());
|
|
||||||
return fieldWrapper;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnFormFieldValuesEdited {
|
|
||||||
void onFormFieldValuesEdited();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
package eu.siacs.conversations.ui.forms;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.text.InputType;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import eu.siacs.conversations.xmpp.forms.Field;
|
|
||||||
|
|
||||||
public class FormJidSingleFieldWrapper extends FormTextFieldWrapper {
|
|
||||||
|
|
||||||
protected FormJidSingleFieldWrapper(Context context, Field field) {
|
|
||||||
super(context, field);
|
|
||||||
editText.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
|
||||||
editText.setHint(R.string.account_settings_example_jabber_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean validates() {
|
|
||||||
String value = getValue();
|
|
||||||
if (!value.isEmpty()) {
|
|
||||||
try {
|
|
||||||
Jid.of(value);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
editText.setError(context.getString(R.string.invalid_jid));
|
|
||||||
editText.requestFocus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.validates();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setValues(List<String> values) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
for(String value : values) {
|
|
||||||
builder.append(value);
|
|
||||||
}
|
|
||||||
editText.setText(builder.toString());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
package eu.siacs.conversations.ui.forms;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.InputType;
|
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
|
||||||
import eu.siacs.conversations.xmpp.forms.Field;
|
|
||||||
|
|
||||||
public class FormTextFieldWrapper extends FormFieldWrapper {
|
|
||||||
|
|
||||||
protected EditText editText;
|
|
||||||
|
|
||||||
protected FormTextFieldWrapper(Context context, Field field) {
|
|
||||||
super(context, field);
|
|
||||||
editText = view.findViewById(R.id.field);
|
|
||||||
editText.setSingleLine(!"text-multi".equals(field.getType()));
|
|
||||||
if ("text-private".equals(field.getType())) {
|
|
||||||
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
|
||||||
}
|
|
||||||
editText.addTextChangedListener(new TextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
editText.setError(null);
|
|
||||||
invokeOnFormFieldValuesEdited();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setLabel(String label, boolean required) {
|
|
||||||
TextView textView = view.findViewById(R.id.label);
|
|
||||||
textView.setText(createSpannableLabelString(label, required));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getValue() {
|
|
||||||
return editText.getText().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getValues() {
|
|
||||||
List<String> values = new ArrayList<>();
|
|
||||||
for (String line : getValue().split("\\n")) {
|
|
||||||
if (line.length() > 0) {
|
|
||||||
values.add(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setValues(List<String> values) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
for(int i = 0; i < values.size(); ++i) {
|
|
||||||
builder.append(values.get(i));
|
|
||||||
if (i < values.size() - 1 && "text-multi".equals(field.getType())) {
|
|
||||||
builder.append("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
editText.setText(builder.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean validates() {
|
|
||||||
if (getValue().trim().length() > 0 || !field.isRequired()) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
editText.setError(context.getString(R.string.this_field_is_required));
|
|
||||||
editText.requestFocus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getLayoutResource() {
|
|
||||||
return R.layout.form_text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void setReadOnly(boolean readOnly) {
|
|
||||||
editText.setEnabled(!readOnly);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
package eu.siacs.conversations.ui.forms;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.forms.Data;
|
|
||||||
import eu.siacs.conversations.xmpp.forms.Field;
|
|
||||||
|
|
||||||
public class FormWrapper {
|
|
||||||
|
|
||||||
private final LinearLayout layout;
|
|
||||||
|
|
||||||
private final Data form;
|
|
||||||
|
|
||||||
private final List<FormFieldWrapper> fieldWrappers = new ArrayList<>();
|
|
||||||
|
|
||||||
private FormWrapper(Context context, LinearLayout linearLayout, Data form) {
|
|
||||||
this.form = form;
|
|
||||||
this.layout = linearLayout;
|
|
||||||
this.layout.removeAllViews();
|
|
||||||
for(Field field : form.getFields()) {
|
|
||||||
FormFieldWrapper fieldWrapper = FormFieldFactory.createFromField(context,field);
|
|
||||||
if (fieldWrapper != null) {
|
|
||||||
layout.addView(fieldWrapper.getView());
|
|
||||||
fieldWrappers.add(fieldWrapper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Data submit() {
|
|
||||||
for(FormFieldWrapper fieldWrapper : fieldWrappers) {
|
|
||||||
fieldWrapper.submit();
|
|
||||||
}
|
|
||||||
this.form.submit();
|
|
||||||
return this.form;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean validates() {
|
|
||||||
boolean validates = true;
|
|
||||||
for(FormFieldWrapper fieldWrapper : fieldWrappers) {
|
|
||||||
validates &= fieldWrapper.validates();
|
|
||||||
}
|
|
||||||
return validates;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnFormFieldValuesEditedListener(FormFieldWrapper.OnFormFieldValuesEdited listener) {
|
|
||||||
for(FormFieldWrapper fieldWrapper : fieldWrappers) {
|
|
||||||
fieldWrapper.setOnFormFieldValuesEditedListener(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReadOnly(boolean b) {
|
|
||||||
for(FormFieldWrapper fieldWrapper : fieldWrappers) {
|
|
||||||
fieldWrapper.setReadOnly(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean edited() {
|
|
||||||
boolean edited = false;
|
|
||||||
for(FormFieldWrapper fieldWrapper : fieldWrappers) {
|
|
||||||
edited |= fieldWrapper.edited();
|
|
||||||
}
|
|
||||||
return edited;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FormWrapper createInLayout(Context context, LinearLayout layout, Data form) {
|
|
||||||
return new FormWrapper(context, layout, form);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -22,11 +22,6 @@ import android.widget.TextView;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
|
@ -36,7 +31,17 @@ import eu.siacs.conversations.ui.adapter.MessageAdapter;
|
||||||
import eu.siacs.conversations.ui.util.PendingItem;
|
import eu.siacs.conversations.ui.util.PendingItem;
|
||||||
import eu.siacs.conversations.utils.WeakReferenceSet;
|
import eu.siacs.conversations.utils.WeakReferenceSet;
|
||||||
|
|
||||||
public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompletionListener, SeekBar.OnSeekBarChangeListener, Runnable, SensorEventListener {
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
public class AudioPlayer
|
||||||
|
implements View.OnClickListener,
|
||||||
|
MediaPlayer.OnCompletionListener,
|
||||||
|
SeekBar.OnSeekBarChangeListener,
|
||||||
|
Runnable,
|
||||||
|
SensorEventListener {
|
||||||
|
|
||||||
private static final int REFRESH_INTERVAL = 250;
|
private static final int REFRESH_INTERVAL = 250;
|
||||||
private static final Object LOCK = new Object();
|
private static final Object LOCK = new Object();
|
||||||
|
@ -57,33 +62,43 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
final Context context = adapter.getContext();
|
final Context context = adapter.getContext();
|
||||||
this.messageAdapter = adapter;
|
this.messageAdapter = adapter;
|
||||||
this.sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
|
this.sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
|
||||||
this.proximitySensor = this.sensorManager == null ? null : this.sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
|
this.proximitySensor =
|
||||||
|
this.sensorManager == null
|
||||||
|
? null
|
||||||
|
: this.sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
|
||||||
initializeProximityWakeLock(context);
|
initializeProximityWakeLock(context);
|
||||||
synchronized (AudioPlayer.LOCK) {
|
synchronized (AudioPlayer.LOCK) {
|
||||||
if (AudioPlayer.player != null) {
|
if (AudioPlayer.player != null) {
|
||||||
AudioPlayer.player.setOnCompletionListener(this);
|
AudioPlayer.player.setOnCompletionListener(this);
|
||||||
if (AudioPlayer.player.isPlaying() && sensorManager != null) {
|
if (AudioPlayer.player.isPlaying() && sensorManager != null) {
|
||||||
sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
|
sensorManager.registerListener(
|
||||||
|
this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formatTime(int ms) {
|
private static String formatTime(int ms) {
|
||||||
return String.format(Locale.ENGLISH, "%d:%02d", ms / 60000, Math.min(Math.round((ms % 60000) / 1000f), 59));
|
return String.format(
|
||||||
|
Locale.ENGLISH,
|
||||||
|
"%d:%02d",
|
||||||
|
ms / 60000,
|
||||||
|
Math.min(Math.round((ms % 60000) / 1000f), 59));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeProximityWakeLock(Context context) {
|
private void initializeProximityWakeLock(Context context) {
|
||||||
if (Build.VERSION.SDK_INT >= 21) {
|
synchronized (AudioPlayer.LOCK) {
|
||||||
synchronized (AudioPlayer.LOCK) {
|
if (AudioPlayer.wakeLock == null) {
|
||||||
if (AudioPlayer.wakeLock == null) {
|
final PowerManager powerManager =
|
||||||
final PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
(PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||||
AudioPlayer.wakeLock = powerManager == null ? null : powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, AudioPlayer.class.getSimpleName());
|
AudioPlayer.wakeLock =
|
||||||
AudioPlayer.wakeLock.setReferenceCounted(false);
|
powerManager == null
|
||||||
}
|
? null
|
||||||
|
: powerManager.newWakeLock(
|
||||||
|
PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,
|
||||||
|
AudioPlayer.class.getSimpleName());
|
||||||
|
AudioPlayer.wakeLock.setReferenceCounted(false);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
AudioPlayer.wakeLock = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,41 +107,39 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
audioPlayer.setTag(message);
|
audioPlayer.setTag(message);
|
||||||
if (init(ViewHolder.get(audioPlayer), message)) {
|
if (init(ViewHolder.get(audioPlayer), message)) {
|
||||||
this.audioPlayerLayouts.addWeakReferenceTo(audioPlayer);
|
this.audioPlayerLayouts.addWeakReferenceTo(audioPlayer);
|
||||||
executor.execute(()-> this.stopRefresher(true));
|
executor.execute(() -> this.stopRefresher(true));
|
||||||
} else {
|
} else {
|
||||||
this.audioPlayerLayouts.removeWeakReferenceTo(audioPlayer);
|
this.audioPlayerLayouts.removeWeakReferenceTo(audioPlayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean init(ViewHolder viewHolder, Message message) {
|
private boolean init(final ViewHolder viewHolder, final Message message) {
|
||||||
if (viewHolder.darkBackground) {
|
MessageAdapter.setTextColor(viewHolder.runtime, viewHolder.bubbleColor);
|
||||||
viewHolder.runtime.setTextAppearance(this.messageAdapter.getContext(), R.style.TextAppearance_Conversations_Caption_OnDark);
|
|
||||||
} else {
|
|
||||||
viewHolder.runtime.setTextAppearance(this.messageAdapter.getContext(), R.style.TextAppearance_Conversations_Caption);
|
|
||||||
}
|
|
||||||
viewHolder.progress.setOnSeekBarChangeListener(this);
|
viewHolder.progress.setOnSeekBarChangeListener(this);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
final ColorStateList color =
|
||||||
ColorStateList color = ContextCompat.getColorStateList(messageAdapter.getContext(), viewHolder.darkBackground ? R.color.white70 : R.color.green700_desaturated);
|
MessageAdapter.bubbleToOnSurfaceColorStateList(
|
||||||
viewHolder.progress.setThumbTintList(color);
|
viewHolder.progress, viewHolder.bubbleColor);
|
||||||
viewHolder.progress.setProgressTintList(color);
|
viewHolder.progress.setThumbTintList(color);
|
||||||
}
|
viewHolder.progress.setProgressTintList(color);
|
||||||
viewHolder.playPause.setAlpha(viewHolder.darkBackground ? 0.7f : 0.57f);
|
|
||||||
viewHolder.playPause.setOnClickListener(this);
|
viewHolder.playPause.setOnClickListener(this);
|
||||||
final Context context = viewHolder.playPause.getContext();
|
final Context context = viewHolder.playPause.getContext();
|
||||||
if (message == currentlyPlayingMessage) {
|
if (message == currentlyPlayingMessage) {
|
||||||
if (AudioPlayer.player != null && AudioPlayer.player.isPlaying()) {
|
if (AudioPlayer.player != null && AudioPlayer.player.isPlaying()) {
|
||||||
viewHolder.playPause.setImageResource(viewHolder.darkBackground ? R.drawable.ic_pause_white_36dp : R.drawable.ic_pause_black_36dp);
|
viewHolder.playPause.setImageResource(R.drawable.ic_pause_24dp);
|
||||||
|
MessageAdapter.setImageTint(viewHolder.playPause, viewHolder.bubbleColor);
|
||||||
viewHolder.playPause.setContentDescription(context.getString(R.string.pause_audio));
|
viewHolder.playPause.setContentDescription(context.getString(R.string.pause_audio));
|
||||||
viewHolder.progress.setEnabled(true);
|
viewHolder.progress.setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
viewHolder.playPause.setContentDescription(context.getString(R.string.play_audio));
|
viewHolder.playPause.setContentDescription(context.getString(R.string.play_audio));
|
||||||
viewHolder.playPause.setImageResource(viewHolder.darkBackground ? R.drawable.ic_play_arrow_white_36dp : R.drawable.ic_play_arrow_black_36dp);
|
viewHolder.playPause.setImageResource(R.drawable.ic_play_arrow_24dp);
|
||||||
|
MessageAdapter.setImageTint(viewHolder.playPause, viewHolder.bubbleColor);
|
||||||
viewHolder.progress.setEnabled(false);
|
viewHolder.progress.setEnabled(false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
viewHolder.playPause.setImageResource(viewHolder.darkBackground ? R.drawable.ic_play_arrow_white_36dp : R.drawable.ic_play_arrow_black_36dp);
|
viewHolder.playPause.setImageResource(R.drawable.ic_play_arrow_24dp);
|
||||||
|
MessageAdapter.setImageTint(viewHolder.playPause, viewHolder.bubbleColor);
|
||||||
viewHolder.playPause.setContentDescription(context.getString(R.string.play_audio));
|
viewHolder.playPause.setContentDescription(context.getString(R.string.play_audio));
|
||||||
viewHolder.runtime.setText(formatTime(message.getFileParams().runtime));
|
viewHolder.runtime.setText(formatTime(message.getFileParams().runtime));
|
||||||
viewHolder.progress.setProgress(0);
|
viewHolder.progress.setProgress(0);
|
||||||
|
@ -145,9 +158,16 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startStop(ImageButton playPause) {
|
private void startStop(ImageButton playPause) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU && ContextCompat.checkSelfPermission(messageAdapter.getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU
|
||||||
|
&& ContextCompat.checkSelfPermission(
|
||||||
|
messageAdapter.getActivity(),
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
pendingOnClickView.push(new WeakReference<>(playPause));
|
pendingOnClickView.push(new WeakReference<>(playPause));
|
||||||
ActivityCompat.requestPermissions(messageAdapter.getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, ConversationsActivity.REQUEST_PLAY_PAUSE);
|
ActivityCompat.requestPermissions(
|
||||||
|
messageAdapter.getActivity(),
|
||||||
|
new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
|
ConversationsActivity.REQUEST_PLAY_PAUSE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
initializeProximityWakeLock(playPause.getContext());
|
initializeProximityWakeLock(playPause.getContext());
|
||||||
|
@ -163,13 +183,13 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
|
|
||||||
private boolean playPauseCurrent(final ViewHolder viewHolder) {
|
private boolean playPauseCurrent(final ViewHolder viewHolder) {
|
||||||
final Context context = viewHolder.playPause.getContext();
|
final Context context = viewHolder.playPause.getContext();
|
||||||
viewHolder.playPause.setAlpha(viewHolder.darkBackground ? 0.7f : 0.57f);
|
|
||||||
if (player.isPlaying()) {
|
if (player.isPlaying()) {
|
||||||
viewHolder.progress.setEnabled(false);
|
viewHolder.progress.setEnabled(false);
|
||||||
player.pause();
|
player.pause();
|
||||||
messageAdapter.flagScreenOff();
|
messageAdapter.flagScreenOff();
|
||||||
releaseProximityWakeLock();
|
releaseProximityWakeLock();
|
||||||
viewHolder.playPause.setImageResource(viewHolder.darkBackground ? R.drawable.ic_play_arrow_white_36dp : R.drawable.ic_play_arrow_black_36dp);
|
viewHolder.playPause.setImageResource(R.drawable.ic_play_arrow_24dp);
|
||||||
|
MessageAdapter.setImageTint(viewHolder.playPause,viewHolder.bubbleColor);
|
||||||
viewHolder.playPause.setContentDescription(context.getString(R.string.play_audio));
|
viewHolder.playPause.setContentDescription(context.getString(R.string.play_audio));
|
||||||
} else {
|
} else {
|
||||||
viewHolder.progress.setEnabled(true);
|
viewHolder.progress.setEnabled(true);
|
||||||
|
@ -177,7 +197,8 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
messageAdapter.flagScreenOn();
|
messageAdapter.flagScreenOn();
|
||||||
acquireProximityWakeLock();
|
acquireProximityWakeLock();
|
||||||
this.stopRefresher(true);
|
this.stopRefresher(true);
|
||||||
viewHolder.playPause.setImageResource(viewHolder.darkBackground ? R.drawable.ic_pause_white_36dp : R.drawable.ic_pause_black_36dp);
|
viewHolder.playPause.setImageResource(R.drawable.ic_pause_24dp);
|
||||||
|
MessageAdapter.setImageTint(viewHolder.playPause,viewHolder.bubbleColor);
|
||||||
viewHolder.playPause.setContentDescription(context.getString(R.string.pause_audio));
|
viewHolder.playPause.setContentDescription(context.getString(R.string.pause_audio));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -193,19 +214,24 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
AudioPlayer.player = new MediaPlayer();
|
AudioPlayer.player = new MediaPlayer();
|
||||||
try {
|
try {
|
||||||
AudioPlayer.currentlyPlayingMessage = message;
|
AudioPlayer.currentlyPlayingMessage = message;
|
||||||
AudioPlayer.player.setAudioStreamType(earpiece ? AudioManager.STREAM_VOICE_CALL : AudioManager.STREAM_MUSIC);
|
AudioPlayer.player.setAudioStreamType(
|
||||||
AudioPlayer.player.setDataSource(messageAdapter.getFileBackend().getFile(message).getAbsolutePath());
|
earpiece ? AudioManager.STREAM_VOICE_CALL : AudioManager.STREAM_MUSIC);
|
||||||
|
AudioPlayer.player.setDataSource(
|
||||||
|
messageAdapter.getFileBackend().getFile(message).getAbsolutePath());
|
||||||
AudioPlayer.player.setOnCompletionListener(this);
|
AudioPlayer.player.setOnCompletionListener(this);
|
||||||
AudioPlayer.player.prepare();
|
AudioPlayer.player.prepare();
|
||||||
AudioPlayer.player.start();
|
AudioPlayer.player.start();
|
||||||
messageAdapter.flagScreenOn();
|
messageAdapter.flagScreenOn();
|
||||||
acquireProximityWakeLock();
|
acquireProximityWakeLock();
|
||||||
viewHolder.progress.setEnabled(true);
|
viewHolder.progress.setEnabled(true);
|
||||||
viewHolder.playPause.setImageResource(viewHolder.darkBackground ? R.drawable.ic_pause_white_36dp : R.drawable.ic_pause_black_36dp);
|
viewHolder.playPause.setImageResource(R.drawable.ic_pause_24dp);
|
||||||
viewHolder.playPause.setContentDescription(viewHolder.playPause.getContext().getString(R.string.pause_audio));
|
MessageAdapter.setImageTint(viewHolder.playPause,viewHolder.bubbleColor);
|
||||||
sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
|
viewHolder.playPause.setContentDescription(
|
||||||
|
viewHolder.playPause.getContext().getString(R.string.pause_audio));
|
||||||
|
sensorManager.registerListener(
|
||||||
|
this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (final Exception e) {
|
||||||
messageAdapter.flagScreenOff();
|
messageAdapter.flagScreenOff();
|
||||||
releaseProximityWakeLock();
|
releaseProximityWakeLock();
|
||||||
AudioPlayer.currentlyPlayingMessage = null;
|
AudioPlayer.currentlyPlayingMessage = null;
|
||||||
|
@ -251,14 +277,16 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetPlayerUi(RelativeLayout audioPlayer) {
|
private void resetPlayerUi(final RelativeLayout audioPlayer) {
|
||||||
if (audioPlayer == null) {
|
if (audioPlayer == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final ViewHolder viewHolder = ViewHolder.get(audioPlayer);
|
final ViewHolder viewHolder = ViewHolder.get(audioPlayer);
|
||||||
final Message message = (Message) audioPlayer.getTag();
|
final Message message = (Message) audioPlayer.getTag();
|
||||||
viewHolder.playPause.setContentDescription(viewHolder.playPause.getContext().getString(R.string.play_audio));
|
viewHolder.playPause.setContentDescription(
|
||||||
viewHolder.playPause.setImageResource(viewHolder.darkBackground ? R.drawable.ic_play_arrow_white_36dp : R.drawable.ic_play_arrow_black_36dp);
|
viewHolder.playPause.getContext().getString(R.string.play_audio));
|
||||||
|
viewHolder.playPause.setImageResource(R.drawable.ic_play_arrow_24dp);
|
||||||
|
MessageAdapter.setImageTint(viewHolder.playPause,viewHolder.bubbleColor);
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
viewHolder.runtime.setText(formatTime(message.getFileParams().runtime));
|
viewHolder.runtime.setText(formatTime(message.getFileParams().runtime));
|
||||||
}
|
}
|
||||||
|
@ -297,14 +325,10 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
synchronized (AudioPlayer.LOCK) {
|
synchronized (AudioPlayer.LOCK) {
|
||||||
|
@ -361,7 +385,8 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
} else {
|
} else {
|
||||||
viewHolder.progress.setProgress(current * 100 / duration);
|
viewHolder.progress.setProgress(current * 100 / duration);
|
||||||
}
|
}
|
||||||
viewHolder.runtime.setText(String.format("%s / %s", formatTime(current), formatTime(duration)));
|
viewHolder.runtime.setText(
|
||||||
|
String.format("%s / %s", formatTime(current), formatTime(duration)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +416,11 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
try {
|
try {
|
||||||
ViewHolder currentViewHolder = getCurrentViewHolder();
|
ViewHolder currentViewHolder = getCurrentViewHolder();
|
||||||
if (currentViewHolder != null) {
|
if (currentViewHolder != null) {
|
||||||
play(currentViewHolder, currentlyPlayingMessage, streamType == AudioManager.STREAM_VOICE_CALL, progress);
|
play(
|
||||||
|
currentViewHolder,
|
||||||
|
currentlyPlayingMessage,
|
||||||
|
streamType == AudioManager.STREAM_VOICE_CALL,
|
||||||
|
progress);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.w(Config.LOGTAG, e);
|
Log.w(Config.LOGTAG, e);
|
||||||
|
@ -401,8 +430,7 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAccuracyChanged(Sensor sensor, int i) {
|
public void onAccuracyChanged(Sensor sensor, int i) {}
|
||||||
}
|
|
||||||
|
|
||||||
private void acquireProximityWakeLock() {
|
private void acquireProximityWakeLock() {
|
||||||
synchronized (AudioPlayer.LOCK) {
|
synchronized (AudioPlayer.LOCK) {
|
||||||
|
@ -435,22 +463,24 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
|
||||||
private TextView runtime;
|
private TextView runtime;
|
||||||
private SeekBar progress;
|
private SeekBar progress;
|
||||||
private ImageButton playPause;
|
private ImageButton playPause;
|
||||||
private boolean darkBackground = false;
|
private MessageAdapter.BubbleColor bubbleColor = MessageAdapter.BubbleColor.SURFACE;
|
||||||
|
|
||||||
public static ViewHolder get(RelativeLayout audioPlayer) {
|
public static ViewHolder get(final RelativeLayout audioPlayer) {
|
||||||
ViewHolder viewHolder = (ViewHolder) audioPlayer.getTag(R.id.TAG_AUDIO_PLAYER_VIEW_HOLDER);
|
final var existingViewHolder =
|
||||||
if (viewHolder == null) {
|
(ViewHolder) audioPlayer.getTag(R.id.TAG_AUDIO_PLAYER_VIEW_HOLDER);
|
||||||
viewHolder = new ViewHolder();
|
if (existingViewHolder != null) {
|
||||||
viewHolder.runtime = audioPlayer.findViewById(R.id.runtime);
|
return existingViewHolder;
|
||||||
viewHolder.progress = audioPlayer.findViewById(R.id.progress);
|
|
||||||
viewHolder.playPause = audioPlayer.findViewById(R.id.play_pause);
|
|
||||||
audioPlayer.setTag(R.id.TAG_AUDIO_PLAYER_VIEW_HOLDER, viewHolder);
|
|
||||||
}
|
}
|
||||||
|
final ViewHolder viewHolder = new ViewHolder();
|
||||||
|
viewHolder.runtime = audioPlayer.findViewById(R.id.runtime);
|
||||||
|
viewHolder.progress = audioPlayer.findViewById(R.id.progress);
|
||||||
|
viewHolder.playPause = audioPlayer.findViewById(R.id.play_pause);
|
||||||
|
audioPlayer.setTag(R.id.TAG_AUDIO_PLAYER_VIEW_HOLDER, viewHolder);
|
||||||
return viewHolder;
|
return viewHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDarkBackground(boolean darkBackground) {
|
public void setBubbleColor(final MessageAdapter.BubbleColor bubbleColor) {
|
||||||
this.darkBackground = darkBackground;
|
this.bubbleColor = bubbleColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
package eu.siacs.conversations.ui.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
public class ActionBarUtil {
|
|
||||||
|
|
||||||
public static void resetActionBarOnClickListeners(@NonNull View view) {
|
|
||||||
final View title = findActionBarTitle(view);
|
|
||||||
final View subtitle = findActionBarSubTitle(view);
|
|
||||||
if (title != null) {
|
|
||||||
title.setOnClickListener(null);
|
|
||||||
}
|
|
||||||
if (subtitle != null) {
|
|
||||||
subtitle.setOnClickListener(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setActionBarOnClickListener(@NonNull View view,
|
|
||||||
@NonNull final View.OnClickListener onClickListener) {
|
|
||||||
final View title = findActionBarTitle(view);
|
|
||||||
final View subtitle = findActionBarSubTitle(view);
|
|
||||||
if (title != null) {
|
|
||||||
title.setOnClickListener(onClickListener);
|
|
||||||
}
|
|
||||||
if (subtitle != null) {
|
|
||||||
subtitle.setOnClickListener(onClickListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @Nullable View findActionBarTitle(@NonNull View root) {
|
|
||||||
return findActionBarItem(root, "action_bar_title", "mTitleTextView");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @Nullable
|
|
||||||
View findActionBarSubTitle(@NonNull View root) {
|
|
||||||
return findActionBarItem(root, "action_bar_subtitle", "mSubtitleTextView");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @Nullable View findActionBarItem(@NonNull View root,
|
|
||||||
@NonNull String resourceName,
|
|
||||||
@NonNull String toolbarFieldName) {
|
|
||||||
View result = findViewSupportOrAndroid(root, resourceName);
|
|
||||||
|
|
||||||
if (result == null) {
|
|
||||||
View actionBar = findViewSupportOrAndroid(root, "action_bar");
|
|
||||||
if (actionBar != null) {
|
|
||||||
result = reflectiveRead(actionBar, toolbarFieldName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (result == null && root.getClass().getName().endsWith("widget.Toolbar")) {
|
|
||||||
result = reflectiveRead(root, toolbarFieldName);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
|
||||||
private static @Nullable View findViewSupportOrAndroid(@NonNull View root,
|
|
||||||
@NonNull String resourceName) {
|
|
||||||
Context context = root.getContext();
|
|
||||||
View result = null;
|
|
||||||
if (result == null) {
|
|
||||||
int supportID = context.getResources().getIdentifier(resourceName, "id", context.getPackageName());
|
|
||||||
result = root.findViewById(supportID);
|
|
||||||
}
|
|
||||||
if (result == null) {
|
|
||||||
int androidID = context.getResources().getIdentifier(resourceName, "id", "android");
|
|
||||||
result = root.findViewById(androidID);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static <T> T reflectiveRead(@NonNull Object object, @NonNull String fieldName) {
|
|
||||||
try {
|
|
||||||
Field field = object.getClass().getDeclaredField(fieldName);
|
|
||||||
field.setAccessible(true);
|
|
||||||
return (T) field.get(object);
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -38,6 +38,9 @@ import android.os.Parcelable;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.entities.Message;
|
||||||
|
import eu.siacs.conversations.utils.MimeUtils;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -46,9 +49,6 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import eu.siacs.conversations.utils.Compatibility;
|
|
||||||
import eu.siacs.conversations.utils.MimeUtils;
|
|
||||||
|
|
||||||
public class Attachment implements Parcelable {
|
public class Attachment implements Parcelable {
|
||||||
|
|
||||||
Attachment(Parcel in) {
|
Attachment(Parcel in) {
|
||||||
|
@ -71,17 +71,18 @@ public class Attachment implements Parcelable {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<Attachment> CREATOR = new Creator<Attachment>() {
|
public static final Creator<Attachment> CREATOR =
|
||||||
@Override
|
new Creator<Attachment>() {
|
||||||
public Attachment createFromParcel(Parcel in) {
|
@Override
|
||||||
return new Attachment(in);
|
public Attachment createFromParcel(Parcel in) {
|
||||||
}
|
return new Attachment(in);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Attachment[] newArray(int size) {
|
public Attachment[] newArray(int size) {
|
||||||
return new Attachment[size];
|
return new Attachment[size];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public String getMime() {
|
public String getMime() {
|
||||||
return mime;
|
return mime;
|
||||||
|
@ -103,7 +104,10 @@ public class Attachment implements Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
FILE, IMAGE, LOCATION, RECORDING
|
FILE,
|
||||||
|
IMAGE,
|
||||||
|
LOCATION,
|
||||||
|
RECORDING
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Uri uri;
|
private final Uri uri;
|
||||||
|
@ -125,8 +129,8 @@ public class Attachment implements Parcelable {
|
||||||
this.uuid = UUID.randomUUID();
|
this.uuid = UUID.randomUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean canBeSendInband(final List<Attachment> attachments) {
|
public static boolean canBeSendInBand(final List<Attachment> attachments) {
|
||||||
for (Attachment attachment : attachments) {
|
for (final Attachment attachment : attachments) {
|
||||||
if (attachment.type != Type.LOCATION) {
|
if (attachment.type != Type.LOCATION) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -135,10 +139,30 @@ public class Attachment implements Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Attachment> of(final Context context, Uri uri, Type type) {
|
public static List<Attachment> of(final Context context, Uri uri, Type type) {
|
||||||
final String mime = type == Type.LOCATION ? null : MimeUtils.guessMimeTypeFromUri(context, uri);
|
final String mime =
|
||||||
|
type == Type.LOCATION ? null : MimeUtils.guessMimeTypeFromUri(context, uri);
|
||||||
return Collections.singletonList(new Attachment(uri, type, mime));
|
return Collections.singletonList(new Attachment(uri, type, mime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Attachment of(final Message message) {
|
||||||
|
final UUID uuid = UUID.fromString(message.getUuid());
|
||||||
|
if (message.isGeoUri()) {
|
||||||
|
return new Attachment(uuid, Uri.EMPTY, Type.LOCATION, null);
|
||||||
|
}
|
||||||
|
final String mime = message.getMimeType();
|
||||||
|
if (MimeUtils.AMBIGUOUS_CONTAINER_FORMATS.contains(mime)) {
|
||||||
|
final Message.FileParams fileParams = message.getFileParams();
|
||||||
|
if (fileParams.width > 0 && fileParams.height > 0) {
|
||||||
|
return new Attachment(uuid, Uri.EMPTY, Type.FILE, "video/*");
|
||||||
|
} else if (fileParams.runtime > 0) {
|
||||||
|
return new Attachment(uuid, Uri.EMPTY, Type.FILE, "audio/*");
|
||||||
|
} else {
|
||||||
|
return new Attachment(uuid, Uri.EMPTY, Type.FILE, "application/octet-stream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Attachment(uuid, Uri.EMPTY, Type.FILE, mime);
|
||||||
|
}
|
||||||
|
|
||||||
public static List<Attachment> of(final Context context, List<Uri> uris, final String type) {
|
public static List<Attachment> of(final Context context, List<Uri> uris, final String type) {
|
||||||
final List<Attachment> attachments = new ArrayList<>();
|
final List<Attachment> attachments = new ArrayList<>();
|
||||||
for (final Uri uri : uris) {
|
for (final Uri uri : uris) {
|
||||||
|
@ -146,16 +170,25 @@ public class Attachment implements Parcelable {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final String mime = MimeUtils.guessMimeTypeFromUriAndMime(context, uri, type);
|
final String mime = MimeUtils.guessMimeTypeFromUriAndMime(context, uri, type);
|
||||||
attachments.add(new Attachment(uri, mime != null && isImage(mime) ? Type.IMAGE : Type.FILE, mime));
|
attachments.add(
|
||||||
|
new Attachment(
|
||||||
|
uri, mime != null && isImage(mime) ? Type.IMAGE : Type.FILE, mime));
|
||||||
}
|
}
|
||||||
return attachments;
|
return attachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Attachment of(UUID uuid, final File file, String mime) {
|
public static Attachment of(UUID uuid, final File file, String mime) {
|
||||||
return new Attachment(uuid, Uri.fromFile(file), mime != null && (isImage(mime) || mime.startsWith("video/")) ? Type.IMAGE : Type.FILE, mime);
|
return new Attachment(
|
||||||
|
uuid,
|
||||||
|
Uri.fromFile(file),
|
||||||
|
mime != null && (isImage(mime) || mime.startsWith("video/"))
|
||||||
|
? Type.IMAGE
|
||||||
|
: Type.FILE,
|
||||||
|
mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Attachment> extractAttachments(final Context context, final Intent intent, Type type) {
|
public static List<Attachment> extractAttachments(
|
||||||
|
final Context context, final Intent intent, Type type) {
|
||||||
List<Attachment> uris = new ArrayList<>();
|
List<Attachment> uris = new ArrayList<>();
|
||||||
if (intent == null) {
|
if (intent == null) {
|
||||||
return uris;
|
return uris;
|
||||||
|
@ -167,7 +200,8 @@ public class Attachment implements Parcelable {
|
||||||
if (clipData != null) {
|
if (clipData != null) {
|
||||||
for (int i = 0; i < clipData.getItemCount(); ++i) {
|
for (int i = 0; i < clipData.getItemCount(); ++i) {
|
||||||
final Uri uri = clipData.getItemAt(i).getUri();
|
final Uri uri = clipData.getItemAt(i).getUri();
|
||||||
final String mime = MimeUtils.guessMimeTypeFromUriAndMime(context, uri, contentType);
|
final String mime =
|
||||||
|
MimeUtils.guessMimeTypeFromUriAndMime(context, uri, contentType);
|
||||||
uris.add(new Attachment(uri, type, mime));
|
uris.add(new Attachment(uri, type, mime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,13 +213,12 @@ public class Attachment implements Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean renderThumbnail() {
|
public boolean renderThumbnail() {
|
||||||
return type == Type.IMAGE || (type == Type.FILE && mime != null && renderFileThumbnail(mime));
|
return type == Type.IMAGE
|
||||||
|
|| (type == Type.FILE && mime != null && renderFileThumbnail(mime));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean renderFileThumbnail(final String mime) {
|
private static boolean renderFileThumbnail(final String mime) {
|
||||||
return mime.startsWith("video/")
|
return mime.startsWith("video/") || isImage(mime) || "application/pdf".equals(mime);
|
||||||
|| isImage(mime)
|
|
||||||
|| "application/pdf".equals(mime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri getUri() {
|
public Uri getUri() {
|
||||||
|
|
|
@ -102,14 +102,16 @@ public class ConversationMenuConfigurator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversation.getNextEncryption() != Message.ENCRYPTION_NONE) {
|
if (next == Message.ENCRYPTION_NONE) {
|
||||||
menuSecure.setIcon(R.drawable.ic_lock_white_24dp);
|
menuSecure.setIcon(R.drawable.ic_lock_open_outline_24dp);
|
||||||
|
} else {
|
||||||
|
menuSecure.setIcon(R.drawable.ic_lock_24dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
pgp.setVisible(Config.supportOpenPgp());
|
pgp.setVisible(Config.supportOpenPgp());
|
||||||
none.setVisible(Config.supportUnencrypted() || conversation.getMode() == Conversation.MODE_MULTI);
|
none.setVisible(Config.supportUnencrypted() || conversation.getMode() == Conversation.MODE_MULTI);
|
||||||
axolotl.setVisible(Config.supportOmemo());
|
axolotl.setVisible(Config.supportOmemo());
|
||||||
switch (conversation.getNextEncryption()) {
|
switch (next) {
|
||||||
case Message.ENCRYPTION_PGP:
|
case Message.ENCRYPTION_PGP:
|
||||||
menuSecure.setTitle(R.string.encrypted_with_openpgp);
|
menuSecure.setTitle(R.string.encrypted_with_openpgp);
|
||||||
pgp.setChecked(true);
|
pgp.setChecked(true);
|
||||||
|
|
|
@ -12,6 +12,8 @@ import android.view.View;
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
|
@ -200,7 +202,7 @@ public final class MucDetailsContextMenuHelper {
|
||||||
activity.xmppConnectionService.changeRoleInConference(conversation, user.getName(), MucOptions.Role.NONE);
|
activity.xmppConnectionService.changeRoleInConference(conversation, user.getName(), MucOptions.Role.NONE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity);
|
||||||
builder.setTitle(R.string.ban_from_conference);
|
builder.setTitle(R.string.ban_from_conference);
|
||||||
String jid = user.getRealJid().asBareJid().toString();
|
String jid = user.getRealJid().asBareJid().toString();
|
||||||
SpannableString message = new SpannableString(activity.getString(R.string.removing_from_public_conference, jid));
|
SpannableString message = new SpannableString(activity.getString(R.string.removing_from_public_conference, jid));
|
||||||
|
|
|
@ -36,6 +36,8 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
@ -72,7 +74,7 @@ public class PresenceSelector {
|
||||||
|
|
||||||
private static void showPresenceSelectionDialog(final Activity activity, final Contact contact, final String[] resourceArray, final OnFullJidSelected onFullJidSelected) {
|
private static void showPresenceSelectionDialog(final Activity activity, final Contact contact, final String[] resourceArray, final OnFullJidSelected onFullJidSelected) {
|
||||||
final Presences presences = contact.getPresences();
|
final Presences presences = contact.getPresences();
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity);
|
||||||
builder.setTitle(activity.getString(R.string.choose_presence));
|
builder.setTitle(activity.getString(R.string.choose_presence));
|
||||||
Pair<Map<String, String>, Map<String, String>> typeAndName = presences.toTypeAndNameMap();
|
Pair<Map<String, String>, Map<String, String>> typeAndName = presences.toTypeAndNameMap();
|
||||||
final Map<String, String> resourceTypeMap = typeAndName.first;
|
final Map<String, String> resourceTypeMap = typeAndName.first;
|
||||||
|
@ -128,8 +130,8 @@ public class PresenceSelector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void warnMutualPresenceSubscription(Activity activity, final Conversation conversation, final OnPresenceSelected listener) {
|
public static void warnMutualPresenceSubscription(final Activity activity, final Conversation conversation, final OnPresenceSelected listener) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity);
|
||||||
builder.setTitle(conversation.getContact().getJid().toString());
|
builder.setTitle(conversation.getContact().getJid().toString());
|
||||||
builder.setMessage(R.string.without_mutual_presence_updates);
|
builder.setMessage(R.string.without_mutual_presence_updates);
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
|
|
|
@ -31,8 +31,15 @@ package eu.siacs.conversations.ui.util;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.Configuration;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.ColorInt;
|
||||||
|
import androidx.annotation.DrawableRes;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import com.google.android.material.color.MaterialColors;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
|
@ -42,149 +49,90 @@ import eu.siacs.conversations.utils.UIHelper;
|
||||||
|
|
||||||
public class SendButtonTool {
|
public class SendButtonTool {
|
||||||
|
|
||||||
public static SendButtonAction getAction(final Activity activity, final Conversation c, final String text) {
|
public static SendButtonAction getAction(
|
||||||
if (activity == null) {
|
final Activity activity, final Conversation c, final String text) {
|
||||||
return SendButtonAction.TEXT;
|
if (activity == null) {
|
||||||
}
|
return SendButtonAction.TEXT;
|
||||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
|
}
|
||||||
final boolean empty = text.length() == 0;
|
final SharedPreferences preferences =
|
||||||
final boolean conference = c.getMode() == Conversation.MODE_MULTI;
|
PreferenceManager.getDefaultSharedPreferences(activity);
|
||||||
if (c.getCorrectingMessage() != null && (empty || text.equals(c.getCorrectingMessage().getBody()))) {
|
final boolean empty = text.isEmpty();
|
||||||
return SendButtonAction.CANCEL;
|
final boolean conference = c.getMode() == Conversation.MODE_MULTI;
|
||||||
} else if (conference && !c.getAccount().httpUploadAvailable()) {
|
if (c.getCorrectingMessage() != null
|
||||||
if (empty && c.getNextCounterpart() != null) {
|
&& (empty || text.equals(c.getCorrectingMessage().getBody()))) {
|
||||||
return SendButtonAction.CANCEL;
|
return SendButtonAction.CANCEL;
|
||||||
} else {
|
} else if (conference && !c.getAccount().httpUploadAvailable()) {
|
||||||
return SendButtonAction.TEXT;
|
if (empty && c.getNextCounterpart() != null) {
|
||||||
}
|
return SendButtonAction.CANCEL;
|
||||||
} else {
|
} else {
|
||||||
if (empty) {
|
return SendButtonAction.TEXT;
|
||||||
if (conference && c.getNextCounterpart() != null) {
|
}
|
||||||
return SendButtonAction.CANCEL;
|
} else {
|
||||||
} else {
|
if (empty) {
|
||||||
String setting = preferences.getString("quick_action", activity.getResources().getString(R.string.quick_action));
|
if (conference && c.getNextCounterpart() != null) {
|
||||||
if (!"none".equals(setting) && UIHelper.receivedLocationQuestion(c.getLatestMessage())) {
|
return SendButtonAction.CANCEL;
|
||||||
return SendButtonAction.SEND_LOCATION;
|
} else {
|
||||||
} else {
|
String setting =
|
||||||
if ("recent".equals(setting)) {
|
preferences.getString(
|
||||||
setting = preferences.getString(ConversationFragment.RECENTLY_USED_QUICK_ACTION, SendButtonAction.TEXT.toString());
|
"quick_action",
|
||||||
return SendButtonAction.valueOfOrDefault(setting);
|
activity.getResources().getString(R.string.quick_action));
|
||||||
} else {
|
if (!"none".equals(setting)
|
||||||
return SendButtonAction.valueOfOrDefault(setting);
|
&& UIHelper.receivedLocationQuestion(c.getLatestMessage())) {
|
||||||
}
|
return SendButtonAction.SEND_LOCATION;
|
||||||
}
|
} else {
|
||||||
}
|
if ("recent".equals(setting)) {
|
||||||
} else {
|
setting =
|
||||||
return SendButtonAction.TEXT;
|
preferences.getString(
|
||||||
}
|
ConversationFragment.RECENTLY_USED_QUICK_ACTION,
|
||||||
}
|
SendButtonAction.TEXT.toString());
|
||||||
}
|
return SendButtonAction.valueOfOrDefault(setting);
|
||||||
|
} else {
|
||||||
|
return SendButtonAction.valueOfOrDefault(setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return SendButtonAction.TEXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static int getSendButtonImageResource(Activity activity, SendButtonAction action, Presence.Status status) {
|
public @DrawableRes static int getSendButtonImageResource(final SendButtonAction action) {
|
||||||
switch (action) {
|
return switch (action) {
|
||||||
case TEXT:
|
case TEXT -> R.drawable.ic_send_24dp;
|
||||||
switch (status) {
|
case TAKE_PHOTO -> R.drawable.ic_camera_alt_24dp;
|
||||||
case CHAT:
|
case SEND_LOCATION -> R.drawable.ic_location_pin_24dp;
|
||||||
case ONLINE:
|
case CHOOSE_PICTURE -> R.drawable.ic_image_24dp;
|
||||||
return R.drawable.ic_send_text_online;
|
case RECORD_VIDEO -> R.drawable.ic_videocam_24dp;
|
||||||
case AWAY:
|
case RECORD_VOICE -> R.drawable.ic_mic_24dp;
|
||||||
return R.drawable.ic_send_text_away;
|
case CANCEL -> R.drawable.ic_cancel_24dp;
|
||||||
case XA:
|
};
|
||||||
case DND:
|
}
|
||||||
return R.drawable.ic_send_text_dnd;
|
|
||||||
default:
|
|
||||||
return getThemeResource(activity, R.attr.ic_send_text_offline, R.drawable.ic_send_text_offline);
|
|
||||||
}
|
|
||||||
case RECORD_VIDEO:
|
|
||||||
switch (status) {
|
|
||||||
case CHAT:
|
|
||||||
case ONLINE:
|
|
||||||
return R.drawable.ic_send_videocam_online;
|
|
||||||
case AWAY:
|
|
||||||
return R.drawable.ic_send_videocam_away;
|
|
||||||
case XA:
|
|
||||||
case DND:
|
|
||||||
return R.drawable.ic_send_videocam_dnd;
|
|
||||||
default:
|
|
||||||
return getThemeResource(activity, R.attr.ic_send_videocam_offline, R.drawable.ic_send_videocam_offline);
|
|
||||||
}
|
|
||||||
case TAKE_PHOTO:
|
|
||||||
switch (status) {
|
|
||||||
case CHAT:
|
|
||||||
case ONLINE:
|
|
||||||
return R.drawable.ic_send_photo_online;
|
|
||||||
case AWAY:
|
|
||||||
return R.drawable.ic_send_photo_away;
|
|
||||||
case XA:
|
|
||||||
case DND:
|
|
||||||
return R.drawable.ic_send_photo_dnd;
|
|
||||||
default:
|
|
||||||
return getThemeResource(activity, R.attr.ic_send_photo_offline, R.drawable.ic_send_photo_offline);
|
|
||||||
}
|
|
||||||
case RECORD_VOICE:
|
|
||||||
switch (status) {
|
|
||||||
case CHAT:
|
|
||||||
case ONLINE:
|
|
||||||
return R.drawable.ic_send_voice_online;
|
|
||||||
case AWAY:
|
|
||||||
return R.drawable.ic_send_voice_away;
|
|
||||||
case XA:
|
|
||||||
case DND:
|
|
||||||
return R.drawable.ic_send_voice_dnd;
|
|
||||||
default:
|
|
||||||
return getThemeResource(activity, R.attr.ic_send_voice_offline, R.drawable.ic_send_voice_offline);
|
|
||||||
}
|
|
||||||
case SEND_LOCATION:
|
|
||||||
switch (status) {
|
|
||||||
case CHAT:
|
|
||||||
case ONLINE:
|
|
||||||
return R.drawable.ic_send_location_online;
|
|
||||||
case AWAY:
|
|
||||||
return R.drawable.ic_send_location_away;
|
|
||||||
case XA:
|
|
||||||
case DND:
|
|
||||||
return R.drawable.ic_send_location_dnd;
|
|
||||||
default:
|
|
||||||
return getThemeResource(activity, R.attr.ic_send_location_offline, R.drawable.ic_send_location_offline);
|
|
||||||
}
|
|
||||||
case CANCEL:
|
|
||||||
switch (status) {
|
|
||||||
case CHAT:
|
|
||||||
case ONLINE:
|
|
||||||
return R.drawable.ic_send_cancel_online;
|
|
||||||
case AWAY:
|
|
||||||
return R.drawable.ic_send_cancel_away;
|
|
||||||
case XA:
|
|
||||||
case DND:
|
|
||||||
return R.drawable.ic_send_cancel_dnd;
|
|
||||||
default:
|
|
||||||
return getThemeResource(activity, R.attr.ic_send_cancel_offline, R.drawable.ic_send_cancel_offline);
|
|
||||||
}
|
|
||||||
case CHOOSE_PICTURE:
|
|
||||||
switch (status) {
|
|
||||||
case CHAT:
|
|
||||||
case ONLINE:
|
|
||||||
return R.drawable.ic_send_picture_online;
|
|
||||||
case AWAY:
|
|
||||||
return R.drawable.ic_send_picture_away;
|
|
||||||
case XA:
|
|
||||||
case DND:
|
|
||||||
return R.drawable.ic_send_picture_dnd;
|
|
||||||
default:
|
|
||||||
return getThemeResource(activity, R.attr.ic_send_picture_offline, R.drawable.ic_send_picture_offline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return getThemeResource(activity, R.attr.ic_send_text_offline, R.drawable.ic_send_text_offline);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getThemeResource(Activity activity, int r_attr_name, int r_drawable_def) {
|
|
||||||
int[] attrs = {r_attr_name};
|
|
||||||
TypedArray ta = activity.getTheme().obtainStyledAttributes(attrs);
|
|
||||||
|
|
||||||
int res = ta.getResourceId(0, r_drawable_def);
|
|
||||||
ta.recycle();
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public @ColorInt static int getSendButtonColor(final View view, final Presence.Status status) {
|
||||||
|
final boolean nightMode =
|
||||||
|
(view.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)
|
||||||
|
== Configuration.UI_MODE_NIGHT_YES;
|
||||||
|
return switch (status) {
|
||||||
|
case OFFLINE -> MaterialColors.getColor(
|
||||||
|
view, com.google.android.material.R.attr.colorOnSurface);
|
||||||
|
case ONLINE, CHAT -> MaterialColors.harmonizeWithPrimary(
|
||||||
|
view.getContext(),
|
||||||
|
ContextCompat.getColor(
|
||||||
|
view.getContext(), nightMode ? R.color.green_200 : R.color.green_800));
|
||||||
|
case AWAY -> MaterialColors.harmonizeWithPrimary(
|
||||||
|
view.getContext(),
|
||||||
|
ContextCompat.getColor(
|
||||||
|
view.getContext(), nightMode ? R.color.amber_200 : R.color.amber_800));
|
||||||
|
case XA -> MaterialColors.harmonizeWithPrimary(
|
||||||
|
view.getContext(),
|
||||||
|
ContextCompat.getColor(
|
||||||
|
view.getContext(),
|
||||||
|
nightMode ? R.color.orange_200 : R.color.orange_800));
|
||||||
|
case DND -> MaterialColors.harmonizeWithPrimary(
|
||||||
|
view.getContext(),
|
||||||
|
ContextCompat.getColor(
|
||||||
|
view.getContext(), nightMode ? R.color.red_200 : R.color.red_800));
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018, Daniel Gultsch All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
* are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation and/or
|
|
||||||
* other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software without
|
|
||||||
* specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eu.siacs.conversations.ui.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.TypedArray;
|
|
||||||
|
|
||||||
import androidx.annotation.AttrRes;
|
|
||||||
import androidx.annotation.ColorInt;
|
|
||||||
|
|
||||||
public class StyledAttributes {
|
|
||||||
public static android.graphics.drawable.Drawable getDrawable(Context context, @AttrRes int id) {
|
|
||||||
TypedArray typedArray = context.obtainStyledAttributes(new int[]{id});
|
|
||||||
android.graphics.drawable.Drawable drawable = typedArray.getDrawable(0);
|
|
||||||
typedArray.recycle();
|
|
||||||
return drawable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float getFloat(Context context, @AttrRes int id) {
|
|
||||||
TypedArray typedArray = context.obtainStyledAttributes(new int[]{id});
|
|
||||||
float value = typedArray.getFloat(0,0f);
|
|
||||||
typedArray.recycle();
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @ColorInt int getColor(Context context, @AttrRes int attr) {
|
|
||||||
TypedArray typedArray = context.obtainStyledAttributes(new int[]{attr});
|
|
||||||
int color = typedArray.getColor(0,0);
|
|
||||||
typedArray.recycle();
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
}
|
|
166
src/main/java/eu/siacs/conversations/ui/util/ToolbarUtils.java
Normal file
166
src/main/java/eu/siacs/conversations/ui/util/ToolbarUtils.java
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package eu.siacs.conversations.ui.util;
|
||||||
|
|
||||||
|
import static java.util.Collections.max;
|
||||||
|
import static java.util.Collections.min;
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.widget.ActionMenuView;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ToolbarUtils {
|
||||||
|
|
||||||
|
private static final Comparator<View> VIEW_TOP_COMPARATOR =
|
||||||
|
new Comparator<View>() {
|
||||||
|
@Override
|
||||||
|
public int compare(View view1, View view2) {
|
||||||
|
return view1.getTop() - view2.getTop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private ToolbarUtils() {
|
||||||
|
// Private constructor to prevent unwanted construction.
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resetActionBarOnClickListeners(@NonNull MaterialToolbar view) {
|
||||||
|
final TextView title = getTitleTextView(view);
|
||||||
|
final TextView subtitle = getSubtitleTextView(view);
|
||||||
|
if (title != null) {
|
||||||
|
title.setOnClickListener(null);
|
||||||
|
}
|
||||||
|
if (subtitle != null) {
|
||||||
|
subtitle.setOnClickListener(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setActionBarOnClickListener(
|
||||||
|
@NonNull MaterialToolbar view, @NonNull final View.OnClickListener onClickListener) {
|
||||||
|
final TextView title = getTitleTextView(view);
|
||||||
|
final TextView subtitle = getSubtitleTextView(view);
|
||||||
|
if (title != null) {
|
||||||
|
title.setOnClickListener(onClickListener);
|
||||||
|
}
|
||||||
|
if (subtitle != null) {
|
||||||
|
subtitle.setOnClickListener(onClickListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static TextView getTitleTextView(@NonNull Toolbar toolbar) {
|
||||||
|
List<TextView> textViews = getTextViewsWithText(toolbar, toolbar.getTitle());
|
||||||
|
return textViews.isEmpty() ? null : min(textViews, VIEW_TOP_COMPARATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static TextView getSubtitleTextView(@NonNull Toolbar toolbar) {
|
||||||
|
List<TextView> textViews = getTextViewsWithText(toolbar, toolbar.getSubtitle());
|
||||||
|
return textViews.isEmpty() ? null : max(textViews, VIEW_TOP_COMPARATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<TextView> getTextViewsWithText(
|
||||||
|
@NonNull Toolbar toolbar, CharSequence text) {
|
||||||
|
List<TextView> textViews = new ArrayList<>();
|
||||||
|
for (int i = 0; i < toolbar.getChildCount(); i++) {
|
||||||
|
View child = toolbar.getChildAt(i);
|
||||||
|
if (child instanceof TextView textView) {
|
||||||
|
if (TextUtils.equals(textView.getText(), text)) {
|
||||||
|
textViews.add(textView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return textViews;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static ImageView getLogoImageView(@NonNull Toolbar toolbar) {
|
||||||
|
return getImageView(toolbar, toolbar.getLogo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static ImageView getImageView(@NonNull Toolbar toolbar, @Nullable Drawable content) {
|
||||||
|
if (content == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < toolbar.getChildCount(); i++) {
|
||||||
|
View child = toolbar.getChildAt(i);
|
||||||
|
if (child instanceof ImageView imageView) {
|
||||||
|
Drawable drawable = imageView.getDrawable();
|
||||||
|
if (drawable != null
|
||||||
|
&& drawable.getConstantState() != null
|
||||||
|
&& drawable.getConstantState().equals(content.getConstantState())) {
|
||||||
|
return imageView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static View getSecondaryActionMenuItemView(@NonNull Toolbar toolbar) {
|
||||||
|
ActionMenuView actionMenuView = getActionMenuView(toolbar);
|
||||||
|
if (actionMenuView != null) {
|
||||||
|
// Only return the first child of the ActionMenuView if there is more than one child
|
||||||
|
if (actionMenuView.getChildCount() > 1) {
|
||||||
|
return actionMenuView.getChildAt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static ActionMenuView getActionMenuView(@NonNull Toolbar toolbar) {
|
||||||
|
for (int i = 0; i < toolbar.getChildCount(); i++) {
|
||||||
|
View child = toolbar.getChildAt(i);
|
||||||
|
if (child instanceof ActionMenuView) {
|
||||||
|
return (ActionMenuView) child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static ImageButton getNavigationIconButton(@NonNull Toolbar toolbar) {
|
||||||
|
Drawable navigationIcon = toolbar.getNavigationIcon();
|
||||||
|
if (navigationIcon == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < toolbar.getChildCount(); i++) {
|
||||||
|
View child = toolbar.getChildAt(i);
|
||||||
|
if (child instanceof ImageButton imageButton) {
|
||||||
|
if (imageButton.getDrawable() == navigationIcon) {
|
||||||
|
return imageButton;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue